mirror of
https://github.com/apache/superset.git
synced 2024-09-12 00:29:39 -04:00
fix: Making the database read-only (#10823)
Co-authored-by: John Bodley <john.bodley@airbnb.com>
This commit is contained in:
parent
d80f406239
commit
a3e2e65121
@ -53,6 +53,7 @@ const propTypes = {
|
||||
onChange: PropTypes.func,
|
||||
clearable: PropTypes.bool,
|
||||
handleError: PropTypes.func.isRequired,
|
||||
isDatabaseSelectEnabled: PropTypes.bool,
|
||||
};
|
||||
|
||||
const defaultProps = {
|
||||
@ -67,6 +68,7 @@ const defaultProps = {
|
||||
sqlLabMode: true,
|
||||
formMode: false,
|
||||
clearable: true,
|
||||
isDatabaseSelectEnabled: true,
|
||||
};
|
||||
|
||||
export default class TableSelector extends React.PureComponent {
|
||||
@ -313,6 +315,7 @@ export default class TableSelector extends React.PureComponent {
|
||||
optionRenderer={this.renderDatabaseOption}
|
||||
mutator={this.dbMutator}
|
||||
placeholder={t('Select a database')}
|
||||
isDisabled={!this.props.isDatabaseSelectEnabled}
|
||||
autoSelect
|
||||
/>,
|
||||
);
|
||||
|
@ -457,15 +457,13 @@ export class DatasourceEditor extends React.PureComponent {
|
||||
onSchemaChange={schema =>
|
||||
this.onDatasourcePropChange('schema', schema)
|
||||
}
|
||||
onDbChange={database =>
|
||||
this.onDatasourcePropChange('database', database)
|
||||
}
|
||||
onTableChange={table =>
|
||||
this.onDatasourcePropChange('datasource_name', table)
|
||||
}
|
||||
sqlLabMode={false}
|
||||
clearable={false}
|
||||
handleError={this.props.addDangerToast}
|
||||
isDatabaseSelectEnabled={false}
|
||||
/>
|
||||
}
|
||||
description={t(
|
||||
@ -748,6 +746,14 @@ export class DatasourceEditor extends React.PureComponent {
|
||||
return (
|
||||
<DatasourceContainer>
|
||||
{this.renderErrors()}
|
||||
<div className="m-t-10">
|
||||
<Alert bsStyle="warning">
|
||||
<strong>{t('Be careful.')} </strong>
|
||||
{t(
|
||||
'Changing these settings will affect all charts using this dataset, including charts owned by other people.',
|
||||
)}
|
||||
</Alert>
|
||||
</div>
|
||||
<Tabs
|
||||
id="table-tabs"
|
||||
onSelect={this.handleTabSelect}
|
||||
@ -830,14 +836,6 @@ export class DatasourceEditor extends React.PureComponent {
|
||||
<Tab eventKey={4} title={t('Settings')}>
|
||||
{activeTabKey === 4 && (
|
||||
<div>
|
||||
<div className="m-t-10">
|
||||
<Alert bsStyle="warning">
|
||||
<strong>{t('Be careful.')} </strong>
|
||||
{t(
|
||||
'Changing these settings will affect all charts using this dataset, including charts owned by other people.',
|
||||
)}
|
||||
</Alert>
|
||||
</div>
|
||||
<Col md={6}>
|
||||
<FormContainer>{this.renderSettingsFieldset()}</FormContainer>
|
||||
</Col>
|
||||
|
@ -14,13 +14,28 @@
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
from typing import Any
|
||||
|
||||
from flask import Markup
|
||||
from flask_appbuilder.fieldwidgets import BS3TextFieldWidget
|
||||
|
||||
from superset.connectors.base.models import BaseDatasource
|
||||
from superset.exceptions import SupersetException
|
||||
from superset.views.base import SupersetModelView
|
||||
|
||||
|
||||
class BS3TextFieldROWidget( # pylint: disable=too-few-public-methods
|
||||
BS3TextFieldWidget
|
||||
):
|
||||
"""
|
||||
Custom read only text field widget.
|
||||
"""
|
||||
|
||||
def __call__(self, field: Any, **kwargs: Any) -> Markup:
|
||||
kwargs["readonly"] = "true"
|
||||
return super().__call__(field, **kwargs)
|
||||
|
||||
|
||||
class DatasourceModelView(SupersetModelView):
|
||||
def pre_delete(self, item: BaseDatasource) -> None:
|
||||
if item.slices:
|
||||
|
@ -25,10 +25,11 @@ from flask_appbuilder.fieldwidgets import Select2Widget
|
||||
from flask_appbuilder.models.sqla.interface import SQLAInterface
|
||||
from flask_appbuilder.security.decorators import has_access
|
||||
from flask_babel import lazy_gettext as _
|
||||
from wtforms import StringField
|
||||
from wtforms.ext.sqlalchemy.fields import QuerySelectField
|
||||
|
||||
from superset import db, security_manager
|
||||
from superset.connectors.base.views import DatasourceModelView
|
||||
from superset.connectors.base.views import BS3TextFieldROWidget, DatasourceModelView
|
||||
from superset.connectors.connector_registry import ConnectorRegistry
|
||||
from superset.connectors.druid import models
|
||||
from superset.constants import RouteMethod
|
||||
@ -98,7 +99,7 @@ class DruidColumnInlineView(CompactCRUDMixin, SupersetModelView):
|
||||
add_form_extra_fields = {
|
||||
"datasource": QuerySelectField(
|
||||
"Datasource",
|
||||
query_factory=lambda: db.session().query(models.DruidDatasource),
|
||||
query_factory=lambda: db.session.query(models.DruidDatasource),
|
||||
allow_blank=True,
|
||||
widget=Select2Widget(extra_classes="readonly"),
|
||||
)
|
||||
@ -179,7 +180,7 @@ class DruidMetricInlineView(CompactCRUDMixin, SupersetModelView):
|
||||
add_form_extra_fields = {
|
||||
"datasource": QuerySelectField(
|
||||
"Datasource",
|
||||
query_factory=lambda: db.session().query(models.DruidDatasource),
|
||||
query_factory=lambda: db.session.query(models.DruidDatasource),
|
||||
allow_blank=True,
|
||||
widget=Select2Widget(extra_classes="readonly"),
|
||||
)
|
||||
@ -333,6 +334,16 @@ class DruidDatasourceModelView(DatasourceModelView, DeleteMixin, YamlExportMixin
|
||||
"changed_by_": _("Changed By"),
|
||||
"modified": _("Modified"),
|
||||
}
|
||||
edit_form_extra_fields = {
|
||||
"cluster": QuerySelectField(
|
||||
"Cluster",
|
||||
query_factory=lambda: db.session.query(models.DruidCluster),
|
||||
widget=Select2Widget(extra_classes="readonly"),
|
||||
),
|
||||
"datasource_name": StringField(
|
||||
"Datasource Name", widget=BS3TextFieldROWidget()
|
||||
),
|
||||
}
|
||||
|
||||
def pre_add(self, item: "DruidDatasourceModelView") -> None:
|
||||
with db.session.no_autoflush:
|
||||
|
@ -160,7 +160,7 @@ class TableColumnInlineView( # pylint: disable=too-many-ancestors
|
||||
add_form_extra_fields = {
|
||||
"table": QuerySelectField(
|
||||
"Table",
|
||||
query_factory=lambda: db.session().query(models.SqlaTable),
|
||||
query_factory=lambda: db.session.query(models.SqlaTable),
|
||||
allow_blank=True,
|
||||
widget=Select2Widget(extra_classes="readonly"),
|
||||
)
|
||||
@ -232,7 +232,7 @@ class SqlMetricInlineView( # pylint: disable=too-many-ancestors
|
||||
add_form_extra_fields = {
|
||||
"table": QuerySelectField(
|
||||
"Table",
|
||||
query_factory=lambda: db.session().query(models.SqlaTable),
|
||||
query_factory=lambda: db.session.query(models.SqlaTable),
|
||||
allow_blank=True,
|
||||
widget=Select2Widget(extra_classes="readonly"),
|
||||
)
|
||||
@ -393,7 +393,7 @@ class TableModelView( # pylint: disable=too-many-ancestors
|
||||
edit_form_extra_fields = {
|
||||
"database": QuerySelectField(
|
||||
"Database",
|
||||
query_factory=lambda: db.session().query(models.Database),
|
||||
query_factory=lambda: db.session.query(models.Database),
|
||||
widget=Select2Widget(extra_classes="readonly"),
|
||||
)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user