├── .ci
├── Dockerfile.cypress
├── docker-compose.ci.yml
├── docker-compose.cypress.yml
├── docker_build
├── pack
└── update_version
├── .coveragerc
├── .dockerignore
├── .editorconfig
├── .github
├── ISSUE_TEMPLATE
│ ├── ---bug_report.md
│ └── --anything_else.md
├── PULL_REQUEST_TEMPLATE.md
├── config.yml
├── weekly-digest.yml
└── workflows
│ └── ci.yml
├── .gitignore
├── .nvmrc
├── .restyled.yaml
├── .yarn
└── .gitignore
├── .yarnrc
├── CHANGELOG.md
├── CONTRIBUTING.md
├── Dockerfile
├── LICENSE
├── Makefile
├── README.md
├── SECURITY.md
├── bin
├── docker-entrypoint
├── flake8_tests.sh
├── get_changes.py
├── release_manager.py
├── run
└── upgrade
├── client
├── .babelrc
├── .eslintignore
├── .eslintrc.js
├── .gitignore
├── app
│ ├── .eslintrc.js
│ ├── __tests__
│ │ ├── enzyme_setup.js
│ │ └── mocks.js
│ ├── assets
│ │ ├── css
│ │ │ └── login.css
│ │ ├── fonts
│ │ │ └── roboto
│ │ │ │ ├── Roboto-Bold-webfont.eot
│ │ │ │ ├── Roboto-Bold-webfont.svg
│ │ │ │ ├── Roboto-Bold-webfont.ttf
│ │ │ │ ├── Roboto-Bold-webfont.woff
│ │ │ │ ├── Roboto-Light-webfont.eot
│ │ │ │ ├── Roboto-Light-webfont.svg
│ │ │ │ ├── Roboto-Light-webfont.ttf
│ │ │ │ ├── Roboto-Light-webfont.woff
│ │ │ │ ├── Roboto-Medium-webfont.eot
│ │ │ │ ├── Roboto-Medium-webfont.svg
│ │ │ │ ├── Roboto-Medium-webfont.ttf
│ │ │ │ ├── Roboto-Medium-webfont.woff
│ │ │ │ ├── Roboto-Regular-webfont.eot
│ │ │ │ ├── Roboto-Regular-webfont.svg
│ │ │ │ ├── Roboto-Regular-webfont.ttf
│ │ │ │ ├── Roboto-Regular-webfont.woff
│ │ │ │ ├── Roboto-Thin-webfont.eot
│ │ │ │ ├── Roboto-Thin-webfont.svg
│ │ │ │ ├── Roboto-Thin-webfont.ttf
│ │ │ │ └── Roboto-Thin-webfont.woff
│ │ ├── images
│ │ │ ├── avatar.svg
│ │ │ ├── db-logos
│ │ │ │ ├── Cassandra.png
│ │ │ │ ├── arangodb.png
│ │ │ │ ├── athena.png
│ │ │ │ ├── aws_es.png
│ │ │ │ ├── axibasetsd.png
│ │ │ │ ├── azure_kusto.png
│ │ │ │ ├── bigquery.png
│ │ │ │ ├── bigquery_gce.png
│ │ │ │ ├── clickhouse.png
│ │ │ │ ├── cloudwatch.png
│ │ │ │ ├── cloudwatch_insights.png
│ │ │ │ ├── cockroach.png
│ │ │ │ ├── corporate_memory.png
│ │ │ │ ├── couchbase.png
│ │ │ │ ├── csv.png
│ │ │ │ ├── databend.png
│ │ │ │ ├── databricks.png
│ │ │ │ ├── db2.png
│ │ │ │ ├── dgraph.png
│ │ │ │ ├── drill.png
│ │ │ │ ├── druid.png
│ │ │ │ ├── dynamodb_sql.png
│ │ │ │ ├── elasticsearch.png
│ │ │ │ ├── elasticsearch2.png
│ │ │ │ ├── elasticsearch2_OpenDistroSQLElasticSearch.png
│ │ │ │ ├── elasticsearch2_XPackSQLElasticSearch.png
│ │ │ │ ├── exasol.png
│ │ │ │ ├── excel.png
│ │ │ │ ├── firebolt.png
│ │ │ │ ├── google_analytics.png
│ │ │ │ ├── google_spreadsheets.png
│ │ │ │ ├── graphite.png
│ │ │ │ ├── hive.png
│ │ │ │ ├── hive_http.png
│ │ │ │ ├── impala.png
│ │ │ │ ├── influxdb.png
│ │ │ │ ├── jirajql.png
│ │ │ │ ├── json.png
│ │ │ │ ├── kibana.png
│ │ │ │ ├── kylin.png
│ │ │ │ ├── mapd.png
│ │ │ │ ├── memsql.png
│ │ │ │ ├── mongodb.png
│ │ │ │ ├── mssql.png
│ │ │ │ ├── mssql_odbc.png
│ │ │ │ ├── mysql.png
│ │ │ │ ├── nz.png
│ │ │ │ ├── oracle.png
│ │ │ │ ├── pg.png
│ │ │ │ ├── phoenix.png
│ │ │ │ ├── pinot.png
│ │ │ │ ├── presto.png
│ │ │ │ ├── prometheus.png
│ │ │ │ ├── python.png
│ │ │ │ ├── qubole.png
│ │ │ │ ├── rds_mysql.png
│ │ │ │ ├── redshift.png
│ │ │ │ ├── redshift_iam.png
│ │ │ │ ├── results.png
│ │ │ │ ├── rockset.png
│ │ │ │ ├── salesforce.png
│ │ │ │ ├── scylla.png
│ │ │ │ ├── snowflake.png
│ │ │ │ ├── sparql_endpoint.png
│ │ │ │ ├── sqlite.png
│ │ │ │ ├── treasuredata.png
│ │ │ │ ├── trino.png
│ │ │ │ ├── uptycs.png
│ │ │ │ ├── url.png
│ │ │ │ ├── vertica.png
│ │ │ │ ├── yandex_appmetrika.png
│ │ │ │ └── yandex_metrika.png
│ │ │ ├── destinations
│ │ │ │ ├── chatwork.png
│ │ │ │ ├── email.png
│ │ │ │ ├── hangouts_chat.png
│ │ │ │ ├── hipchat.png
│ │ │ │ ├── mattermost.png
│ │ │ │ ├── microsoft_teams_webhook.png
│ │ │ │ ├── pagerduty.png
│ │ │ │ ├── slack.png
│ │ │ │ └── webhook.png
│ │ │ ├── favicon-16x16.png
│ │ │ ├── favicon-32x32.png
│ │ │ ├── favicon-96x96.png
│ │ │ ├── fixtures
│ │ │ │ └── map-tile.png
│ │ │ ├── google_logo.svg
│ │ │ ├── gravatar.png
│ │ │ ├── illustrations
│ │ │ │ ├── alert.svg
│ │ │ │ ├── dashboard.svg
│ │ │ │ ├── no-query-results.svg
│ │ │ │ ├── query.svg
│ │ │ │ └── readme.md
│ │ │ ├── logo.png
│ │ │ ├── logo_white.png
│ │ │ └── redash_icon_small.png
│ │ ├── less
│ │ │ ├── STYLING-README.md
│ │ │ ├── ant.less
│ │ │ ├── inc
│ │ │ │ ├── 404.less
│ │ │ │ ├── ace-editor.less
│ │ │ │ ├── alert.less
│ │ │ │ ├── ant-variables.less
│ │ │ │ ├── base.less
│ │ │ │ ├── bootstrap-overrides.less
│ │ │ │ ├── breadcrumb.less
│ │ │ │ ├── button.less
│ │ │ │ ├── carousel.less
│ │ │ │ ├── chart.less
│ │ │ │ ├── dropdown.less
│ │ │ │ ├── edit-in-place.less
│ │ │ │ ├── flex.less
│ │ │ │ ├── font.less
│ │ │ │ ├── form.less
│ │ │ │ ├── generics.less
│ │ │ │ ├── header.less
│ │ │ │ ├── ie-warning.less
│ │ │ │ ├── jumbotron.less
│ │ │ │ ├── label.less
│ │ │ │ ├── less-plugins
│ │ │ │ │ └── for.less
│ │ │ │ ├── list-group.less
│ │ │ │ ├── list.less
│ │ │ │ ├── login.less
│ │ │ │ ├── media.less
│ │ │ │ ├── messages.less
│ │ │ │ ├── misc.less
│ │ │ │ ├── mixins.less
│ │ │ │ ├── modal.less
│ │ │ │ ├── panel.less
│ │ │ │ ├── photos.less
│ │ │ │ ├── popover.less
│ │ │ │ ├── pricing-table.less
│ │ │ │ ├── print.less
│ │ │ │ ├── profile.less
│ │ │ │ ├── progress-bar.less
│ │ │ │ ├── schema-browser.less
│ │ │ │ ├── sidebar.less
│ │ │ │ ├── table.less
│ │ │ │ ├── tile.less
│ │ │ │ ├── tooltips.less
│ │ │ │ ├── variables.less
│ │ │ │ ├── visualizations
│ │ │ │ │ ├── box.less
│ │ │ │ │ ├── map.less
│ │ │ │ │ ├── misc.less
│ │ │ │ │ └── pivot-table.less
│ │ │ │ ├── well.less
│ │ │ │ └── widgets.less
│ │ │ ├── main.less
│ │ │ ├── redash
│ │ │ │ ├── css-logo.less
│ │ │ │ ├── loading-indicator.less
│ │ │ │ ├── query.less
│ │ │ │ ├── redash-table.less
│ │ │ │ └── tags-control.less
│ │ │ └── server.less
│ │ └── robots.txt
│ ├── components
│ │ ├── AceEditorInput.jsx
│ │ ├── AceEditorInput.less
│ │ ├── ApplicationArea
│ │ │ ├── ApplicationLayout
│ │ │ │ ├── DesktopNavbar.jsx
│ │ │ │ ├── DesktopNavbar.less
│ │ │ │ ├── MobileNavbar.jsx
│ │ │ │ ├── MobileNavbar.less
│ │ │ │ ├── VersionInfo.jsx
│ │ │ │ ├── index.jsx
│ │ │ │ └── index.less
│ │ │ ├── ErrorMessage.jsx
│ │ │ ├── ErrorMessage.less
│ │ │ ├── ErrorMessage.test.js
│ │ │ ├── ErrorMessageDetails.jsx
│ │ │ ├── Router.jsx
│ │ │ ├── handleNavigationIntent.js
│ │ │ ├── index.jsx
│ │ │ ├── navigateTo.js
│ │ │ ├── routeWithApiKeySession.jsx
│ │ │ └── routeWithUserSession.tsx
│ │ ├── BeaconConsent.jsx
│ │ ├── BigMessage.jsx
│ │ ├── CodeBlock.jsx
│ │ ├── CodeBlock.less
│ │ ├── Collapse.jsx
│ │ ├── CreateSourceDialog.jsx
│ │ ├── DateInput.jsx
│ │ ├── DateRangeInput.jsx
│ │ ├── DateTimeInput.jsx
│ │ ├── DateTimeRangeInput.jsx
│ │ ├── DialogWrapper.d.ts
│ │ ├── DialogWrapper.jsx
│ │ ├── DynamicComponent.jsx
│ │ ├── EditInPlace.jsx
│ │ ├── EditParameterSettingsDialog.jsx
│ │ ├── EditVisualizationButton
│ │ │ ├── QueryControlDropdown.jsx
│ │ │ ├── QueryResultsLink.jsx
│ │ │ └── index.jsx
│ │ ├── EmailSettingsWarning.jsx
│ │ ├── FavoritesControl.jsx
│ │ ├── Filters.jsx
│ │ ├── HelpTrigger.jsx
│ │ ├── HelpTrigger.less
│ │ ├── InputWithCopy.jsx
│ │ ├── Link.tsx
│ │ ├── NoTaggedObjectsFound.jsx
│ │ ├── PageHeader
│ │ │ ├── index.jsx
│ │ │ └── index.less
│ │ ├── Paginator.jsx
│ │ ├── ParameterApplyButton.jsx
│ │ ├── ParameterMappingInput.jsx
│ │ ├── ParameterMappingInput.less
│ │ ├── ParameterValueInput.jsx
│ │ ├── ParameterValueInput.less
│ │ ├── Parameters.jsx
│ │ ├── Parameters.less
│ │ ├── PermissionsEditorDialog
│ │ │ ├── index.jsx
│ │ │ └── index.less
│ │ ├── PlainButton.less
│ │ ├── PlainButton.tsx
│ │ ├── PreviewCard.jsx
│ │ ├── QueryBasedParameterInput.jsx
│ │ ├── QueryLink.jsx
│ │ ├── QueryLink.less
│ │ ├── QuerySelector.jsx
│ │ ├── Resizable
│ │ │ ├── index.jsx
│ │ │ └── index.less
│ │ ├── SelectItemsDialog.jsx
│ │ ├── SelectItemsDialog.less
│ │ ├── SelectWithVirtualScroll.tsx
│ │ ├── SettingsWrapper.jsx
│ │ ├── TagsList.less
│ │ ├── TagsList.tsx
│ │ ├── TimeAgo.jsx
│ │ ├── Timer.jsx
│ │ ├── Tooltip.tsx
│ │ ├── UserGroups.jsx
│ │ ├── UserGroups.less
│ │ ├── admin
│ │ │ ├── Layout.jsx
│ │ │ ├── RQStatus.jsx
│ │ │ ├── StatusBlock.jsx
│ │ │ └── layout.less
│ │ ├── cards-list
│ │ │ ├── CardsList.less
│ │ │ └── CardsList.tsx
│ │ ├── dashboards
│ │ │ ├── AddWidgetDialog.jsx
│ │ │ ├── AutoHeightController.js
│ │ │ ├── CreateDashboardDialog.jsx
│ │ │ ├── DashboardGrid.jsx
│ │ │ ├── EditParameterMappingsDialog.jsx
│ │ │ ├── ExpandedWidgetDialog.jsx
│ │ │ ├── TextboxDialog.jsx
│ │ │ ├── TextboxDialog.less
│ │ │ ├── dashboard-grid.less
│ │ │ └── dashboard-widget
│ │ │ │ ├── RestrictedWidget.jsx
│ │ │ │ ├── TextboxWidget.jsx
│ │ │ │ ├── VisualizationWidget.jsx
│ │ │ │ ├── Widget.jsx
│ │ │ │ ├── Widget.less
│ │ │ │ └── index.js
│ │ ├── dynamic-form
│ │ │ ├── DynamicForm.jsx
│ │ │ ├── DynamicForm.less
│ │ │ ├── DynamicFormField.jsx
│ │ │ ├── dynamicFormHelper.js
│ │ │ ├── fields
│ │ │ │ ├── AceEditorField.jsx
│ │ │ │ ├── CheckboxField.jsx
│ │ │ │ ├── ContentField.jsx
│ │ │ │ ├── FileField.jsx
│ │ │ │ ├── InputField.jsx
│ │ │ │ ├── NumberField.jsx
│ │ │ │ ├── SelectField.jsx
│ │ │ │ ├── TextAreaField.jsx
│ │ │ │ └── index.js
│ │ │ └── getFieldLabel.js
│ │ ├── dynamic-parameters
│ │ │ ├── DateParameter.jsx
│ │ │ ├── DateRangeParameter.jsx
│ │ │ ├── DynamicButton.jsx
│ │ │ ├── DynamicButton.less
│ │ │ ├── DynamicDatePicker.jsx
│ │ │ ├── DynamicDateRangePicker.jsx
│ │ │ └── DynamicParameters.less
│ │ ├── empty-state
│ │ │ ├── EmptyState.d.ts
│ │ │ ├── EmptyState.jsx
│ │ │ └── empty-state.less
│ │ ├── groups
│ │ │ ├── CreateGroupDialog.jsx
│ │ │ ├── DeleteGroupButton.jsx
│ │ │ ├── DetailsPageSidebar.jsx
│ │ │ ├── GroupName.jsx
│ │ │ └── ListItemAddon.jsx
│ │ ├── items-list
│ │ │ ├── ItemsList.tsx
│ │ │ ├── classes
│ │ │ │ ├── ItemsFetcher.js
│ │ │ │ ├── ItemsSource.d.ts
│ │ │ │ ├── ItemsSource.js
│ │ │ │ ├── Paginator.js
│ │ │ │ ├── Sorter.js
│ │ │ │ └── StateStorage.js
│ │ │ ├── components
│ │ │ │ ├── EmptyState.jsx
│ │ │ │ ├── ItemsTable.jsx
│ │ │ │ ├── LoadingState.jsx
│ │ │ │ └── Sidebar.jsx
│ │ │ └── hooks
│ │ │ │ └── useItemsListExtraActions.js
│ │ ├── layouts
│ │ │ ├── ContentWithSidebar.jsx
│ │ │ └── content-with-sidebar.less
│ │ ├── proptypes.js
│ │ ├── queries
│ │ │ ├── AddToDashboardDialog.jsx
│ │ │ ├── ApiKeyDialog
│ │ │ │ ├── index.jsx
│ │ │ │ └── index.less
│ │ │ ├── EmbedQueryDialog.jsx
│ │ │ ├── EmbedQueryDialog.less
│ │ │ ├── QueryEditor
│ │ │ │ ├── AutoLimitCheckbox.jsx
│ │ │ │ ├── AutocompleteToggle.jsx
│ │ │ │ ├── QueryEditorControls.jsx
│ │ │ │ ├── QueryEditorControls.less
│ │ │ │ ├── ace.js
│ │ │ │ ├── index.jsx
│ │ │ │ └── index.less
│ │ │ ├── ScheduleDialog.css
│ │ │ ├── ScheduleDialog.jsx
│ │ │ ├── ScheduleDialog.test.js
│ │ │ ├── SchedulePhrase.jsx
│ │ │ ├── SchemaBrowser.jsx
│ │ │ ├── __snapshots__
│ │ │ │ └── ScheduleDialog.test.js.snap
│ │ │ ├── add-to-dashboard-dialog.less
│ │ │ └── editor-components
│ │ │ │ ├── databricks
│ │ │ │ ├── DatabricksSchemaBrowser.jsx
│ │ │ │ ├── DatabricksSchemaBrowser.less
│ │ │ │ └── useDatabricksSchema.js
│ │ │ │ ├── editorComponents.js
│ │ │ │ └── index.js
│ │ ├── query-snippets
│ │ │ └── QuerySnippetDialog.jsx
│ │ ├── tags-control
│ │ │ ├── EditTagsDialog.jsx
│ │ │ └── TagsControl.jsx
│ │ └── visualizations
│ │ │ ├── EditVisualizationDialog.jsx
│ │ │ ├── EditVisualizationDialog.less
│ │ │ ├── VisualizationName.jsx
│ │ │ ├── VisualizationName.less
│ │ │ ├── VisualizationRenderer.jsx
│ │ │ └── visualizationComponents.jsx
│ ├── config
│ │ ├── antd-spinner.jsx
│ │ ├── dashboard-grid-options.js
│ │ └── index.js
│ ├── extensions
│ │ └── .gitkeep
│ ├── index.html
│ ├── index.js
│ ├── lib
│ │ ├── accessibility.ts
│ │ ├── calculateTextWidth.ts
│ │ ├── hooks
│ │ │ ├── useFullscreenHandler.js
│ │ │ ├── useImmutableCallback.js
│ │ │ ├── useLazyRef.ts
│ │ │ ├── useSearchResults.js
│ │ │ └── useUniqueId.ts
│ │ ├── localOptions.js
│ │ ├── pagination
│ │ │ ├── index.js
│ │ │ └── paginator.js
│ │ ├── queryFormat.test.js
│ │ ├── queryFormat.ts
│ │ ├── useQueryResultData.js
│ │ └── utils.js
│ ├── multi_org.html
│ ├── pages
│ │ ├── admin
│ │ │ ├── Jobs.jsx
│ │ │ ├── OutdatedQueries.jsx
│ │ │ ├── SystemStatus.jsx
│ │ │ └── system-status.less
│ │ ├── alert
│ │ │ ├── Alert.jsx
│ │ │ ├── AlertEdit.jsx
│ │ │ ├── AlertNew.jsx
│ │ │ ├── AlertView.jsx
│ │ │ └── components
│ │ │ │ ├── AlertDestinations.jsx
│ │ │ │ ├── AlertDestinations.less
│ │ │ │ ├── Criteria.jsx
│ │ │ │ ├── Criteria.less
│ │ │ │ ├── HorizontalFormItem.jsx
│ │ │ │ ├── MenuButton.jsx
│ │ │ │ ├── NotificationTemplate.jsx
│ │ │ │ ├── NotificationTemplate.less
│ │ │ │ ├── Query.jsx
│ │ │ │ ├── Query.less
│ │ │ │ ├── Rearm.jsx
│ │ │ │ ├── Rearm.less
│ │ │ │ ├── Title.jsx
│ │ │ │ └── Title.less
│ │ ├── alerts
│ │ │ └── AlertsList.jsx
│ │ ├── dashboards
│ │ │ ├── DashboardList.jsx
│ │ │ ├── DashboardPage.jsx
│ │ │ ├── DashboardPage.less
│ │ │ ├── PublicDashboardPage.jsx
│ │ │ ├── PublicDashboardPage.less
│ │ │ ├── components
│ │ │ │ ├── DashboardHeader.jsx
│ │ │ │ ├── DashboardHeader.less
│ │ │ │ ├── DashboardListEmptyState.tsx
│ │ │ │ └── ShareDashboardDialog.jsx
│ │ │ ├── dashboard-list.css
│ │ │ └── hooks
│ │ │ │ ├── useDashboard.js
│ │ │ │ ├── useDataSources.js
│ │ │ │ ├── useEditModeHandler.js
│ │ │ │ └── useRefreshRateHandler.js
│ │ ├── data-sources
│ │ │ ├── DataSourcesList.jsx
│ │ │ └── EditDataSource.jsx
│ │ ├── destinations
│ │ │ ├── DestinationsList.jsx
│ │ │ └── EditDestination.jsx
│ │ ├── groups
│ │ │ ├── GroupDataSources.jsx
│ │ │ ├── GroupMembers.jsx
│ │ │ └── GroupsList.jsx
│ │ ├── home
│ │ │ ├── Home.jsx
│ │ │ ├── Home.less
│ │ │ └── components
│ │ │ │ └── FavoritesList.jsx
│ │ ├── index.js
│ │ ├── queries-list
│ │ │ ├── QueriesList.jsx
│ │ │ ├── QueriesListEmptyState.jsx
│ │ │ └── queries-list.css
│ │ ├── queries
│ │ │ ├── QuerySource.jsx
│ │ │ ├── QuerySource.less
│ │ │ ├── QueryView.jsx
│ │ │ ├── QueryView.less
│ │ │ ├── VisualizationEmbed.jsx
│ │ │ ├── components
│ │ │ │ ├── QueryExecutionMetadata.jsx
│ │ │ │ ├── QueryExecutionMetadata.less
│ │ │ │ ├── QueryExecutionStatus.jsx
│ │ │ │ ├── QueryMetadata.jsx
│ │ │ │ ├── QueryMetadata.less
│ │ │ │ ├── QueryPageHeader.jsx
│ │ │ │ ├── QueryPageHeader.less
│ │ │ │ ├── QuerySourceAlerts.jsx
│ │ │ │ ├── QuerySourceAlerts.less
│ │ │ │ ├── QuerySourceDropdown.jsx
│ │ │ │ ├── QuerySourceDropdownItem.jsx
│ │ │ │ ├── QuerySourceTypeIcon.jsx
│ │ │ │ ├── QueryViewButton.jsx
│ │ │ │ ├── QueryVisualizationTabs.jsx
│ │ │ │ ├── QueryVisualizationTabs.less
│ │ │ │ └── wrapQueryPage.jsx
│ │ │ └── hooks
│ │ │ │ ├── useAddNewParameterDialog.js
│ │ │ │ ├── useAddToDashboardDialog.js
│ │ │ │ ├── useAddVisualizationDialog.js
│ │ │ │ ├── useApiKeyDialog.js
│ │ │ │ ├── useArchiveQuery.jsx
│ │ │ │ ├── useAutoLimitFlags.js
│ │ │ │ ├── useAutocompleteFlags.js
│ │ │ │ ├── useDataSourceSchema.js
│ │ │ │ ├── useDeleteVisualization.js
│ │ │ │ ├── useDuplicateQuery.js
│ │ │ │ ├── useEditScheduleDialog.js
│ │ │ │ ├── useEditVisualizationDialog.js
│ │ │ │ ├── useEmbedDialog.js
│ │ │ │ ├── usePermissionsEditorDialog.js
│ │ │ │ ├── usePublishQuery.js
│ │ │ │ ├── useQuery.js
│ │ │ │ ├── useQueryDataSources.js
│ │ │ │ ├── useQueryExecute.js
│ │ │ │ ├── useQueryFlags.js
│ │ │ │ ├── useQueryParameters.js
│ │ │ │ ├── useRenameQuery.js
│ │ │ │ ├── useUnpublishQuery.js
│ │ │ │ ├── useUnsavedChangesAlert.js
│ │ │ │ ├── useUpdateQuery.jsx
│ │ │ │ ├── useUpdateQueryDescription.js
│ │ │ │ ├── useUpdateQueryTags.js
│ │ │ │ └── useVisualizationTabHandler.js
│ │ ├── query-snippets
│ │ │ ├── QuerySnippetsList.jsx
│ │ │ └── QuerySnippetsList.less
│ │ ├── settings
│ │ │ ├── OrganizationSettings.jsx
│ │ │ ├── components
│ │ │ │ ├── AuthSettings
│ │ │ │ │ ├── GoogleLoginSettings.jsx
│ │ │ │ │ ├── PasswordLoginSettings.jsx
│ │ │ │ │ ├── SAMLSettings.jsx
│ │ │ │ │ └── index.jsx
│ │ │ │ ├── GeneralSettings
│ │ │ │ │ ├── BeaconConsentSettings.jsx
│ │ │ │ │ ├── FeatureFlagsSettings.jsx
│ │ │ │ │ ├── FormatSettings.jsx
│ │ │ │ │ ├── PlotlySettings.jsx
│ │ │ │ │ └── index.jsx
│ │ │ │ └── prop-types.js
│ │ │ └── hooks
│ │ │ │ └── useOrganizationSettings.js
│ │ └── users
│ │ │ ├── UserProfile.jsx
│ │ │ ├── UsersList.jsx
│ │ │ ├── components
│ │ │ ├── ApiKeyForm.jsx
│ │ │ ├── CreateUserDialog.jsx
│ │ │ ├── EditableUserProfile.jsx
│ │ │ ├── PasswordForm
│ │ │ │ ├── ChangePasswordDialog.jsx
│ │ │ │ ├── PasswordLinkAlert.jsx
│ │ │ │ ├── PasswordResetForm.jsx
│ │ │ │ ├── ResendInvitationForm.jsx
│ │ │ │ └── index.jsx
│ │ │ ├── ReadOnlyUserProfile.jsx
│ │ │ ├── ReadOnlyUserProfile.test.js
│ │ │ ├── ToggleUserForm.jsx
│ │ │ ├── UserInfoForm.jsx
│ │ │ └── __snapshots__
│ │ │ │ └── ReadOnlyUserProfile.test.js.snap
│ │ │ ├── hooks
│ │ │ └── useUserGroups.js
│ │ │ └── settings.less
│ ├── redash-font
│ │ ├── fonts
│ │ │ ├── redash-icons.eot
│ │ │ ├── redash-icons.svg
│ │ │ ├── redash-icons.ttf
│ │ │ └── redash-icons.woff
│ │ ├── style.less
│ │ └── variables.less
│ ├── services
│ │ ├── KeyboardShortcuts.js
│ │ ├── alert-subscription.js
│ │ ├── alert.js
│ │ ├── auth.js
│ │ ├── auth.test.js
│ │ ├── axios.js
│ │ ├── dashboard.js
│ │ ├── data-source.js
│ │ ├── databricks-data-source.js
│ │ ├── destination.js
│ │ ├── getTags.js
│ │ ├── group.js
│ │ ├── location.js
│ │ ├── notification.d.ts
│ │ ├── notification.js
│ │ ├── notifications.js
│ │ ├── offline-listener.js
│ │ ├── organizationSettings.js
│ │ ├── organizationStatus.js
│ │ ├── parameters
│ │ │ ├── DateParameter.js
│ │ │ ├── DateRangeParameter.js
│ │ │ ├── EnumParameter.js
│ │ │ ├── NumberParameter.js
│ │ │ ├── Parameter.js
│ │ │ ├── QueryBasedDropdownParameter.js
│ │ │ ├── TextParameter.js
│ │ │ ├── index.js
│ │ │ └── tests
│ │ │ │ ├── DateParameter.test.js
│ │ │ │ ├── DateRangeParameter.test.js
│ │ │ │ ├── EnumParameter.test.js
│ │ │ │ ├── NumberParameter.test.js
│ │ │ │ ├── Parameter.test.js
│ │ │ │ ├── QueryBasedDropdownParameter.test.js
│ │ │ │ └── TextParameter.test.js
│ │ ├── policy
│ │ │ ├── DefaultPolicy.js
│ │ │ └── index.js
│ │ ├── query-result.js
│ │ ├── query-snippet.js
│ │ ├── query.js
│ │ ├── recordEvent.js
│ │ ├── resizeObserver.js
│ │ ├── restoreSession.jsx
│ │ ├── routes.ts
│ │ ├── sanitize.js
│ │ ├── settingsMenu.js
│ │ ├── settingsMenu.test.js
│ │ ├── url.js
│ │ ├── user.js
│ │ ├── utils.js
│ │ ├── visualization.js
│ │ └── widget.js
│ ├── styles
│ │ ├── formStyle.less
│ │ └── formStyle.ts
│ ├── unsupported.html
│ ├── unsupportedRedirect.js
│ └── version.json
├── cypress
│ ├── .eslintrc.js
│ ├── cypress.js
│ ├── integration
│ │ ├── alert
│ │ │ ├── create_alert_spec.js
│ │ │ ├── edit_alert_spec.js
│ │ │ └── view_alert_spec.js
│ │ ├── dashboard
│ │ │ ├── dashboard_spec.js
│ │ │ ├── dashboard_tags_spec.js
│ │ │ ├── filters_spec.js
│ │ │ ├── grid_compliant_widgets_spec.js
│ │ │ ├── parameter_spec.js
│ │ │ ├── sharing_spec.js
│ │ │ ├── textbox_spec.js
│ │ │ └── widget_spec.js
│ │ ├── data-source
│ │ │ ├── create_data_source_spec.js
│ │ │ └── edit_data_source_spec.js
│ │ ├── destination
│ │ │ └── create_destination_spec.js
│ │ ├── embed
│ │ │ └── share_embed_spec.js
│ │ ├── group
│ │ │ ├── edit_group_spec.js
│ │ │ └── group_list_spec.js
│ │ ├── query-snippets
│ │ │ └── create_query_snippet_spec.js
│ │ ├── query
│ │ │ ├── create_query_spec.js
│ │ │ ├── filters_spec.js
│ │ │ ├── parameter_spec.js
│ │ │ └── query_tags_spec.js
│ │ ├── settings
│ │ │ ├── organization_settings_spec.js
│ │ │ └── settings_tabs_spec.js
│ │ ├── user
│ │ │ ├── create_user_spec.js
│ │ │ ├── edit_profile_spec.js
│ │ │ ├── login_spec.js
│ │ │ ├── logout_spec.js
│ │ │ └── user_list_spec.js
│ │ └── visualizations
│ │ │ ├── box_plot_spec.js
│ │ │ ├── chart_spec.js
│ │ │ ├── choropleth_spec.js
│ │ │ ├── cohort_spec.js
│ │ │ ├── counter_spec.js
│ │ │ ├── edit_visualization_dialog_spec.js
│ │ │ ├── funnel_spec.js
│ │ │ ├── map_spec.js
│ │ │ ├── pivot_spec.js
│ │ │ ├── sankey_sunburst_spec.js
│ │ │ ├── table
│ │ │ ├── .mocks
│ │ │ │ ├── all-cell-types.js
│ │ │ │ ├── large-dataset.js
│ │ │ │ ├── multi-column-sort.js
│ │ │ │ └── search-in-data.js
│ │ │ └── table_spec.js
│ │ │ └── word_cloud_spec.js
│ ├── plugins
│ │ └── index.js
│ ├── seed-data.js
│ ├── support
│ │ ├── commands.js
│ │ ├── dashboard
│ │ │ └── index.js
│ │ ├── index.js
│ │ ├── parameters.js
│ │ ├── redash-api
│ │ │ └── index.js
│ │ ├── tags
│ │ │ └── index.js
│ │ └── visualizations
│ │ │ ├── chart.js
│ │ │ └── table.js
│ └── tsconfig.json
├── prettier.config.js
└── tsconfig.json
├── cypress.json
├── docker-compose.yml
├── manage.py
├── migrations
├── 0001_warning.py
├── README
├── alembic.ini
├── env.py
├── script.py.mako
└── versions
│ ├── 0ec979123ba4_.py
│ ├── 0f740a081d20_inline_tags.py
│ ├── 1daa601d3ae5_add_columns_for_disabled_users.py
│ ├── 5ec5c84ba61e_.py
│ ├── 640888ce445d_.py
│ ├── 65fc9ede4746_add_is_draft_status_to_queries_and_.py
│ ├── 6b5be7e0a0ef_.py
│ ├── 71477dadd6ef_favorites_unique_constraint.py
│ ├── 73beceabb948_bring_back_null_schedule.py
│ ├── 7671dca4e604_.py
│ ├── 89bc7873a3e0_fix_multiple_heads.py
│ ├── 969126bd800f_.py
│ ├── 98af61feea92_add_encrypted_options_to_data_sources.py
│ ├── a92d92aa678e_inline_tags.py
│ ├── d1eae8b9893e_.py
│ ├── d4c798575877_create_favorites.py
│ ├── d7d747033183_encrypt_alert_destinations.py
│ ├── e5c7a4e2df4d_remove_query_tracker_keys.py
│ ├── e7004224f284_add_org_id_to_favorites.py
│ ├── e7f8a917aa8e_add_user_details_json_column.py
│ └── fd4fc850d7ea_.py
├── netlify.toml
├── package.json
├── pip.conf
├── pytest.ini
├── redash
├── __init__.py
├── app.py
├── authentication
│ ├── __init__.py
│ ├── account.py
│ ├── google_oauth.py
│ ├── jwt_auth.py
│ ├── ldap_auth.py
│ ├── org_resolving.py
│ ├── remote_user_auth.py
│ └── saml_auth.py
├── cli
│ ├── __init__.py
│ ├── data_sources.py
│ ├── database.py
│ ├── groups.py
│ ├── organization.py
│ ├── queries.py
│ ├── rq.py
│ └── users.py
├── destinations
│ ├── __init__.py
│ ├── chatwork.py
│ ├── email.py
│ ├── hangoutschat.py
│ ├── hipchat.py
│ ├── mattermost.py
│ ├── microsoft_teams_webhook.py
│ ├── pagerduty.py
│ ├── slack.py
│ └── webhook.py
├── handlers
│ ├── __init__.py
│ ├── admin.py
│ ├── alerts.py
│ ├── api.py
│ ├── authentication.py
│ ├── base.py
│ ├── dashboards.py
│ ├── data_sources.py
│ ├── databricks.py
│ ├── destinations.py
│ ├── embed.py
│ ├── events.py
│ ├── favorites.py
│ ├── groups.py
│ ├── organization.py
│ ├── permissions.py
│ ├── queries.py
│ ├── query_results.py
│ ├── query_snippets.py
│ ├── settings.py
│ ├── setup.py
│ ├── static.py
│ ├── users.py
│ ├── visualizations.py
│ ├── webpack.py
│ └── widgets.py
├── metrics
│ ├── __init__.py
│ ├── database.py
│ └── request.py
├── models
│ ├── __init__.py
│ ├── base.py
│ ├── changes.py
│ ├── mixins.py
│ ├── organizations.py
│ ├── parameterized_query.py
│ ├── types.py
│ └── users.py
├── monitor.py
├── permissions.py
├── query_runner
│ ├── __init__.py
│ ├── amazon_elasticsearch.py
│ ├── arango.py
│ ├── athena.py
│ ├── axibase_tsd.py
│ ├── azure_kusto.py
│ ├── big_query.py
│ ├── big_query_gce.py
│ ├── cass.py
│ ├── clickhouse.py
│ ├── cloudwatch.py
│ ├── cloudwatch_insights.py
│ ├── corporate_memory.py
│ ├── couchbase.py
│ ├── csv.py
│ ├── databend.py
│ ├── databricks.py
│ ├── db2.py
│ ├── dgraph.py
│ ├── drill.py
│ ├── druid.py
│ ├── dynamodb_sql.py
│ ├── elasticsearch.py
│ ├── elasticsearch2.py
│ ├── exasol.py
│ ├── excel.py
│ ├── files
│ │ ├── rds-combined-ca-bundle.pem
│ │ └── redshift-ca-bundle.crt
│ ├── firebolt.py
│ ├── google_analytics.py
│ ├── google_spanner.py
│ ├── google_spreadsheets.py
│ ├── graphite.py
│ ├── hive_ds.py
│ ├── impala_ds.py
│ ├── influx_db.py
│ ├── jql.py
│ ├── json_ds.py
│ ├── kylin.py
│ ├── mapd.py
│ ├── memsql_ds.py
│ ├── mongodb.py
│ ├── mssql.py
│ ├── mssql_odbc.py
│ ├── mysql.py
│ ├── nz.py
│ ├── oracle.py
│ ├── pg.py
│ ├── phoenix.py
│ ├── pinot.py
│ ├── presto.py
│ ├── prometheus.py
│ ├── python.py
│ ├── qubole.py
│ ├── query_results.py
│ ├── rockset.py
│ ├── salesforce.py
│ ├── script.py
│ ├── snowflake.py
│ ├── sparql_endpoint.py
│ ├── sqlite.py
│ ├── treasuredata.py
│ ├── trino.py
│ ├── uptycs.py
│ ├── url.py
│ ├── vertica.py
│ └── yandex_metrica.py
├── security.py
├── serializers
│ ├── __init__.py
│ └── query_result.py
├── settings
│ ├── __init__.py
│ ├── dynamic_settings.py
│ ├── helpers.py
│ └── organization.py
├── tasks
│ ├── __init__.py
│ ├── alerts.py
│ ├── databricks.py
│ ├── failure_report.py
│ ├── general.py
│ ├── queries
│ │ ├── __init__.py
│ │ ├── execution.py
│ │ └── maintenance.py
│ ├── schedule.py
│ └── worker.py
├── templates
│ ├── _includes
│ │ ├── signed_out_tail.html
│ │ └── tail.html
│ ├── emails
│ │ ├── failures.html
│ │ ├── failures.txt
│ │ ├── invite.html
│ │ ├── invite.txt
│ │ ├── layout.html
│ │ ├── reset.html
│ │ ├── reset.txt
│ │ ├── reset_disabled.html
│ │ ├── reset_disabled.txt
│ │ ├── verify.html
│ │ └── verify.txt
│ ├── error.html
│ ├── forgot.html
│ ├── invite.html
│ ├── layouts
│ │ └── signed_out.html
│ ├── login.html
│ ├── reset.html
│ ├── setup.html
│ └── verify.html
├── utils
│ ├── __init__.py
│ ├── configuration.py
│ ├── human_time.py
│ ├── requests_session.py
│ └── sentry.py
├── version_check.py
├── worker.py
└── wsgi.py
├── requirements.txt
├── requirements_all_ds.txt
├── requirements_dev.txt
├── requirements_oracle_ds.txt
├── scripts
└── README.md
├── setup.cfg
├── setup
└── README.md
├── tests
├── __init__.py
├── factories.py
├── handlers
│ ├── __init__.py
│ ├── test_alerts.py
│ ├── test_authentication.py
│ ├── test_dashboards.py
│ ├── test_data_sources.py
│ ├── test_destinations.py
│ ├── test_embed.py
│ ├── test_favorites.py
│ ├── test_groups.py
│ ├── test_paginate.py
│ ├── test_permissions.py
│ ├── test_queries.py
│ ├── test_query_results.py
│ ├── test_query_snippets.py
│ ├── test_settings.py
│ ├── test_users.py
│ ├── test_visualizations.py
│ └── test_widgets.py
├── metrics
│ ├── __init__.py
│ ├── test_database.py
│ └── test_request.py
├── models
│ ├── __init__.py
│ ├── test_alerts.py
│ ├── test_api_keys.py
│ ├── test_changes.py
│ ├── test_dashboards.py
│ ├── test_data_sources.py
│ ├── test_parameterized_query.py
│ ├── test_permissions.py
│ ├── test_queries.py
│ ├── test_query_results.py
│ └── test_users.py
├── query_runner
│ ├── __init__.py
│ ├── test_athena.py
│ ├── test_basesql_queryrunner.py
│ ├── test_cass.py
│ ├── test_clickhouse.py
│ ├── test_databricks.py
│ ├── test_drill.py
│ ├── test_elasticsearch2.py
│ ├── test_google_spreadsheets.py
│ ├── test_http.py
│ ├── test_jql.py
│ ├── test_mongodb.py
│ ├── test_oracle.py
│ ├── test_pg.py
│ ├── test_prometheus.py
│ ├── test_python.py
│ ├── test_query_results.py
│ ├── test_script.py
│ └── test_utils.py
├── serializers
│ ├── __init__.py
│ └── test_query_results.py
├── tasks
│ ├── __init__.py
│ ├── test_alerts.py
│ ├── test_empty_schedule.py
│ ├── test_failure_report.py
│ ├── test_queries.py
│ ├── test_refresh_queries.py
│ ├── test_refresh_schemas.py
│ ├── test_schedule.py
│ └── test_worker.py
├── test_authentication.py
├── test_cli.py
├── test_configuration.py
├── test_handlers.py
├── test_migrations.py
├── test_models.py
├── test_permissions.py
├── test_utils.py
└── utils
│ └── __init__.py
├── viz-lib
├── .babelrc
├── .gitignore
├── CHANGELOG.md
├── README.md
├── __tests__
│ ├── enzyme_setup.js
│ └── mocks.js
├── package.json
├── prettier.config.js
├── src
│ ├── components
│ │ ├── ColorPicker
│ │ │ ├── Input.tsx
│ │ │ ├── Label.tsx
│ │ │ ├── Swatch.tsx
│ │ │ ├── index.less
│ │ │ ├── index.tsx
│ │ │ ├── input.less
│ │ │ ├── label.less
│ │ │ ├── swatch.less
│ │ │ └── utils.ts
│ │ ├── ErrorBoundary.tsx
│ │ ├── HtmlContent.tsx
│ │ ├── TextAlignmentSelect
│ │ │ ├── index.less
│ │ │ └── index.tsx
│ │ ├── json-view-interactive
│ │ │ ├── JsonViewInteractive.tsx
│ │ │ └── json-view-interactive.less
│ │ ├── sortable
│ │ │ ├── index.tsx
│ │ │ └── style.less
│ │ └── visualizations
│ │ │ └── editor
│ │ │ ├── ContextHelp.tsx
│ │ │ ├── Section.less
│ │ │ ├── Section.tsx
│ │ │ ├── Switch.less
│ │ │ ├── Switch.tsx
│ │ │ ├── TextArea.less
│ │ │ ├── TextArea.tsx
│ │ │ ├── context-help.less
│ │ │ ├── control-label.less
│ │ │ ├── createTabbedEditor.tsx
│ │ │ ├── index.ts
│ │ │ └── withControlLabel.tsx
│ ├── index.ts
│ ├── lib
│ │ ├── chooseTextColorForBackground.ts
│ │ ├── hooks
│ │ │ └── useMemoWithDeepCompare.ts
│ │ ├── referenceCountingCache.ts
│ │ ├── utils.ts
│ │ └── value-format.tsx
│ ├── services
│ │ ├── resizeObserver.ts
│ │ └── sanitize.ts
│ └── visualizations
│ │ ├── ColorPalette.ts
│ │ ├── Editor.tsx
│ │ ├── Renderer.tsx
│ │ ├── box-plot
│ │ ├── Editor.tsx
│ │ ├── Renderer.tsx
│ │ ├── d3box.ts
│ │ ├── index.ts
│ │ └── renderer.less
│ │ ├── chart
│ │ ├── Editor
│ │ │ ├── AxisSettings.tsx
│ │ │ ├── ChartTypeSelect.tsx
│ │ │ ├── ColorsSettings.test.tsx
│ │ │ ├── ColorsSettings.tsx
│ │ │ ├── ColumnMappingSelect.tsx
│ │ │ ├── CustomChartSettings.tsx
│ │ │ ├── DataLabelsSettings.test.tsx
│ │ │ ├── DataLabelsSettings.tsx
│ │ │ ├── DefaultColorsSettings.tsx
│ │ │ ├── GeneralSettings.test.tsx
│ │ │ ├── GeneralSettings.tsx
│ │ │ ├── HeatmapColorsSettings.tsx
│ │ │ ├── PieColorsSettings.tsx
│ │ │ ├── SeriesSettings.test.tsx
│ │ │ ├── SeriesSettings.tsx
│ │ │ ├── XAxisSettings.test.tsx
│ │ │ ├── XAxisSettings.tsx
│ │ │ ├── YAxisSettings.test.tsx
│ │ │ ├── YAxisSettings.tsx
│ │ │ ├── __snapshots__
│ │ │ │ ├── ColorsSettings.test.tsx.snap
│ │ │ │ ├── DataLabelsSettings.test.tsx.snap
│ │ │ │ ├── GeneralSettings.test.tsx.snap
│ │ │ │ ├── SeriesSettings.test.tsx.snap
│ │ │ │ ├── XAxisSettings.test.tsx.snap
│ │ │ │ └── YAxisSettings.test.tsx.snap
│ │ │ ├── editor.less
│ │ │ ├── index.test.tsx
│ │ │ └── index.tsx
│ │ ├── Renderer
│ │ │ ├── CustomPlotlyChart.tsx
│ │ │ ├── PlotlyChart.tsx
│ │ │ ├── index.tsx
│ │ │ ├── initChart.ts
│ │ │ └── renderer.less
│ │ ├── fixtures
│ │ │ └── getChartData
│ │ │ │ ├── multiple-series-grouped.json
│ │ │ │ ├── multiple-series-multiple-y.json
│ │ │ │ ├── multiple-series-sorted.json
│ │ │ │ └── single-series.json
│ │ ├── getChartData.test.ts
│ │ ├── getChartData.ts
│ │ ├── getOptions.ts
│ │ ├── index.ts
│ │ └── plotly
│ │ │ ├── customChartUtils.ts
│ │ │ ├── fixtures
│ │ │ ├── prepareData
│ │ │ │ ├── bar
│ │ │ │ │ ├── default.json
│ │ │ │ │ ├── normalized.json
│ │ │ │ │ └── stacked.json
│ │ │ │ ├── box
│ │ │ │ │ ├── default.json
│ │ │ │ │ └── with-points.json
│ │ │ │ ├── bubble
│ │ │ │ │ └── default.json
│ │ │ │ ├── heatmap
│ │ │ │ │ ├── default.json
│ │ │ │ │ ├── reversed.json
│ │ │ │ │ ├── sorted-reversed.json
│ │ │ │ │ ├── sorted.json
│ │ │ │ │ └── with-labels.json
│ │ │ │ ├── line-area
│ │ │ │ │ ├── default.json
│ │ │ │ │ ├── keep-missing-values.json
│ │ │ │ │ ├── missing-values-0.json
│ │ │ │ │ ├── normalized-stacked.json
│ │ │ │ │ ├── normalized.json
│ │ │ │ │ └── stacked.json
│ │ │ │ ├── pie
│ │ │ │ │ ├── custom-tooltip.json
│ │ │ │ │ ├── default.json
│ │ │ │ │ ├── without-labels.json
│ │ │ │ │ └── without-x.json
│ │ │ │ └── scatter
│ │ │ │ │ ├── default.json
│ │ │ │ │ └── without-labels.json
│ │ │ └── prepareLayout
│ │ │ │ ├── box-single-axis.json
│ │ │ │ ├── box-with-second-axis.json
│ │ │ │ ├── default-single-axis.json
│ │ │ │ ├── default-with-second-axis.json
│ │ │ │ ├── default-with-stacking.json
│ │ │ │ ├── default-without-legend.json
│ │ │ │ ├── pie-multiple-series.json
│ │ │ │ ├── pie-without-annotations.json
│ │ │ │ └── pie.json
│ │ │ ├── index.ts
│ │ │ ├── prepareData.test.ts
│ │ │ ├── prepareData.ts
│ │ │ ├── prepareDefaultData.ts
│ │ │ ├── prepareHeatmapData.ts
│ │ │ ├── prepareLayout.test.ts
│ │ │ ├── prepareLayout.ts
│ │ │ ├── preparePieData.ts
│ │ │ ├── updateAxes.ts
│ │ │ ├── updateChartSize.ts
│ │ │ ├── updateData.ts
│ │ │ └── utils.ts
│ │ ├── choropleth
│ │ ├── ColorPalette.ts
│ │ ├── Editor
│ │ │ ├── BoundsSettings.tsx
│ │ │ ├── ColorsSettings.tsx
│ │ │ ├── FormatSettings.tsx
│ │ │ ├── GeneralSettings.tsx
│ │ │ ├── index.ts
│ │ │ └── utils.ts
│ │ ├── Renderer
│ │ │ ├── Legend.tsx
│ │ │ ├── index.tsx
│ │ │ ├── initChoropleth.tsx
│ │ │ ├── renderer.less
│ │ │ └── utils.ts
│ │ ├── getOptions.ts
│ │ ├── hooks
│ │ │ └── useLoadGeoJson.ts
│ │ ├── index.ts
│ │ └── maps
│ │ │ ├── convert-projection.ts
│ │ │ ├── countries.geo.json
│ │ │ ├── japan.prefectures.geo.json
│ │ │ ├── usa-albers.geo.json
│ │ │ └── usa.geo.json
│ │ ├── cohort
│ │ ├── Cornelius.tsx
│ │ ├── Editor
│ │ │ ├── AppearanceSettings.tsx
│ │ │ ├── ColorsSettings.tsx
│ │ │ ├── ColumnsSettings.tsx
│ │ │ ├── OptionsSettings.tsx
│ │ │ └── index.ts
│ │ ├── Renderer.tsx
│ │ ├── cornelius.less
│ │ ├── getOptions.ts
│ │ ├── index.ts
│ │ ├── prepareData.ts
│ │ └── renderer.less
│ │ ├── counter
│ │ ├── Editor
│ │ │ ├── FormatSettings.tsx
│ │ │ ├── GeneralSettings.tsx
│ │ │ └── index.ts
│ │ ├── Renderer.tsx
│ │ ├── index.ts
│ │ ├── render.less
│ │ ├── utils.test.ts
│ │ └── utils.ts
│ │ ├── details
│ │ ├── DetailsRenderer.tsx
│ │ ├── details.less
│ │ └── index.ts
│ │ ├── funnel
│ │ ├── Editor
│ │ │ ├── AppearanceSettings.tsx
│ │ │ ├── GeneralSettings.tsx
│ │ │ └── index.ts
│ │ ├── Renderer
│ │ │ ├── FunnelBar.tsx
│ │ │ ├── funnel-bar.less
│ │ │ ├── index.less
│ │ │ ├── index.tsx
│ │ │ └── prepareData.ts
│ │ ├── getOptions.ts
│ │ └── index.ts
│ │ ├── index.ts
│ │ ├── map
│ │ ├── Editor
│ │ │ ├── FormatSettings.tsx
│ │ │ ├── GeneralSettings.tsx
│ │ │ ├── GroupsSettings.tsx
│ │ │ ├── StyleSettings.tsx
│ │ │ └── index.ts
│ │ ├── Renderer.tsx
│ │ ├── getOptions.ts
│ │ ├── index.ts
│ │ ├── initMap.ts
│ │ └── prepareData.ts
│ │ ├── pivot
│ │ ├── Editor.tsx
│ │ ├── Renderer.tsx
│ │ ├── index.ts
│ │ └── renderer.less
│ │ ├── prop-types.ts
│ │ ├── registeredVisualizations.ts
│ │ ├── sankey
│ │ ├── Editor.tsx
│ │ ├── Renderer.tsx
│ │ ├── d3sankey.ts
│ │ ├── index.ts
│ │ ├── initSankey.ts
│ │ └── renderer.less
│ │ ├── sunburst
│ │ ├── Editor.tsx
│ │ ├── Renderer.tsx
│ │ ├── index.ts
│ │ ├── initSunburst.ts
│ │ └── renderer.less
│ │ ├── table
│ │ ├── Editor
│ │ │ ├── ColumnEditor.tsx
│ │ │ ├── ColumnsSettings.test.tsx
│ │ │ ├── ColumnsSettings.tsx
│ │ │ ├── GridSettings.test.tsx
│ │ │ ├── GridSettings.tsx
│ │ │ ├── __snapshots__
│ │ │ │ ├── ColumnsSettings.test.tsx.snap
│ │ │ │ └── GridSettings.test.tsx.snap
│ │ │ ├── editor.less
│ │ │ └── index.tsx
│ │ ├── Renderer.tsx
│ │ ├── columns
│ │ │ ├── __snapshots__
│ │ │ │ ├── boolean.test.tsx.snap
│ │ │ │ ├── datetime.test.tsx.snap
│ │ │ │ ├── image.test.tsx.snap
│ │ │ │ ├── link.test.tsx.snap
│ │ │ │ ├── number.test.tsx.snap
│ │ │ │ └── text.test.tsx.snap
│ │ │ ├── boolean.test.tsx
│ │ │ ├── boolean.tsx
│ │ │ ├── datetime.test.tsx
│ │ │ ├── datetime.tsx
│ │ │ ├── image.test.tsx
│ │ │ ├── image.tsx
│ │ │ ├── index.ts
│ │ │ ├── json.tsx
│ │ │ ├── link.test.tsx
│ │ │ ├── link.tsx
│ │ │ ├── number.test.tsx
│ │ │ ├── number.tsx
│ │ │ ├── text.test.tsx
│ │ │ └── text.tsx
│ │ ├── getOptions.ts
│ │ ├── index.ts
│ │ ├── renderer.less
│ │ └── utils.tsx
│ │ ├── variables.less
│ │ ├── visualizationsSettings.tsx
│ │ └── word-cloud
│ │ ├── Editor.tsx
│ │ ├── Renderer.tsx
│ │ ├── index.ts
│ │ └── renderer.less
├── tsconfig.json
├── webpack.config.js
└── yarn.lock
├── webpack.config.js
├── worker.conf
└── yarn.lock
/.ci/Dockerfile.cypress:
--------------------------------------------------------------------------------
1 | FROM cypress/browsers:node14.17.0-chrome91-ff89
2 |
3 | ENV APP /usr/src/app
4 | WORKDIR $APP
5 |
6 | COPY package.json yarn.lock .yarnrc $APP/
7 | COPY viz-lib $APP/viz-lib
8 | RUN npm install yarn@1.22.10 -g && yarn --frozen-lockfile --network-concurrency 1 > /dev/null
9 |
10 | COPY . $APP
11 |
12 | RUN ./node_modules/.bin/cypress verify
13 |
--------------------------------------------------------------------------------
/.ci/docker-compose.ci.yml:
--------------------------------------------------------------------------------
1 | version: '2.2'
2 | services:
3 | redash:
4 | build: ../
5 | command: manage version
6 | depends_on:
7 | - postgres
8 | - redis
9 | ports:
10 | - "5000:5000"
11 | environment:
12 | PYTHONUNBUFFERED: 0
13 | REDASH_LOG_LEVEL: "INFO"
14 | REDASH_REDIS_URL: "redis://redis:6379/0"
15 | REDASH_DATABASE_URL: "postgresql://postgres@postgres/postgres"
16 | REDASH_COOKIE_SECRET: "2H9gNG9obnAQ9qnR9BDTQUph6CbXKCzF"
17 | redis:
18 | image: redis:3.0-alpine
19 | restart: unless-stopped
20 | postgres:
21 | image: postgres:9.5.6-alpine
22 | command: "postgres -c fsync=off -c full_page_writes=off -c synchronous_commit=OFF"
23 | restart: unless-stopped
24 |
--------------------------------------------------------------------------------
/.ci/docker_build:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -e
3 | VERSION=$(jq -r .version package.json)
4 | VERSION_TAG=$VERSION.b$CIRCLE_BUILD_NUM
5 |
6 | export DOCKER_BUILDKIT=1
7 | export COMPOSE_DOCKER_CLI_BUILD=1
8 |
9 | docker login -u $DOCKER_USER -p $DOCKER_PASS
10 |
11 | if [ $CIRCLE_BRANCH = master ] || [ $CIRCLE_BRANCH = preview-image ]
12 | then
13 | docker build --build-arg skip_dev_deps=true -t redash/redash:preview -t redash/preview:$VERSION_TAG .
14 | docker push redash/redash:preview
15 | docker push redash/preview:$VERSION_TAG
16 | else
17 | docker build --build-arg skip_dev_deps=true -t redash/redash:$VERSION_TAG .
18 | docker push redash/redash:$VERSION_TAG
19 | fi
20 |
21 | echo "Built: $VERSION_TAG"
22 |
--------------------------------------------------------------------------------
/.ci/pack:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | NAME=redash
3 | VERSION=$(jq -r .version package.json)
4 | FULL_VERSION=$VERSION+b$CIRCLE_BUILD_NUM
5 | FILENAME=$NAME.$FULL_VERSION.tar.gz
6 |
7 | mkdir -p /tmp/artifacts/
8 |
9 | tar -zcv -f /tmp/artifacts/$FILENAME --exclude=".git" --exclude="optipng*" --exclude="cypress" --exclude="*.pyc" --exclude="*.pyo" --exclude="venv" *
10 |
--------------------------------------------------------------------------------
/.ci/update_version:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | VERSION=$(jq -r .version package.json)
3 | FULL_VERSION=$VERSION+b$CIRCLE_BUILD_NUM
4 |
5 | sed -ri "s/^__version__ = '([A-Za-z0-9.-]*)'/__version__ = '$FULL_VERSION'/" redash/__init__.py
6 | sed -i "s/dev/$CIRCLE_SHA1/" client/app/version.json
7 |
--------------------------------------------------------------------------------
/.coveragerc:
--------------------------------------------------------------------------------
1 | [run]
2 | branch = True
3 | source = redash
4 |
5 | [report]
6 | omit =
7 | */settings.py
8 | */python?.?/*
9 | show_missing = True
10 |
--------------------------------------------------------------------------------
/.dockerignore:
--------------------------------------------------------------------------------
1 | client/.tmp/
2 | client/dist/
3 | node_modules/
4 | viz-lib/node_modules/
5 | .tmp/
6 | .venv/
7 | venv/
8 | .git/
9 | /.codeclimate.yml
10 | /.coverage
11 | /coverage.xml
12 | /.circleci/
13 | /.github/
14 | /netlify.toml
15 | /setup/
16 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | end_of_line = lf
5 | insert_final_newline = true
6 | trim_trailing_whitespace = true
7 |
8 | [*.py]
9 | indent_style = space
10 | indent_size = 4
11 |
12 | [*.{js,jsx,css,less,html}]
13 | indent_style = space
14 | indent_size = 2
15 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/--anything_else.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: "\U0001F4A1Anything else"
3 | about: "For help, support, features & ideas - please use Discussions \U0001F46B "
4 | labels: "Support Question"
5 | ---
6 |
7 | We use GitHub only for bug reports 🐛
8 |
9 | Anything else should be a discussion: https://github.com/getredash/redash/discussions/ 👫
10 |
11 | 🚨For support, help & questions use https://github.com/getredash/redash/discussions/categories/q-a
12 | 💡For feature requests & ideas use https://github.com/getredash/redash/discussions/categories/ideas
13 |
14 | Alternatively, check out these resources below. Thanks! 😁.
15 |
16 | - [Discussions](https://github.com/getredash/redash/discussions/)
17 | - [Knowledge Base](https://redash.io/help)
18 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | ## What type of PR is this?
2 |
3 |
4 | - [ ] Refactor
5 | - [ ] Feature
6 | - [ ] Bug Fix
7 | - [ ] New Query Runner (Data Source)
8 | - [ ] New Alert Destination
9 | - [ ] Other
10 |
11 | ## Description
12 |
13 |
14 | ## How is this tested?
15 |
16 | - [ ] Unit tests (pytest, jest)
17 | - [ ] E2E Tests (Cypress)
18 | - [ ] Manually
19 | - [ ] N/A
20 |
21 |
22 |
23 | ## Related Tickets & Documents
24 |
25 |
26 | ## Mobile & Desktop Screenshots/Recordings (if there are UI changes)
27 |
--------------------------------------------------------------------------------
/.github/config.yml:
--------------------------------------------------------------------------------
1 | # https://github.com/behaviorbot/request-info?installation_id=189571
2 | requestInfoLabelToAdd: needs-more-info
3 | requestInfoReplyComment: >
4 | We would appreciate it if you could provide us with more info about this issue/pr!
5 |
6 |
--------------------------------------------------------------------------------
/.github/weekly-digest.yml:
--------------------------------------------------------------------------------
1 | # Configuration for weekly-digest - https://github.com/apps/weekly-digest
2 | publishDay: mon
3 | canPublishIssues: true
4 | canPublishPullRequests: true
5 | canPublishContributors: true
6 | canPublishStargazers: true
7 | canPublishCommits: true
8 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .venv
2 | venv/
3 | .cache
4 | .coverage.*
5 | .coveralls.yml
6 | .idea
7 | *.pyc
8 | .nyc_output
9 | coverage
10 | .coverage
11 | coverage.xml
12 | client/dist
13 | .DS_Store
14 | .#*
15 | \#*#
16 | *~
17 | _build
18 | .vscode
19 | .env
20 |
21 | dump.rdb
22 |
23 | node_modules
24 | .tmp
25 | .sass-cache
26 | npm-debug.log
27 |
28 | client/cypress/screenshots
29 | client/cypress/videos
30 | supervisord.conf
31 | uwsgi.ini
32 |
--------------------------------------------------------------------------------
/.nvmrc:
--------------------------------------------------------------------------------
1 | v14.16.1
2 |
--------------------------------------------------------------------------------
/.yarn/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/.yarnrc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/.yarnrc
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 | # Security Policy
2 |
3 | ## Reporting a Vulnerability
4 |
5 | Please email security@redash.io to report any security vulnerabilities. We will acknowledge receipt of your vulnerability and strive to send you regular updates about our progress. If you're curious about the status of your disclosure please feel free to email us again. If you want to encrypt your disclosure email, you can use [this PGP key](https://keybase.io/arikfr/key.asc).
6 |
--------------------------------------------------------------------------------
/bin/flake8_tests.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | set -o errexit # fail the build if any task fails
4 |
5 | flake8 --version ; pip --version
6 | # stop the build if there are Python syntax errors or undefined names
7 | flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
8 | # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
9 | flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
10 |
--------------------------------------------------------------------------------
/bin/run:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # Ideally I would use stdin with source, but in older bash versions this
4 | # wasn't supported properly.
5 | TEMP_ENV_FILE=`mktemp /tmp/redash_env.XXXXXX`
6 | sed 's/^REDASH/export REDASH/' .env > $TEMP_ENV_FILE
7 | source $TEMP_ENV_FILE
8 | rm $TEMP_ENV_FILE
9 |
10 | exec "$@"
11 |
--------------------------------------------------------------------------------
/client/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | [
4 | "@babel/preset-env",
5 | {
6 | "exclude": ["@babel/plugin-transform-async-to-generator", "@babel/plugin-transform-arrow-functions"],
7 | "corejs": "2",
8 | "useBuiltIns": "usage"
9 | }
10 | ],
11 | "@babel/preset-react",
12 | "@babel/preset-typescript"
13 | ],
14 | "plugins": [
15 | "@babel/plugin-proposal-class-properties",
16 | "@babel/plugin-transform-object-assign",
17 | [
18 | "babel-plugin-transform-builtin-extend",
19 | {
20 | "globals": ["Error"]
21 | }
22 | ]
23 | ],
24 | "env": {
25 | "test": {
26 | "plugins": ["istanbul"]
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/client/.eslintignore:
--------------------------------------------------------------------------------
1 | build/*.js
2 | dist
3 | config/*.js
4 | client/dist
5 |
--------------------------------------------------------------------------------
/client/.gitignore:
--------------------------------------------------------------------------------
1 | dist
2 |
--------------------------------------------------------------------------------
/client/app/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: ["plugin:jest/recommended"],
3 | plugins: ["jest"],
4 | env: {
5 | "jest/globals": true,
6 | },
7 | rules: {
8 | "jest/no-focused-tests": "off",
9 | },
10 | };
11 |
--------------------------------------------------------------------------------
/client/app/__tests__/enzyme_setup.js:
--------------------------------------------------------------------------------
1 | import { configure } from "enzyme";
2 | import Adapter from "enzyme-adapter-react-16";
3 |
4 | configure({ adapter: new Adapter() });
5 |
--------------------------------------------------------------------------------
/client/app/__tests__/mocks.js:
--------------------------------------------------------------------------------
1 | import MockDate from "mockdate";
2 |
3 | const date = new Date("2000-01-01T02:00:00.000");
4 |
5 | MockDate.set(date);
6 |
--------------------------------------------------------------------------------
/client/app/assets/fonts/roboto/Roboto-Bold-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/fonts/roboto/Roboto-Bold-webfont.eot
--------------------------------------------------------------------------------
/client/app/assets/fonts/roboto/Roboto-Bold-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/fonts/roboto/Roboto-Bold-webfont.ttf
--------------------------------------------------------------------------------
/client/app/assets/fonts/roboto/Roboto-Bold-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/fonts/roboto/Roboto-Bold-webfont.woff
--------------------------------------------------------------------------------
/client/app/assets/fonts/roboto/Roboto-Light-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/fonts/roboto/Roboto-Light-webfont.eot
--------------------------------------------------------------------------------
/client/app/assets/fonts/roboto/Roboto-Light-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/fonts/roboto/Roboto-Light-webfont.ttf
--------------------------------------------------------------------------------
/client/app/assets/fonts/roboto/Roboto-Light-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/fonts/roboto/Roboto-Light-webfont.woff
--------------------------------------------------------------------------------
/client/app/assets/fonts/roboto/Roboto-Medium-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/fonts/roboto/Roboto-Medium-webfont.eot
--------------------------------------------------------------------------------
/client/app/assets/fonts/roboto/Roboto-Medium-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/fonts/roboto/Roboto-Medium-webfont.ttf
--------------------------------------------------------------------------------
/client/app/assets/fonts/roboto/Roboto-Medium-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/fonts/roboto/Roboto-Medium-webfont.woff
--------------------------------------------------------------------------------
/client/app/assets/fonts/roboto/Roboto-Regular-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/fonts/roboto/Roboto-Regular-webfont.eot
--------------------------------------------------------------------------------
/client/app/assets/fonts/roboto/Roboto-Regular-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/fonts/roboto/Roboto-Regular-webfont.ttf
--------------------------------------------------------------------------------
/client/app/assets/fonts/roboto/Roboto-Regular-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/fonts/roboto/Roboto-Regular-webfont.woff
--------------------------------------------------------------------------------
/client/app/assets/fonts/roboto/Roboto-Thin-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/fonts/roboto/Roboto-Thin-webfont.eot
--------------------------------------------------------------------------------
/client/app/assets/fonts/roboto/Roboto-Thin-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/fonts/roboto/Roboto-Thin-webfont.ttf
--------------------------------------------------------------------------------
/client/app/assets/fonts/roboto/Roboto-Thin-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/fonts/roboto/Roboto-Thin-webfont.woff
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/Cassandra.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/Cassandra.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/arangodb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/arangodb.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/athena.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/athena.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/aws_es.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/aws_es.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/axibasetsd.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/axibasetsd.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/azure_kusto.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/azure_kusto.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/bigquery.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/bigquery.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/bigquery_gce.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/bigquery_gce.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/clickhouse.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/clickhouse.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/cloudwatch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/cloudwatch.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/cloudwatch_insights.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/cloudwatch_insights.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/cockroach.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/cockroach.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/corporate_memory.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/corporate_memory.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/couchbase.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/couchbase.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/csv.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/csv.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/databend.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/databend.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/databricks.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/databricks.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/db2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/db2.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/dgraph.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/dgraph.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/drill.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/drill.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/druid.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/druid.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/dynamodb_sql.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/dynamodb_sql.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/elasticsearch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/elasticsearch.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/elasticsearch2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/elasticsearch2.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/elasticsearch2_OpenDistroSQLElasticSearch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/elasticsearch2_OpenDistroSQLElasticSearch.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/elasticsearch2_XPackSQLElasticSearch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/elasticsearch2_XPackSQLElasticSearch.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/exasol.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/exasol.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/excel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/excel.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/firebolt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/firebolt.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/google_analytics.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/google_analytics.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/google_spreadsheets.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/google_spreadsheets.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/graphite.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/graphite.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/hive.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/hive.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/hive_http.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/hive_http.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/impala.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/impala.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/influxdb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/influxdb.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/jirajql.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/jirajql.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/json.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/json.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/kibana.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/kibana.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/kylin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/kylin.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/mapd.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/mapd.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/memsql.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/memsql.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/mongodb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/mongodb.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/mssql.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/mssql.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/mssql_odbc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/mssql_odbc.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/mysql.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/mysql.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/nz.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/nz.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/oracle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/oracle.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/pg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/pg.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/phoenix.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/phoenix.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/pinot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/pinot.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/presto.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/presto.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/prometheus.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/prometheus.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/python.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/python.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/qubole.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/qubole.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/rds_mysql.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/rds_mysql.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/redshift.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/redshift.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/redshift_iam.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/redshift_iam.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/results.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/results.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/rockset.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/rockset.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/salesforce.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/salesforce.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/scylla.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/scylla.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/snowflake.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/snowflake.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/sparql_endpoint.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/sparql_endpoint.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/sqlite.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/sqlite.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/treasuredata.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/treasuredata.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/trino.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/trino.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/uptycs.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/uptycs.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/url.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/url.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/vertica.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/vertica.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/yandex_appmetrika.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/yandex_appmetrika.png
--------------------------------------------------------------------------------
/client/app/assets/images/db-logos/yandex_metrika.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/db-logos/yandex_metrika.png
--------------------------------------------------------------------------------
/client/app/assets/images/destinations/chatwork.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/destinations/chatwork.png
--------------------------------------------------------------------------------
/client/app/assets/images/destinations/email.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/destinations/email.png
--------------------------------------------------------------------------------
/client/app/assets/images/destinations/hangouts_chat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/destinations/hangouts_chat.png
--------------------------------------------------------------------------------
/client/app/assets/images/destinations/hipchat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/destinations/hipchat.png
--------------------------------------------------------------------------------
/client/app/assets/images/destinations/mattermost.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/destinations/mattermost.png
--------------------------------------------------------------------------------
/client/app/assets/images/destinations/microsoft_teams_webhook.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/destinations/microsoft_teams_webhook.png
--------------------------------------------------------------------------------
/client/app/assets/images/destinations/pagerduty.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/destinations/pagerduty.png
--------------------------------------------------------------------------------
/client/app/assets/images/destinations/slack.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/destinations/slack.png
--------------------------------------------------------------------------------
/client/app/assets/images/destinations/webhook.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/destinations/webhook.png
--------------------------------------------------------------------------------
/client/app/assets/images/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/favicon-16x16.png
--------------------------------------------------------------------------------
/client/app/assets/images/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/favicon-32x32.png
--------------------------------------------------------------------------------
/client/app/assets/images/favicon-96x96.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/favicon-96x96.png
--------------------------------------------------------------------------------
/client/app/assets/images/fixtures/map-tile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/fixtures/map-tile.png
--------------------------------------------------------------------------------
/client/app/assets/images/google_logo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/client/app/assets/images/gravatar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/gravatar.png
--------------------------------------------------------------------------------
/client/app/assets/images/illustrations/readme.md:
--------------------------------------------------------------------------------
1 | The illustrations shared in this folder are covered by the CC-BY-SA-NC-ND License v4.0 (or newer). You are allowed to use them when using unmodified versions of the Redash source code for non-commercial purposes (meaning for yourself), but you are not allowed to use for any other use or to distribute them as part of your software or fork of Redash.
2 |
3 | For any questions, please contact us.
4 |
--------------------------------------------------------------------------------
/client/app/assets/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/logo.png
--------------------------------------------------------------------------------
/client/app/assets/images/logo_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/logo_white.png
--------------------------------------------------------------------------------
/client/app/assets/images/redash_icon_small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazdata/redash/e8b4c30d801c863c23a4237a5cae8088866da35a/client/app/assets/images/redash_icon_small.png
--------------------------------------------------------------------------------
/client/app/assets/less/STYLING-README.md:
--------------------------------------------------------------------------------
1 | # Styling readme
2 |
3 | Some general rules before you add stuff.
4 |
5 | - Avoid using inline css
6 | - If possible, use classes that are already in place instead of adding new
7 | - Keep less/inc folder untouched, rewrite things in less/redash respectively
8 | - Try following BEM naming conventions: http://getbem.com/naming/
9 |
--------------------------------------------------------------------------------
/client/app/assets/less/inc/ace-editor.less:
--------------------------------------------------------------------------------
1 | .ace_editor {
2 | border: 1px solid fade(@redash-gray, 15%);
3 | height: 100%;
4 | margin-bottom: 10px;
5 |
6 | &.ace_autocomplete .ace_completion-highlight {
7 | text-shadow: none !important;
8 | background: #ffff005e;
9 | font-weight: 600;
10 | }
11 |
12 | &.ace-tm {
13 | .ace_gutter {
14 | background: #fff !important;
15 | }
16 |
17 | .ace_gutter-active-line {
18 | background-color: fade(@redash-gray, 20%) !important;
19 | }
20 |
21 | .ace_marker-layer .ace_active-line {
22 | background: fade(@redash-gray, 9%) !important;
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/client/app/assets/less/inc/breadcrumb.less:
--------------------------------------------------------------------------------
1 | .breadcrumb {
2 | border-bottom: 1px solid #E5E5E5;
3 | border-radius: 0;
4 | padding-top: 10px;
5 | padding-right: 33px;
6 | padding-bottom: 11px;
7 |
8 | @media (min-width: (@screen-lg-min + 80px)) {
9 | padding-left: (@sidebar-left-width + @grid-gutter-width);
10 | }
11 |
12 | @media (min-width: @screen-sm-min) and (max-width: (@screen-md-max + 80px)) {
13 | padding-left: (@sidebar-left-mid-width + @grid-gutter-width);
14 | }
15 |
16 | @media (max-width: (@screen-sm-min)) {
17 | padding-left: @grid-gutter-width/2;
18 | }
19 |
20 | & > li {
21 | & > a {
22 | color: #A9A9A9;
23 |
24 | &:hover {
25 | color: @breadcrumb-active-color;
26 | }
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/client/app/assets/less/inc/carousel.less:
--------------------------------------------------------------------------------
1 | .carousel-caption {
2 | left: 0;
3 | right: 0;
4 | bottom: 0;
5 | background: rgba(0,0,0,0.6);
6 |
7 | h3 {
8 | margin-top: 0;
9 | margin-bottom: 3px;
10 | color: #fff;
11 | }
12 | }
13 |
14 | .carousel-indicators {
15 | bottom: 10px;
16 |
17 | & > li:not(.active) {
18 | border: 0;
19 | background: #000;
20 | }
21 | }
22 |
23 | .carousel-control {
24 | width: 50px;
25 | background: none;
26 |
27 | .fa {
28 | font-size: 50px;
29 | height: 52px;
30 | margin-top: -26px;
31 | position: absolute;
32 | top: 50%;
33 | .margin-left(-9px);
34 | }
35 | }
36 |
37 | @media @max-768 {
38 | .carousel-indicators, .carousel-caption {
39 | display: none;
40 | }
41 | }
--------------------------------------------------------------------------------
/client/app/assets/less/inc/edit-in-place.less:
--------------------------------------------------------------------------------
1 | .edit-in-place {
2 | white-space: pre-line;
3 | display: inline-block;
4 |
5 | p {
6 | margin-bottom: 0;
7 | }
8 |
9 | .editable {
10 | display: inline-block;
11 | cursor: pointer;
12 |
13 | &:hover {
14 | background: @redash-yellow;
15 | border-radius: @redash-radius;
16 | }
17 | }
18 |
19 | &.active input,
20 | &.active textarea {
21 | display: inline-block;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/client/app/assets/less/inc/jumbotron.less:
--------------------------------------------------------------------------------
1 | .jumbotron {
2 | padding-left: 60px;
3 | padding-right: 60px;
4 | }
--------------------------------------------------------------------------------
/client/app/assets/less/inc/label.less:
--------------------------------------------------------------------------------
1 | .label {
2 | border-radius: 2px;
3 | padding: 3px 6px 4px;
4 | font-weight: 500;
5 | font-size: 11px;
6 | }
7 |
8 | .badge {
9 | border-radius: 1px;
10 | }
11 |
12 | .label-default {
13 | background: fade(@redash-gray, 85%);
14 | }
15 |
16 | .label-tag-unpublished {
17 | background: fade(@redash-gray, 85%);
18 | }
19 |
20 | .label-tag-archived {
21 | .label-warning();
22 | }
23 |
24 | .label-tag {
25 | background: fade(@redash-gray, 10%);
26 | color: fade(@redash-gray, 75%);
27 | }
28 |
29 | .label-tag-unpublished,
30 | .label-tag-archived,
31 | .label-tag {
32 | margin-right: 3px;
33 | display: inline;
34 | margin-top: 2px;
35 | max-width: 24ch;
36 | .text-overflow();
37 | }
--------------------------------------------------------------------------------
/client/app/assets/less/inc/less-plugins/for.less:
--------------------------------------------------------------------------------
1 |
2 | .for(@i, @n) {.-each(@i)}
3 | .for(@n) when (isnumber(@n)) {.for(1, @n)}
4 | .for(@i, @n) when not (@i = @n) {
5 | .for((@i + (@n - @i) / abs(@n - @i)), @n);
6 | }
7 |
8 | .for(@array) when (default()) {.for-impl_(length(@array))}
9 | .for-impl_(@i) when (@i > 1) {.for-impl_((@i - 1))}
10 | .for-impl_(@i) when (@i > 0) {.-each(extract(@array, @i))}
11 |
--------------------------------------------------------------------------------
/client/app/assets/less/inc/list.less:
--------------------------------------------------------------------------------
1 | .clist {
2 | list-style: none;
3 |
4 | & > li {
5 | &:before {
6 | font-family: @font-icon;
7 | margin: 0 10px 0 -20px;
8 | vertical-align: middle;
9 | }
10 | }
11 |
12 | &.clist-angle > li:before {
13 | content: "\f2fb";
14 | }
15 |
16 | &.clist-check > li:before {
17 | content: "\f26b";
18 | }
19 |
20 | &.clist-star > li:before {
21 | content: "\f27d";
22 | }
23 | }
--------------------------------------------------------------------------------
/client/app/assets/less/inc/popover.less:
--------------------------------------------------------------------------------
1 | .popover {
2 | box-shadow: fade(@redash-gray, 25%) 0px 0px 15px 0px;
3 | }
4 |
5 | .popover-title {
6 | border-bottom: 0;
7 | padding: 15px;
8 | font-size: 12px;
9 | text-transform: uppercase;
10 |
11 | & + .popover-content {
12 | padding-top: 0;
13 | }
14 | }
15 |
16 | .popover-content {
17 | padding: 15px;
18 |
19 | p {
20 | margin-bottom: 0;
21 | }
22 | }
--------------------------------------------------------------------------------
/client/app/assets/less/inc/progress-bar.less:
--------------------------------------------------------------------------------
1 | .progress {
2 | box-shadow: none;
3 | border-radius: 0;
4 | height: 5px;
5 | margin-bottom: 0;
6 |
7 | .progress-bar {
8 | box-shadow: none;
9 | }
10 | }
--------------------------------------------------------------------------------
/client/app/assets/less/inc/tooltips.less:
--------------------------------------------------------------------------------
1 | .tooltip-inner {
2 | border-radius: 1px;
3 | padding: 5px 10px;
4 | font-size: 12px;
5 | }
--------------------------------------------------------------------------------
/client/app/assets/less/inc/visualizations/box.less:
--------------------------------------------------------------------------------
1 | .box {
2 | font: 10px sans-serif;
3 | line, rect, circle {
4 | fill: #fff;
5 | stroke: #000;
6 | stroke-width: 1.5px;
7 | }
8 | .center {
9 | stroke-dasharray: 3, 3;
10 | }
11 | .outlier {
12 | fill: none;
13 | stroke: #000;
14 | }
15 | }
16 |
17 | .axis text {
18 | font: 10px sans-serif;
19 | }
20 |
21 | .axis path,
22 | .axis line {
23 | fill: none;
24 | stroke: #000;
25 | shape-rendering: crispEdges;
26 | }
27 |
28 | .grid-background {
29 | fill: #ddd;
30 | }
31 |
32 | .grid path,
33 | .grid line {
34 | fill: none;
35 | stroke: #fff;
36 | shape-rendering: crispEdges;
37 | }
38 |
39 | .grid .minor line {
40 | stroke-opacity: .5;
41 | }
42 |
43 | .grid text {
44 | display: none;
45 | }
46 |
--------------------------------------------------------------------------------
/client/app/assets/less/inc/visualizations/map.less:
--------------------------------------------------------------------------------
1 | .map-visualization-container {
2 | height: 500px;
3 |
4 | > div:first-child {
5 | width: 100%;
6 | height: 100%;
7 | z-index: 0;
8 | }
9 | }
10 |
11 | .leaflet-popup-content img {
12 | max-width: 100%;
13 | height: auto;
14 | }
15 |
--------------------------------------------------------------------------------
/client/app/assets/less/inc/visualizations/misc.less:
--------------------------------------------------------------------------------
1 | .visualization-renderer {
2 | display: block;
3 |
4 | .pagination,
5 | .ant-pagination {
6 | margin: 0;
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/client/app/assets/less/inc/visualizations/pivot-table.less:
--------------------------------------------------------------------------------
1 | .pivot-table-visualization-container > table,
2 | .visualization-renderer > .visualization-renderer-wrapper {
3 | overflow: auto;
4 | }
5 |
--------------------------------------------------------------------------------
/client/app/assets/less/inc/well.less:
--------------------------------------------------------------------------------
1 | .well {
2 | border-radius: 0;
3 | background: #fff;
4 | box-shadow: none;
5 | }
--------------------------------------------------------------------------------
/client/app/assets/less/inc/widgets.less:
--------------------------------------------------------------------------------
1 | /* --------------------------------------------------------
2 | User Signups
3 | -----------------------------------------------------------*/
4 | .rounded-thumbs {
5 | padding: 15px 25px 0;
6 | }
7 |
8 | .rt-item {
9 | display: block;
10 | padding-top: 10px;
11 | padding-bottom: 10px;
12 |
13 | img {
14 | width: 100%;
15 | height: 100%;
16 | border-radius: 50%;
17 | }
18 |
19 | small {
20 | .text-overflow();
21 | text-align: center;
22 | display: block;
23 | color: #777;
24 | margin-top: 3px;
25 | }
26 |
27 | &:hover {
28 | background-color: @light-gray;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/client/app/assets/less/redash/tags-control.less:
--------------------------------------------------------------------------------
1 | .tags-control {
2 | display: flex;
3 | flex-direction: row;
4 | flex-wrap: wrap;
5 | align-items: stretch;
6 | justify-content: flex-start;
7 | line-height: 1em;
8 |
9 | &.inline-tags-control {
10 | display: inline-block;
11 | }
12 |
13 | .tag-separator {
14 | margin: 4px 3px 0 0;
15 | }
16 |
17 | &.disabled {
18 | opacity: 0.4;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/client/app/assets/robots.txt:
--------------------------------------------------------------------------------
1 | # robotstxt.org
2 |
3 | User-agent: *
4 |
--------------------------------------------------------------------------------
/client/app/components/AceEditorInput.jsx:
--------------------------------------------------------------------------------
1 | import React, { forwardRef } from "react";
2 | import AceEditor from "react-ace";
3 |
4 | import "./AceEditorInput.less";
5 |
6 | function AceEditorInput(props, ref) {
7 | return (
8 |
19 | );
20 | }
21 |
22 | export default forwardRef(AceEditorInput);
23 |
--------------------------------------------------------------------------------
/client/app/components/AceEditorInput.less:
--------------------------------------------------------------------------------
1 | .ace-editor-input {
2 | // hide ghost cursor when not focused
3 | .ace_hidden-cursors {
4 | opacity: 0;
5 | }
6 |
7 | // allow Ant Form feedback icon to hover scrollbar
8 | .ace_scrollbar {
9 | z-index: auto;
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/client/app/components/ApplicationArea/ApplicationLayout/MobileNavbar.less:
--------------------------------------------------------------------------------
1 | @backgroundColor: #001529;
2 | @dividerColor: rgba(255, 255, 255, 0.5);
3 | @textColor: rgba(255, 255, 255, 0.75);
4 |
5 | .mobile-navbar {
6 | display: flex;
7 | justify-content: space-between;
8 | align-items: center;
9 | background: @backgroundColor;
10 | box-shadow: 0 4px 9px -3px rgba(102, 136, 153, 0.15);
11 | padding: 0 15px;
12 | height: 100%;
13 |
14 | &-logo {
15 | img {
16 | height: 40px;
17 | width: 40px;
18 | }
19 | }
20 |
21 | .ant-btn.mobile-navbar-toggle-button {
22 | padding: 0 10px;
23 | }
24 | }
25 |
26 | .mobile-navbar-menu {
27 | .ant-dropdown-menu-item {
28 | font-weight: 500;
29 | color: @textColor;
30 | }
31 |
32 | .ant-dropdown-menu-item-divider {
33 | background: @dividerColor;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/client/app/components/ApplicationArea/ErrorMessage.less:
--------------------------------------------------------------------------------
1 | .error-message-container {
2 | width: 100%;
3 | padding: 0 15px;
4 | display: flex;
5 | flex-direction: column;
6 | align-items: center;
7 | justify-content: flex-start;
8 |
9 | .error-state {
10 | max-width: 1200px;
11 | width: 100%;
12 |
13 | @media (min-width: 768px) {
14 | width: 65%;
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/client/app/components/ApplicationArea/ErrorMessageDetails.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import PropTypes from "prop-types";
3 |
4 | export function ErrorMessageDetails(props) {
5 | return {props.message}
;
6 | }
7 |
8 | ErrorMessageDetails.propTypes = {
9 | error: PropTypes.instanceOf(Error).isRequired,
10 | message: PropTypes.string.isRequired,
11 | };
12 |
--------------------------------------------------------------------------------
/client/app/components/ApplicationArea/handleNavigationIntent.js:
--------------------------------------------------------------------------------
1 | import { isString } from "lodash";
2 | import navigateTo from "./navigateTo";
3 |
4 | export default function handleNavigationIntent(event) {
5 | let element = event.target;
6 | while (element) {
7 | if (element.tagName === "A") {
8 | break;
9 | }
10 | element = element.parentNode;
11 | }
12 | if (!element || !element.hasAttribute("href") || element.hasAttribute("download") || element.dataset.skipRouter) {
13 | return;
14 | }
15 |
16 | // Keep some default behaviour
17 | if (event.altKey || event.ctrlKey || event.metaKey || event.shiftKey) {
18 | return;
19 | }
20 |
21 | const target = element.getAttribute("target");
22 | if (isString(target) && target.toLowerCase() === "_blank") {
23 | return;
24 | }
25 |
26 | event.preventDefault();
27 |
28 | navigateTo(element.href);
29 | }
30 |
--------------------------------------------------------------------------------
/client/app/components/ApplicationArea/navigateTo.js:
--------------------------------------------------------------------------------
1 | import location from "@/services/location";
2 | import url from "@/services/url";
3 | import { stripBase } from "./Router";
4 |
5 | // When `replace` is set to `true` - it will just replace current URL
6 | // without reloading current page (router will skip this location change)
7 | export default function navigateTo(href, replace = false) {
8 | // Allow calling chain to roll up, and then navigate
9 | setTimeout(() => {
10 | const isExternal = stripBase(href) === false;
11 | if (isExternal) {
12 | window.location = href;
13 | return;
14 | }
15 | href = url.parse(href);
16 | location.update(
17 | {
18 | path: href.pathname,
19 | search: href.search,
20 | hash: href.hash,
21 | },
22 | replace
23 | );
24 | }, 10);
25 | }
26 |
--------------------------------------------------------------------------------
/client/app/components/CodeBlock.less:
--------------------------------------------------------------------------------
1 | @import (reference, less) "~@/assets/less/ant";
2 |
3 | .code-block {
4 | background: rgba(0, 0, 0, 0.06);
5 | border: 1px solid rgba(0, 0, 0, 0.06);
6 | border-radius: 2px;
7 | padding: 3px 27px 3px 3px;
8 | position: relative;
9 | min-height: 32px;
10 |
11 | code {
12 | padding: 0;
13 | font-size: 85%;
14 | }
15 |
16 | .@{btn-prefix-cls} {
17 | position: absolute;
18 | right: 3px;
19 | bottom: 3px;
20 | padding-left: 3px !important;
21 | padding-right: 3px !important;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/client/app/components/Collapse.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import PropTypes from "prop-types";
3 | import cx from "classnames";
4 | import AntCollapse from "antd/lib/collapse";
5 |
6 | export default function Collapse({ collapsed, children, className, ...props }) {
7 | return (
8 |
12 |
13 | {children}
14 |
15 |
16 | );
17 | }
18 |
19 | Collapse.propTypes = {
20 | collapsed: PropTypes.bool,
21 | children: PropTypes.node,
22 | className: PropTypes.string,
23 | };
24 |
25 | Collapse.defaultProps = {
26 | collapsed: true,
27 | children: null,
28 | className: "",
29 | };
30 |
--------------------------------------------------------------------------------
/client/app/components/EditVisualizationButton/index.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import PropTypes from "prop-types";
3 | import Button from "antd/lib/button";
4 | import FormOutlinedIcon from "@ant-design/icons/FormOutlined";
5 |
6 | export default function EditVisualizationButton(props) {
7 | return (
8 |
15 | );
16 | }
17 |
18 | EditVisualizationButton.propTypes = {
19 | openVisualizationEditor: PropTypes.func.isRequired,
20 | selectedTab: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
21 | };
22 |
23 | EditVisualizationButton.defaultProps = {
24 | selectedTab: "",
25 | };
26 |
--------------------------------------------------------------------------------
/client/app/components/NoTaggedObjectsFound.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import PropTypes from "prop-types";
3 | import BigMessage from "@/components/BigMessage";
4 | import { TagsControl } from "@/components/tags-control/TagsControl";
5 |
6 | export default function NoTaggedObjectsFound({ objectType, tags }) {
7 | return (
8 |
9 | No {objectType} found tagged with
10 | .
11 |
12 | );
13 | }
14 |
15 | NoTaggedObjectsFound.propTypes = {
16 | objectType: PropTypes.string.isRequired,
17 | tags: PropTypes.oneOfType([PropTypes.array, PropTypes.objectOf(Set)]).isRequired,
18 | };
19 |
--------------------------------------------------------------------------------
/client/app/components/PageHeader/index.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import PropTypes from "prop-types";
3 |
4 | import "./index.less";
5 |
6 | export default function PageHeader({ title, actions }) {
7 | return (
8 |
9 |
{title}
10 | {actions &&
{actions}
}
11 |
12 | );
13 | }
14 |
15 | PageHeader.propTypes = {
16 | title: PropTypes.string,
17 | actions: PropTypes.node,
18 | };
19 |
20 | PageHeader.defaultProps = {
21 | title: "",
22 | actions: null,
23 | };
24 |
--------------------------------------------------------------------------------
/client/app/components/PageHeader/index.less:
--------------------------------------------------------------------------------
1 | .page-header-wrapper {
2 | margin: 15px 0 10px 0;
3 | display: flex;
4 | flex-direction: row;
5 | flex-wrap: nowrap;
6 | align-items: center;
7 | justify-content: stretch;
8 |
9 | h3 {
10 | margin: 0;
11 | line-height: 1.3;
12 | font-weight: 500;
13 | flex: 1 1 auto;
14 | }
15 |
16 | .page-header-actions {
17 | flex: 0 0 auto;
18 | padding: 0 0 0 15px;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/client/app/components/ParameterValueInput.less:
--------------------------------------------------------------------------------
1 | @import (reference, less) "~@/assets/less/ant"; // for ant @vars
2 |
3 | @input-dirty: #fffce1;
4 |
5 | .parameter-input {
6 | display: inline-block;
7 | position: relative;
8 | width: 100%;
9 |
10 | .@{ant-prefix}-input,
11 | .@{ant-prefix}-input-number {
12 | min-width: 100% !important;
13 | }
14 |
15 | .@{ant-prefix}-select {
16 | width: 100%;
17 | }
18 |
19 | &[data-dirty] {
20 | .@{ant-prefix}-input,
21 | .@{ant-prefix}-input-number,
22 | .@{ant-prefix}-select-selector,
23 | .@{ant-prefix}-picker {
24 | background-color: @input-dirty;
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/client/app/components/PermissionsEditorDialog/index.less:
--------------------------------------------------------------------------------
1 | .permissions-editor-dialog {
2 | .ant-select-dropdown-menu-item-disabled {
3 | // make sure .text-muted has the disabled color
4 | &, .text-muted {
5 | color: rgba(0, 0, 0, 0.25);
6 | }
7 | }
8 | }
--------------------------------------------------------------------------------
/client/app/components/PlainButton.less:
--------------------------------------------------------------------------------
1 | @import (reference, less) "~@/assets/less/ant";
2 |
3 | .plain-button {
4 | all: unset;
5 | transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
6 |
7 | .@{dropdown-prefix-cls}-menu-item > & {
8 | width: 100%;
9 | margin: -5px -12px;
10 | padding: 5px 12px;
11 | }
12 |
13 | .@{menu-prefix-cls}-item > & {
14 | width: 100%;
15 | margin: 0 -16px;
16 | padding: 0 16px;
17 | }
18 | }
19 |
20 | .plain-button-link {
21 | .btn-link();
22 | }
23 |
--------------------------------------------------------------------------------
/client/app/components/PlainButton.tsx:
--------------------------------------------------------------------------------
1 | import classNames from "classnames";
2 | import React from "react";
3 |
4 | import "./PlainButton.less";
5 |
6 | export interface PlainButtonProps extends Omit, "type"> {
7 | type?: "link" | "button";
8 | }
9 |
10 | function PlainButton({ className, type, ...rest }: PlainButtonProps) {
11 | return (
12 |
17 | );
18 | }
19 |
20 | export default PlainButton;
21 |
--------------------------------------------------------------------------------
/client/app/components/QueryLink.less:
--------------------------------------------------------------------------------
1 | .query-link {
2 | .visualization-name {
3 | font-size: 15px;
4 | font-weight: 500;
5 | color: rgba(0, 0, 0, 0.8);
6 | }
7 | }
--------------------------------------------------------------------------------
/client/app/components/SelectItemsDialog.less:
--------------------------------------------------------------------------------
1 | .select-items-list {
2 | &:hover,
3 | &:focus,
4 | &:focus-within {
5 | color: #555;
6 | background-color: #f5f5f5;
7 | transition: all 150ms ease-in-out;
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/client/app/components/Tooltip.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import AntTooltip, { TooltipProps } from "antd/lib/tooltip";
3 | import { isNil } from "lodash";
4 |
5 | export default function Tooltip({ title, ...restProps }: TooltipProps) {
6 | const liveTitle = !isNil(title) ? (
7 |
8 | {title}
9 |
10 | ) : null;
11 |
12 | return ;
13 | }
14 |
--------------------------------------------------------------------------------
/client/app/components/UserGroups.less:
--------------------------------------------------------------------------------
1 | .user-groups {
2 | margin: -5px 0 0 -5px;
3 |
4 | .ant-tag {
5 | margin: 5px 0 0 5px;
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/client/app/components/admin/layout.less:
--------------------------------------------------------------------------------
1 | .admin-page-layout {
2 | .ant-table {
3 | overflow-x: auto;
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/client/app/components/dashboards/TextboxDialog.less:
--------------------------------------------------------------------------------
1 | .textbox-dialog {
2 | small {
3 | display: block;
4 | margin-top: 4px;
5 | }
6 |
7 | .preview {
8 | padding: 9px 9px 1px;
9 | background-color: #f7f7f7;
10 | margin-top: 8px;
11 | word-wrap: break-word
12 | }
13 |
14 | .preview-title {
15 | display: block;
16 | margin-top: -5px;
17 | }
18 | }
--------------------------------------------------------------------------------
/client/app/components/dashboards/dashboard-widget/RestrictedWidget.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Widget from "./Widget";
3 |
4 | function RestrictedWidget(props) {
5 | return (
6 |
7 |
8 |
9 |
10 |
11 |
12 |
没有部件来源数据源权限!
13 |
14 |
15 |
16 | );
17 | }
18 |
19 | export default RestrictedWidget;
20 |
--------------------------------------------------------------------------------
/client/app/components/dashboards/dashboard-widget/index.js:
--------------------------------------------------------------------------------
1 | export { default as VisualizationWidget } from "./VisualizationWidget";
2 | export { default as TextboxWidget } from "./TextboxWidget";
3 | export { default as RestrictedWidget } from "./RestrictedWidget";
4 |
--------------------------------------------------------------------------------
/client/app/components/dynamic-form/DynamicForm.less:
--------------------------------------------------------------------------------
1 | @import (reference, less) "~@/assets/less/ant";
2 |
3 | @btn-extra-options-bg: fade(@redash-gray, 10%);
4 | @btn-extra-options-border: fade(@redash-gray, 15%);
5 |
6 | .dynamic-form {
7 | .extra-options {
8 | margin: 25px 0 10px;
9 | }
10 |
11 | .extra-options-button {
12 | &,
13 | &:focus,
14 | &:hover {
15 | height: 40px;
16 | font-weight: 500;
17 | background-color: @btn-extra-options-bg;
18 | border-color: @btn-extra-options-border;
19 | color: @btn-default-color;
20 | }
21 |
22 | &:focus,
23 | &:hover {
24 | background-color: fade(@btn-extra-options-bg, 15%);
25 | }
26 | }
27 |
28 | .extra-options-content {
29 | margin-top: 15px;
30 |
31 | .ant-form-item:last-of-type {
32 | margin-bottom: 0 !important;
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/client/app/components/dynamic-form/fields/AceEditorField.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import AceEditorInput from "@/components/AceEditorInput";
3 |
4 | export default function AceEditorField({ form, field, ...otherProps }) {
5 | return ;
6 | }
7 |
--------------------------------------------------------------------------------
/client/app/components/dynamic-form/fields/CheckboxField.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Checkbox from "antd/lib/checkbox";
3 | import getFieldLabel from "../getFieldLabel";
4 |
5 | export default function CheckboxField({ form, field, ...otherProps }) {
6 | const fieldLabel = getFieldLabel(field);
7 | return {fieldLabel};
8 | }
9 |
--------------------------------------------------------------------------------
/client/app/components/dynamic-form/fields/ContentField.jsx:
--------------------------------------------------------------------------------
1 | export default function ContentField({ field }) {
2 | return field.content;
3 | }
4 |
--------------------------------------------------------------------------------
/client/app/components/dynamic-form/fields/FileField.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Button from "antd/lib/button";
3 | import Upload from "antd/lib/upload";
4 | import UploadOutlinedIcon from "@ant-design/icons/UploadOutlined";
5 |
6 | export default function FileField({ form, field, ...otherProps }) {
7 | const { name, initialValue } = field;
8 | const { getFieldValue } = form;
9 | const disabled = getFieldValue(name) !== undefined && getFieldValue(name) !== initialValue;
10 |
11 | return (
12 | false}>
13 |
16 |
17 | );
18 | }
19 |
--------------------------------------------------------------------------------
/client/app/components/dynamic-form/fields/InputField.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Input from "antd/lib/input";
3 |
4 | export default function InputField({ form, field, ...otherProps }) {
5 | return ;
6 | }
7 |
--------------------------------------------------------------------------------
/client/app/components/dynamic-form/fields/NumberField.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import InputNumber from "antd/lib/input-number";
3 |
4 | export default function NumberField({ form, field, ...otherProps }) {
5 | return ;
6 | }
7 |
--------------------------------------------------------------------------------
/client/app/components/dynamic-form/fields/SelectField.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Select from "antd/lib/select";
3 |
4 | export default function SelectField({ form, field, ...otherProps }) {
5 | const { readOnly } = field;
6 | return (
7 |
20 | );
21 | }
22 |
--------------------------------------------------------------------------------
/client/app/components/dynamic-form/fields/TextAreaField.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Input from "antd/lib/input";
3 |
4 | export default function TextAreaField({ form, field, ...otherProps }) {
5 | return ;
6 | }
7 |
--------------------------------------------------------------------------------
/client/app/components/dynamic-form/fields/index.js:
--------------------------------------------------------------------------------
1 | export { default as AceEditorField } from "./AceEditorField";
2 | export { default as CheckboxField } from "./CheckboxField";
3 | export { default as ContentField } from "./ContentField";
4 | export { default as FileField } from "./FileField";
5 | export { default as InputField } from "./InputField";
6 | export { default as NumberField } from "./NumberField";
7 | export { default as SelectField } from "./SelectField";
8 | export { default as TextAreaField } from "./TextAreaField";
9 |
--------------------------------------------------------------------------------
/client/app/components/dynamic-form/getFieldLabel.js:
--------------------------------------------------------------------------------
1 | import { toHuman } from "@/lib/utils";
2 |
3 | export default function getFieldLabel(field) {
4 | const { title, name } = field;
5 | return title || toHuman(name);
6 | }
7 |
--------------------------------------------------------------------------------
/client/app/components/dynamic-parameters/DynamicButton.less:
--------------------------------------------------------------------------------
1 | .dynamic-button {
2 | height: 100%;
3 | position: absolute !important;
4 | right: 1px;
5 | top: 0;
6 |
7 | .ant-dropdown-trigger {
8 | height: 100%;
9 | }
10 |
11 | button {
12 | border: none;
13 | padding: 0;
14 | box-shadow: none;
15 | background-color: transparent !important;
16 | }
17 |
18 | &:after {
19 | content: "";
20 | position: absolute;
21 | width: 1px;
22 | height: 19px;
23 | left: 0;
24 | top: 8px;
25 | border-left: 1px dotted rgba(0, 0, 0, 0.12);
26 | }
27 | }
28 |
29 | .dynamic-menu {
30 | width: 187px;
31 |
32 | em {
33 | color: #ccc;
34 | font-size: 11px;
35 | }
36 | }
37 |
38 | .dynamic-icon {
39 | display: flex !important;
40 | align-items: center;
41 | justify-content: center;
42 | }
43 |
--------------------------------------------------------------------------------
/client/app/components/items-list/components/EmptyState.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import BigMessage from "@/components/BigMessage";
3 |
4 | // Default "list empty" message for list pages
5 | export default function EmptyState(props) {
6 | return (
7 |
8 |
9 |
10 | );
11 | }
12 |
--------------------------------------------------------------------------------
/client/app/components/items-list/components/LoadingState.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import BigMessage from "@/components/BigMessage";
3 |
4 | // Default "loading" message for list pages
5 | export default function LoadingState(props) {
6 | return (
7 |
8 |
9 |
10 | );
11 | }
12 |
--------------------------------------------------------------------------------
/client/app/components/layouts/content-with-sidebar.less:
--------------------------------------------------------------------------------
1 | .layout-with-sidebar {
2 | @spacing: 15px;
3 | position: relative;
4 |
5 | display: flex;
6 | align-items: stretch;
7 | justify-content: stretch;
8 | flex-direction: row;
9 | margin: 0;
10 |
11 | > .layout-content {
12 | flex: 1 0 auto;
13 | width: 75%;
14 | order: 1;
15 | margin: 0;
16 | padding: 0 0 0 @spacing
17 | }
18 |
19 | > .layout-sidebar {
20 | flex: 0 0 auto;
21 | width: 25%;
22 | max-width: 350px;
23 | order: 0;
24 | margin: 0;
25 | }
26 |
27 | @media (max-width: 990px) {
28 | flex-direction: column;
29 |
30 | > .layout-content {
31 | width: 100%;
32 | order: 1;
33 | margin: 0;
34 | padding: 0;
35 | }
36 |
37 | > .layout-sidebar {
38 | width: 100%;
39 | max-width: none;
40 | order: 0;
41 | margin: 0 0 @spacing 0;
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/client/app/components/queries/ApiKeyDialog/index.less:
--------------------------------------------------------------------------------
1 | .query-api-key-dialog-wrapper {
2 | .ant-input-group.ant-input-group-compact {
3 | display: flex;
4 | flex-wrap: nowrap;
5 |
6 | .ant-input {
7 | flex-grow: 1;
8 | flex-shrink: 1;
9 | }
10 |
11 | .ant-btn {
12 | flex-grow: 0;
13 | flex-shrink: 0;
14 | height: auto;
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/client/app/components/queries/EmbedQueryDialog.less:
--------------------------------------------------------------------------------
1 | @import (reference, less) "~@/assets/less/ant";
2 |
3 | .embed-query-dialog {
4 | label {
5 | font-weight: normal;
6 | }
7 |
8 | .size-input {
9 | width: 72px;
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/client/app/components/queries/QueryEditor/QueryEditorControls.less:
--------------------------------------------------------------------------------
1 | .query-editor-controls {
2 | display: flex;
3 | flex-wrap: nowrap;
4 | align-items: stretch;
5 | justify-content: stretch;
6 |
7 | // Styles for a wrapper that `Tooltip` adds for disabled `Button`s
8 | span.query-editor-controls-button {
9 | display: flex !important;
10 | align-items: stretch;
11 | justify-content: stretch;
12 | }
13 |
14 | .ant-btn {
15 | height: auto;
16 |
17 | .fa + span,
18 | .zmdi + span {
19 | // if button has icon and label - add some space between them
20 | margin-left: 5px;
21 | }
22 | }
23 |
24 | .query-editor-controls-checkbox {
25 | display: inline-block;
26 | white-space: nowrap;
27 | margin: auto 5px;
28 | }
29 |
30 | .query-editor-controls-spacer {
31 | flex: 1 1 auto;
32 | height: 35px; // same as Antd