From 58f17efa6f5c5f781e73f316742971af76c5fad6 Mon Sep 17 00:00:00 2001 From: Shivam Goel <3541878+shivamgoel@users.noreply.github.com> Date: Wed, 2 Sep 2026 09:00:37 -0700 Subject: [PATCH 01/12] feat(datasource): headless query API for Explorable datasources (#43527) --- .../superset_core/semantic_layers/types.py | 2 + superset/charts/schemas.py | 18 +- superset/common/chart_data.py | 1 + superset/common/query_context_processor.py | 18 + superset/common/tabular_query.py | 436 ++++++++++++++++++ superset/config.py | 3 + superset/datasource/api.py | 360 ++++++++++++++- superset/datasource/schemas.py | 119 ++++- superset/explorables/base.py | 10 + .../mcp_service/dataset/tool/query_dataset.py | 89 ++-- .../semantic_layer/tool/get_table.py | 91 ++-- superset/mcp_service/utils/query_utils.py | 43 +- superset/security/manager.py | 4 + superset/semantic_layers/mapper.py | 55 +-- tests/unit_tests/common/test_tabular_query.py | 426 +++++++++++++++++ tests/unit_tests/datasource/test_query_api.py | 269 +++++++++++ .../unit_tests/semantic_layers/mapper_test.py | 51 +- 17 files changed, 1798 insertions(+), 197 deletions(-) create mode 100644 superset/common/tabular_query.py create mode 100644 tests/unit_tests/common/test_tabular_query.py create mode 100644 tests/unit_tests/datasource/test_query_api.py diff --git a/superset-core/src/superset_core/semantic_layers/types.py b/superset-core/src/superset_core/semantic_layers/types.py index 4fbdadbbfacc..2c6e5da70f12 100644 --- a/superset-core/src/superset_core/semantic_layers/types.py +++ b/superset-core/src/superset_core/semantic_layers/types.py @@ -146,6 +146,8 @@ class Operator(str, enum.Enum): NOT_IN = "NOT IN" LIKE = "LIKE" NOT_LIKE = "NOT LIKE" + ILIKE = "ILIKE" + NOT_ILIKE = "NOT ILIKE" IS_NULL = "IS NULL" IS_NOT_NULL = "IS NOT NULL" ADHOC = "ADHOC" diff --git a/superset/charts/schemas.py b/superset/charts/schemas.py index 76e9d3abdd88..a08217facca7 100644 --- a/superset/charts/schemas.py +++ b/superset/charts/schemas.py @@ -30,7 +30,7 @@ validates, ValidationError, ) -from marshmallow.validate import Length, Range +from marshmallow.validate import Length, NoneOf, Range from marshmallow_union import Union from superset.common.chart_data import ChartDataResultFormat, ChartDataResultType @@ -1588,7 +1588,21 @@ class ChartDataQueryContextSchema(Schema): ) result_type = fields.Enum(ChartDataResultType, by_value=True) - result_format = fields.Enum(ChartDataResultFormat, by_value=True) + result_format = fields.Enum( + ChartDataResultFormat, + by_value=True, + # Arrow is served only by the datasource query endpoint; + # ``_send_chart_response`` has no Arrow branch. Rejecting it here fails + # fast, rather than executing the query and only then returning + # "Unsupported result_format". + validate=NoneOf( + [ChartDataResultFormat.ARROW], + error=( + "result_format 'arrow' is not supported by this endpoint; use " + "POST /api/v1/datasource///query." + ), + ), + ) form_data = fields.Raw(allow_none=True, required=False) diff --git a/superset/common/chart_data.py b/superset/common/chart_data.py index e03f51eee205..36155ee2c7b4 100644 --- a/superset/common/chart_data.py +++ b/superset/common/chart_data.py @@ -25,6 +25,7 @@ class ChartDataResultFormat(StrEnum): CSV = "csv" JSON = "json" XLSX = "xlsx" + ARROW = "arrow" @classmethod def table_like(cls) -> set["ChartDataResultFormat"]: diff --git a/superset/common/query_context_processor.py b/superset/common/query_context_processor.py index 17852041edbc..1debe06a796f 100644 --- a/superset/common/query_context_processor.py +++ b/superset/common/query_context_processor.py @@ -23,6 +23,7 @@ from typing import Any, cast, ClassVar, Sequence, TYPE_CHECKING import pandas as pd +import pyarrow as pa from flask import current_app from flask_babel import gettext as _ @@ -403,6 +404,9 @@ def _grouping_sets_fallback(self, query_object: QueryObject) -> QueryResult: def get_data( self, df: pd.DataFrame, coltypes: list[GenericDataType] ) -> str | bytes | list[dict[str, Any]]: + if self._query_context.result_format == ChartDataResultFormat.ARROW: + return self._to_arrow_ipc(df) + if self._query_context.result_format in ChartDataResultFormat.table_like(): include_index = not isinstance(df.index, pd.RangeIndex) columns = list(df.columns) @@ -429,6 +433,20 @@ def get_data( return df.to_dict(orient="records") + @staticmethod + def _to_arrow_ipc(df: pd.DataFrame) -> bytes: + """Serialize to an Arrow IPC stream for throughput-sensitive callers. + + Serialization happens at response time rather than in the cache, so + Arrow and JSON requests for the same query share cache entries and no + cache-key versioning is needed. + """ + table = pa.Table.from_pandas(df, preserve_index=False) + sink = pa.BufferOutputStream() + with pa.ipc.new_stream(sink, table.schema) as writer: + writer.write_table(table) + return sink.getvalue().to_pybytes() + def _prepare_contribution_totals(self) -> tuple[list[int], int | None]: """ Identify contribution queries and normalize the totals query so cache keys diff --git a/superset/common/tabular_query.py b/superset/common/tabular_query.py new file mode 100644 index 000000000000..1f73cc01c765 --- /dev/null +++ b/superset/common/tabular_query.py @@ -0,0 +1,436 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +"""Name-based tabular querying for any Explorable datasource. + +Shared by the REST query endpoint and the MCP query tools so the resolve → +validate → build → execute sequence exists once. The REST endpoint owns this +contract; other surfaces adapt to it. + +Type dispatch is deliberately absent: ``Explorable.get_query_result`` already +routes datasets to SQL execution and semantic views to the semantic-layer +mapper, so callers pass the datasource type as data and never branch on it. +""" + +from __future__ import annotations + +import difflib +from collections.abc import Sequence +from dataclasses import dataclass, field +from typing import Any, TYPE_CHECKING + +from superset.charts.data.form_data import set_query_context_form_data +from superset.common.chart_data import ChartDataResultFormat +from superset.common.utils.time_range_utils import get_since_until_from_time_range +from superset.daos.datasource import DatasourceDAO +from superset.superset_typing import Column, Metric +from superset.utils.core import DatasourceType, FilterOperator + +if TYPE_CHECKING: + from superset.explorables.base import Explorable + + +# (column name, descending) — mirrors SemanticQuery's OrderTuple, which pairs a +# metric/dimension with an OrderDirection. +OrderSpec = tuple[str, bool] + + +class TabularQueryValidationError(ValueError): + """Raised when a request cannot be satisfied by the target datasource.""" + + +@dataclass +class ResolvedExplorable: + """A datasource resolved and authorized, with its queryable name sets.""" + + explorable: Explorable + display_name: str + time_column: str | None + valid_dimensions: set[str] + valid_metrics: set[str] + dttm_columns: set[str] = field(default_factory=set) + + def resolve_grain_column( + self, time_column: str | None, dimensions: Sequence[Column] | None + ) -> str | None: + """Pick the column a requested time grain should bucket. + + Precedence: an explicit ``time_column``, else a temporal name already + listed in ``dimensions`` (the natural way to ask for buckets), else the + column a ``time_range`` resolved to. + """ + if time_column: + return time_column + for dimension in dimensions or []: + if isinstance(dimension, str) and dimension in self.dttm_columns: + return dimension + return self.time_column + + +def validate_names( + requested: Sequence[str], + valid: set[str], + kind: str, + *, + empty_hint: str | None = None, + list_valid_on_miss: bool = False, + full_list_hint: str = "call get_dataset_info for the full list", +) -> list[str]: + """Return error messages for names not found in *valid*. + + Includes close-match suggestions when available. When *valid* is empty, + appends *empty_hint* instead of a useless fuzzy match. When no close + match exists and *list_valid_on_miss* is set, lists the valid names so + the caller does not have to guess again; *full_list_hint* names the tool + to call when the valid list is truncated. + """ + errors: list[str] = [] + for name in requested: + if name not in valid: + msg = f"Unknown {kind}: '{name}'" + if not valid: + if empty_hint: + msg += f". {empty_hint}" + else: + suggestions = difflib.get_close_matches(name, valid, n=3, cutoff=0.6) + if suggestions: + msg += f". Did you mean: {', '.join(suggestions)}?" + elif list_valid_on_miss: + shown = sorted(valid)[:10] + more = len(valid) - len(shown) + suffix = f" (and {more} more; {full_list_hint})" if more > 0 else "" + msg += f". Valid {kind}s: {', '.join(shown)}{suffix}" + errors.append(msg) + return errors + + +def _display_name(explorable: Explorable) -> str: + """Best available human label; ``Explorable`` does not mandate one.""" + for attr in ("table_name", "name"): + if value := getattr(explorable, attr, None): + return str(value) + return f"{explorable.type} {explorable.id}" + + +def _resolve_time_column( + explorable: Explorable, + display_name: str, + time_column: str | None, + has_time_range: bool, +) -> str | None: + """Resolve and validate the temporal column a time range applies to. + + Datasets carry ``main_dttm_col``; semantic views do not, so a lone datetime + dimension is inferred. Only inferred when a time range was given — an + unfiltered query must not acquire a temporal axis it did not ask for. + """ + valid_columns = {column.column_name for column in explorable.columns} + dttm_columns = [ + column.column_name for column in explorable.columns if column.is_dttm + ] + + resolved = time_column + if resolved is None and has_time_range: + resolved = getattr(explorable, "main_dttm_col", None) + if not resolved and len(dttm_columns) > 1: + # A semantic view's dimensions arrive as an unordered set, so + # picking one here would vary between processes. + raise TabularQueryValidationError( + f"'{display_name}' has multiple datetime dimensions " + f"({', '.join(sorted(dttm_columns))}). Set time_column to " + "choose one." + ) + resolved = resolved or (dttm_columns[0] if dttm_columns else None) + if not resolved: + raise TabularQueryValidationError( + "time_range was provided but no temporal column is configured " + f"on '{display_name}'. Set time_column explicitly." + ) + + if resolved is not None and resolved not in set(dttm_columns): + subject = ( + f"time_column '{resolved}'" + if time_column + else f"the configured temporal column '{resolved}'" + ) + if resolved in valid_columns: + raise TabularQueryValidationError( + f"{subject} on '{display_name}' is not marked as a datetime column." + ) + raise TabularQueryValidationError(f"Unknown {subject} on '{display_name}'.") + return resolved + + +def resolve_explorable( + datasource_type: DatasourceType | str, + datasource_id: int, + *, + time_column: str | None = None, + has_time_range: bool = False, +) -> ResolvedExplorable: + """Look up a datasource, authorize it, and collect its queryable names. + + Raises ``DatasourceNotFound`` / ``DatasourceTypeNotSupportedError`` from + the DAO and ``SupersetSecurityException`` from the access check; callers + map these to their own transport's error shape. + """ + explorable: Explorable = DatasourceDAO.get_datasource( + DatasourceType(datasource_type), datasource_id + ) + explorable.raise_for_access() + + display_name = _display_name(explorable) + return ResolvedExplorable( + explorable=explorable, + display_name=display_name, + time_column=_resolve_time_column( + explorable, display_name, time_column, has_time_range + ), + valid_dimensions={column.column_name for column in explorable.columns}, + valid_metrics={metric.metric_name for metric in explorable.metrics}, + dttm_columns={ + column.column_name for column in explorable.columns if column.is_dttm + }, + ) + + +NO_METRICS_HINT = ( + "This datasource has no metrics defined. Query dimensions only, or add a " + "saved metric to the datasource." +) + + +def validate_query_names( + valid_metrics: set[str], + valid_dimensions: set[str], + *, + metrics: Sequence[Metric] | None = None, + dimensions: Sequence[Column] | None = None, + filters: Sequence[dict[str, Any]] | None = None, + order_names: Sequence[str] | None = None, + metrics_empty_hint: str | None = None, + metrics_full_list_hint: str | None = None, +) -> list[str]: + """Validate every name in a request against the datasource's definitions. + + Takes plain name sets rather than a resolved datasource so callers that + resolve differently — the MCP tools use per-type DAOs — can share it. + + Ad-hoc metrics and columns are dicts rather than names and are skipped + here: datasets accept them, and semantic views reject them downstream in + the mapper, which owns that rule. + """ + errors: list[str] = [] + errors.extend( + validate_names( + [name for name in (dimensions or []) if isinstance(name, str)], + valid_dimensions, + "dimension", + ) + ) + errors.extend( + validate_names( + [name for name in (metrics or []) if isinstance(name, str)], + valid_metrics, + "metric", + empty_hint=metrics_empty_hint or NO_METRICS_HINT, + list_valid_on_miss=True, + # The default names get_dataset_info, which cannot resolve a + # semantic view; callers serving views must name their own tool. + **( + {"full_list_hint": metrics_full_list_hint} + if metrics_full_list_hint + else {} + ), + ) + ) + errors.extend( + validate_names( + [ + clause["col"] + for clause in (filters or []) + if isinstance(clause.get("col"), str) + ], + valid_dimensions, + "filter column", + ) + ) + if order_names: + errors.extend( + validate_names( + order_names, + valid_dimensions | valid_metrics, + "order_by", + ) + ) + return errors + + +def _time_range_filters( + time_column: str, time_range: str, rewrite_one_sided: bool +) -> list[dict[str, Any]]: + """Express *time_range* as query filters. + + Semantic views need a one-sided range rewritten as an explicit comparison: + ``_apply_granularity`` deletes every filter on the granularity column once a + ``TEMPORAL_RANGE`` filter is present, and the mapper's ``_get_time_filter`` + emits nothing unless both bounds resolve, so the range would vanish and the + query would scan the whole view. + + Datasets must keep ``TEMPORAL_RANGE``. ``SqlaTable.get_time_filter`` accepts + either bound alone and is the only path that applies the dataset's timezone, + the legacy hour offset and grain-aware truncation, so rewriting would shift + one-sided results relative to two-sided ones and leave ``from_dttm`` / + ``to_dttm`` unset for Jinja. + """ + temporal_range = [ + { + "col": time_column, + "op": FilterOperator.TEMPORAL_RANGE.value, + "val": time_range, + } + ] + if not rewrite_one_sided: + return temporal_range + + since, until = get_since_until_from_time_range(time_range=time_range) + if since and until: + return temporal_range + + bounds = ( + (FilterOperator.GREATER_THAN_OR_EQUALS, since), + (FilterOperator.LESS_THAN, until), + ) + return [ + {"col": time_column, "op": operator.value, "val": value.isoformat(sep=" ")} + for operator, value in bounds + if value + ] + + +def build_query_dict( + *, + time_column: str | None = None, + metrics: Sequence[Metric] | None = None, + dimensions: Sequence[Column] | None = None, + filters: Sequence[dict[str, Any]] | None = None, + time_range: str | None = None, + time_grain: str | None = None, + grain_column: str | None = None, + limit: int | None = None, + offset: int = 0, + order: Sequence[OrderSpec] | None = None, + order_desc: bool = True, + rewrite_one_sided_time_range: bool = False, +) -> dict[str, Any]: + """Assemble a QueryObject-shaped dict from a name-based request. + + Parameter names follow ``SemanticQuery`` (``limit``, ``offset``, ``order``) + rather than ``QueryObject``; the translation to ``row_limit`` / + ``row_offset`` / ``orderby`` happens here so the request vocabulary stays + independent of the execution model. + """ + query_filters: list[dict[str, Any]] = list(filters or []) + if time_range and time_column: + query_filters.extend( + _time_range_filters(time_column, time_range, rewrite_one_sided_time_range) + ) + + query_columns: list[Column] = list(dimensions or []) + if time_grain and grain_column: + # A grain only takes effect on a BASE_AXIS adhoc column + # (`SqlaTable.adhoc_column_to_sqla` gates on it); `extras.time_grain_sqla` + # alone is read by the semantic-layer mapper but ignored for datasets. + query_columns = [ + column + for column in query_columns + if not (isinstance(column, str) and column == grain_column) + ] + query_columns.insert( + 0, + { + "label": grain_column, + "sqlExpression": grain_column, + # `_normalize_column` rejects adhoc dimensions without this, + # so semantic views would raise on every time_grain query. + "isColumnReference": True, + "columnType": "BASE_AXIS", + "timeGrain": time_grain, + }, + ) + + query_dict: dict[str, Any] = { + "filters": query_filters, + "columns": query_columns, + "metrics": list(metrics or []), + "row_limit": limit, + # Drives series-limit ordering, which has no per-column form. Taken as + # a parameter rather than derived from ``order``, so an empty ``order`` + # does not silently flip it. + "order_desc": order_desc, + } + if offset: + query_dict["row_offset"] = offset + if time_column: + query_dict["granularity"] = time_column + if time_grain: + query_dict["extras"] = {"time_grain_sqla": time_grain} + if order: + # QueryObject.orderby is (name, ascending); the wire carries per-column + # descending flags, so invert each one rather than applying a single + # direction to every column. + query_dict["orderby"] = [(name, not descending) for name, descending in order] + return query_dict + + +def execute_tabular_query( + datasource_id: int, + datasource_type: str, + query_dict: dict[str, Any], + *, + result_format: ChartDataResultFormat = ChartDataResultFormat.JSON, + use_cache: bool = True, + force: bool = False, + cache_timeout: int | None = None, +) -> dict[str, Any]: + """Execute via the standard pipeline and return the command payload. + + Entering at ``QueryContextFactory`` rather than below it is what keeps + caching, RLS, post-processing, and event logging intact. + ``ChartDataCommand.validate`` is the authorization gate. + """ + # Imported here: both modules pull in the datasource stack, which imports + # this one during app setup. + from superset.commands.chart.data.get_data_command import ChartDataCommand + from superset.common.query_context_factory import QueryContextFactory + + query_context = QueryContextFactory().create( + datasource={"id": datasource_id, "type": datasource_type}, + queries=[query_dict], + form_data={}, + result_format=result_format, + force=force or not use_cache, + custom_cache_timeout=cache_timeout, + ) + # Without this, Jinja macros such as {{ current_username() }} cannot see + # the query context and virtual datasets render differently than they do + # through the chart data API. + set_query_context_form_data(query_context, datasource_id, datasource_type) + + command = ChartDataCommand(query_context) + command.validate() + return command.run() diff --git a/superset/config.py b/superset/config.py index 048495b7746d..114ccfcd0bb3 100644 --- a/superset/config.py +++ b/superset/config.py @@ -378,6 +378,9 @@ def _try_json_readsha(filepath: str, length: int) -> str | None: # Add endpoints that need to be exempt from CSRF protection WTF_CSRF_EXEMPT_LIST = [ "superset.charts.data.api.data", + # Headless query endpoint for token-authenticated API clients, exempted for + # the same reason as the chart data endpoint above. + "superset.datasource.api.query", "superset.dashboards.api.cache_dashboard_screenshot", "superset.views.core.log", "superset.views.datasource.views.samples", diff --git a/superset/datasource/api.py b/superset/datasource/api.py index a9f3bc9d3516..3b16dc9413d3 100644 --- a/superset/datasource/api.py +++ b/superset/datasource/api.py @@ -18,22 +18,40 @@ import logging from typing import Any -from flask import current_app as app, request +from flask import current_app as app, make_response, request, Response from flask_appbuilder.api import expose, protect, rison, safe from flask_appbuilder.api.schemas import get_list_schema +from marshmallow import ValidationError from superset import event_logger, is_feature_enabled, security_manager from superset.commands.datasource.list import GetCombinedDatasourceListCommand +from superset.commands.exceptions import CommandException +from superset.common.chart_data import ChartDataResultFormat +from superset.common.tabular_query import ( + build_query_dict, + execute_tabular_query, + resolve_explorable, + ResolvedExplorable, + TabularQueryValidationError, + validate_query_names, +) from superset.connectors.sqla.models import BaseDatasource from superset.daos.datasource import DatasourceDAO from superset.daos.exceptions import DatasourceNotFound, DatasourceTypeNotSupportedError -from superset.exceptions import SupersetSecurityException +from superset.datasource.schemas import DatasourceQuerySchema +from superset.exceptions import ( + QueryObjectValidationError, + SupersetException, + SupersetSecurityException, +) from superset.extensions import cache_manager +from superset.semantic_layers.mapper import SUPPORTED_FILTER_OPERATORS from superset.superset_typing import FlaskResponse from superset.utils import json from superset.utils.core import ( apply_max_row_limit, DatasourceType, + FilterOperator, parse_boolean_string, SqlExpressionType, ) @@ -45,14 +63,31 @@ SEARCH_CACHE_TIMEOUT = 60 +class _HttpError(Exception): + """Carries an HTTP status out of the shared resolve helper.""" + + def __init__(self, status: int, message: str) -> None: + super().__init__(message) + self.status = status + self.message = message + + class DatasourceRestApi(BaseSupersetApi): allow_browser_login = True class_permission_name = "Datasource" method_permission_name = { "combined_list": "read", + # Both new routes share can_query. Notably `datasource_info` is NOT + # named `get`: PUBLIC_ROLE_PERMISSIONS already grants + # ("can_get", "Datasource") for chart rendering, so a method named + # `get` would expose datasource metadata to unauthenticated users + # wherever PUBLIC_ROLE_LIKE = "Public". + "query": "query", + "datasource_info": "query", } resource_name = "datasource" openapi_spec_tag = "Datasources" + openapi_spec_component_schemas = (DatasourceQuerySchema,) @expose( "///column//values/", @@ -544,6 +579,327 @@ def compatible(self, datasource_type: str, datasource_id: int) -> FlaskResponse: return self.response(200, result=result) + def _resolve_for_query( + self, datasource_type: str, datasource_id: int, payload: dict[str, Any] + ) -> ResolvedExplorable: + """Resolve + authorize, translating DAO/security errors to HTTP.""" + if DatasourceType( + datasource_type + ) == DatasourceType.SEMANTIC_VIEW and not is_feature_enabled("SEMANTIC_LAYERS"): + raise _HttpError(404, "Semantic views are not enabled.") + try: + return resolve_explorable( + datasource_type, + datasource_id, + time_column=payload.get("time_column"), + has_time_range=bool(payload.get("time_range")), + ) + except DatasourceTypeNotSupportedError as ex: + raise _HttpError(400, ex.message) from ex + except DatasourceNotFound as ex: + raise _HttpError(404, ex.message) from ex + except SupersetSecurityException as ex: + raise _HttpError(403, ex.message) from ex + except TabularQueryValidationError as ex: + raise _HttpError(400, str(ex)) from ex + + @expose("///query", methods=("POST",)) + @protect() + @safe + @statsd_metrics + @event_logger.log_this_with_context( + action=lambda self, *args, **kwargs: f"{self.__class__.__name__}.query", + log_to_statsd=False, + ) + def query(self, datasource_type: str, datasource_id: int) -> FlaskResponse: + """Query a datasource using metric and dimension names. + --- + post: + summary: Query a datasource by its semantic definitions + parameters: + - in: path + schema: + type: string + name: datasource_type + - in: path + schema: + type: integer + name: datasource_id + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/DatasourceQuerySchema' + responses: + 200: + description: Query result + content: + application/json: + schema: + type: object + properties: + result: + type: array + items: + type: object + application/vnd.apache.arrow.stream: + schema: + type: string + format: binary + 400: + $ref: '#/components/responses/400' + 401: + $ref: '#/components/responses/401' + 403: + $ref: '#/components/responses/403' + 404: + $ref: '#/components/responses/404' + """ + try: + payload = DatasourceQuerySchema().load(request.json or {}) + except ValidationError as ex: + return self.response_400(message=ex.messages) + + try: + resolved = self._resolve_for_query(datasource_type, datasource_id, payload) + except _HttpError as ex: + return self.response(ex.status, message=ex.message) + except ValueError: + return self.response( + 400, message=f"Invalid datasource type: {datasource_type}" + ) + + if errors := validate_query_names( + resolved.valid_metrics, + resolved.valid_dimensions, + metrics=payload["metrics"], + dimensions=payload["dimensions"], + filters=payload["filters"], + order_names=[term["column"] for term in payload["order"]], + metrics_full_list_hint=( + f"GET /api/v1/datasource/{datasource_type}/{datasource_id}" + ), + ): + return self.response_400(message="; ".join(errors)) + + return self._execute_and_respond(resolved, payload) + + def _execute_and_respond( + self, resolved: ResolvedExplorable, payload: dict[str, Any] + ) -> FlaskResponse: + """Run the query and render it in the requested result format.""" + database = getattr(resolved.explorable, "database", None) + if ( + payload["offset"] + and database + and not database.db_engine_spec.supports_offset + ): + # get_sqla_query drops row_offset for these engines, so the request + # would return the first page again under a 200. + return self.response_400( + message=( + f"{database.db_engine_spec.engine} does not support offset " + "pagination." + ) + ) + + grain_column = resolved.resolve_grain_column( + payload["time_column"], payload["dimensions"] + ) + if payload["time_grain"]: + if not grain_column: + # Silently dropping the grain would return unbucketed rows that + # look correct, so refuse instead. + return self.response_400( + message=( + "time_grain requires a temporal column. Set time_column, " + "include a datetime dimension, or provide time_range." + ) + ) + supported = { + grain["duration"] for grain in resolved.explorable.get_time_grains() + } + if payload["time_grain"] not in supported: + # Unsupported grains reach get_timestamp_expr, which raises + # NotImplementedError rather than a validation error. + return self.response_400( + message=( + f"Unsupported time_grain: '{payload['time_grain']}'. " + f"Supported: {', '.join(sorted(g for g in supported if g))}." + ) + ) + + try: + query_dict = self._build_query_dict(resolved, payload, grain_column) + except ValidationError as ex: + return self.response_400(message=ex.messages) + except ValueError as ex: + return self.response_400(message=str(ex)) + + return self._run(resolved, payload, query_dict) + + @staticmethod + def _build_query_dict( + resolved: ResolvedExplorable, payload: dict[str, Any], grain_column: str | None + ) -> dict[str, Any]: + return build_query_dict( + time_column=resolved.time_column, + metrics=payload["metrics"], + dimensions=payload["dimensions"], + filters=payload["filters"], + time_range=payload["time_range"], + time_grain=payload["time_grain"], + grain_column=grain_column, + rewrite_one_sided_time_range=( + resolved.explorable.type == DatasourceType.SEMANTIC_VIEW.value + ), + limit=payload["limit"], + offset=payload["offset"], + order=[(term["column"], term["descending"]) for term in payload["order"]], + # No wire field for this; follow the leading term's direction. + order_desc=( + payload["order"][0]["descending"] if payload["order"] else True + ), + ) + + def _run( + self, + resolved: ResolvedExplorable, + payload: dict[str, Any], + query_dict: dict[str, Any], + ) -> FlaskResponse: + result_format = payload["result_format"] + + try: + result = execute_tabular_query( + int(resolved.explorable.id), + str(resolved.explorable.type), + query_dict, + result_format=result_format, + use_cache=payload["use_cache"], + force=payload["force"], + cache_timeout=payload["cache_timeout"], + ) + except SupersetSecurityException as ex: + return self.response(403, message=ex.message) + except (ValueError, QueryObjectValidationError) as ex: + return self.response_400(message=str(ex)) + except CommandException as ex: + return self.response_400(message=ex.message or str(ex)) + + queries = result.get("queries") or [] + if result_format == ChartDataResultFormat.ARROW: + if len(queries) != 1: + return self.response_400( + message="Arrow result format supports exactly one query." + ) + return Response( + queries[0]["data"], + mimetype="application/vnd.apache.arrow.stream", + ) + response = make_response( + json.dumps( + {"result": queries}, + default=json.json_int_dttm_ser, + ignore_nan=True, + ), + 200, + ) + response.headers["Content-Type"] = "application/json; charset=utf-8" + return response + + @expose("//", methods=("GET",)) + @protect() + @safe + @statsd_metrics + @event_logger.log_this_with_context( + action=lambda self, *args, **kwargs: ( + f"{self.__class__.__name__}.datasource_info" + ), + log_to_statsd=False, + ) + def datasource_info( + self, datasource_type: str, datasource_id: int + ) -> FlaskResponse: + """Get datasource metadata and query capabilities. + --- + get: + summary: Get datasource metadata and capabilities + parameters: + - in: path + schema: + type: string + name: datasource_type + - in: path + schema: + type: integer + name: datasource_id + responses: + 200: + description: Datasource metadata plus a capabilities block + content: + application/json: + schema: + type: object + properties: + result: + type: object + 400: + $ref: '#/components/responses/400' + 401: + $ref: '#/components/responses/401' + 403: + $ref: '#/components/responses/403' + 404: + $ref: '#/components/responses/404' + """ + try: + resolved = self._resolve_for_query(datasource_type, datasource_id, {}) + except _HttpError as ex: + return self.response(ex.status, message=ex.message) + except ValueError: + return self.response( + 400, message=f"Invalid datasource type: {datasource_type}" + ) + + try: + datasource = resolved.explorable + is_semantic_view = ( + DatasourceType(datasource_type) == DatasourceType.SEMANTIC_VIEW + ) + supported_operators = ( + SUPPORTED_FILTER_OPERATORS + if is_semantic_view + else {op.value for op in FilterOperator} + ) + features = sorted( + feature.value + for feature in getattr( + getattr(datasource, "implementation", None), "features", set() + ) + ) + result = dict(datasource.data) + result["capabilities"] = { + "is_rls_supported": datasource.is_rls_supported, + "query_language": datasource.query_language, + "supports_samples": getattr(datasource, "supports_samples", True), + "supports_drill_to_detail": getattr( + datasource, "supports_drill_to_detail", True + ), + # Datasets accept ad-hoc metrics; semantic views reject them in the + # mapper, since the provider owns metric definitions. + "supports_adhoc_metrics": not is_semantic_view, + "time_grains": datasource.get_time_grains(), + "supported_operators": sorted(supported_operators), + "features": features, + } + return self.response(200, result=result) + except SupersetSecurityException as ex: + return self.response(403, message=ex.message) + except (ValueError, SupersetException) as ex: + return self.response_400(message=str(ex)) + @expose("/", methods=("GET",)) @protect() @safe diff --git a/superset/datasource/schemas.py b/superset/datasource/schemas.py index 3f8f2ba5298e..1008d3d5246c 100644 --- a/superset/datasource/schemas.py +++ b/superset/datasource/schemas.py @@ -14,16 +14,23 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -"""Marshmallow schemas for the combined datasource list endpoint.""" +"""Marshmallow schemas for the datasource list and query endpoints.""" from __future__ import annotations -from marshmallow import fields, Schema +from marshmallow import fields, Schema, validates_schema, ValidationError +from marshmallow.validate import OneOf, Range +from superset.charts.schemas import ChartDataFilterSchema +from superset.common.chart_data import ChartDataResultFormat from superset.connectors.sqla.models import SqlaTable from superset.semantic_layers.models import SemanticView from superset.subjects.schemas import SubjectResponseSchema +# Matches the MCP query tools' ceiling so the two surfaces agree. The server +# additionally clamps via apply_max_row_limit against ROW_LIMIT. +MAX_ROW_LIMIT = 50_000 + class _ChangedBySchema(Schema): first_name = fields.String() @@ -140,3 +147,111 @@ def get_changed_on_delta_humanized(self, obj: SemanticView) -> str: def get_changed_on_utc(self, obj: SemanticView) -> str: return obj.changed_on_utc() + + +class DatasourceQueryOrderSchema(Schema): + """One ordering term, mirroring SemanticQuery's OrderTuple.""" + + column = fields.String( + required=True, + metadata={"description": "Metric or dimension name to sort by."}, + ) + descending = fields.Boolean( + load_default=True, + metadata={"description": "Sort this column descending."}, + ) + + +class DatasourceQuerySchema(Schema): + """Name-based query request for POST /datasource///query. + + Field names mirror the semantic-layer vocabulary (``dimensions``, + ``metrics``) rather than Explore's (``columns``); translation to the + QueryObject shape happens in ``superset.common.tabular_query``. + """ + + # Raw, not String: Metric/Column are `AdhocMetric | str` and + # `AdhocColumn | str`, so ad-hoc expressions are accepted for datasets + # exactly as ChartDataQueryObjectSchema accepts them. Semantic views + # reject ad-hoc metrics downstream, in the mapper that owns that rule. + metrics = fields.List( + fields.Raw(), + load_default=list, + metadata={ + "description": "Saved metric names, or ad-hoc metric objects " + "(datasets only). See ChartDataAdhocMetricSchema." + }, + ) + dimensions = fields.List( + fields.Raw(), + load_default=list, + metadata={"description": "Dimension/column names to group by."}, + ) + filters = fields.List( + fields.Nested(ChartDataFilterSchema), + load_default=list, + metadata={"description": "Filters to apply, AND-ed together."}, + ) + time_range = fields.String( + allow_none=True, + load_default=None, + metadata={"description": "e.g. 'Last 30 days' or '2024-01-01 : 2024-12-31'."}, + ) + time_column = fields.String( + allow_none=True, + load_default=None, + metadata={ + "description": "Temporal column the time range applies to. Inferred " + "from the datasource when omitted." + }, + ) + time_grain = fields.String( + allow_none=True, + load_default=None, + metadata={"description": "ISO 8601 duration, e.g. 'P1D' or 'PT1H'."}, + ) + limit = fields.Integer( + allow_none=True, + load_default=None, + validate=[Range(min=1, max=MAX_ROW_LIMIT)], + metadata={ + "description": "Rows to return. Also clamped server-side by ROW_LIMIT." + }, + ) + offset = fields.Integer( + load_default=0, + validate=[Range(min=0)], + metadata={"description": "Rows to skip, for pagination."}, + ) + order = fields.List( + fields.Nested(DatasourceQueryOrderSchema), + load_default=list, + metadata={ + "description": "Ordering terms, applied in sequence. Each carries its " + "own direction." + }, + ) + result_format = fields.Enum( + ChartDataResultFormat, + by_value=True, + load_default=ChartDataResultFormat.JSON, + validate=OneOf([ChartDataResultFormat.JSON, ChartDataResultFormat.ARROW]), + metadata={ + "description": "'json' (default) or 'arrow' for an Arrow IPC stream." + }, + ) + use_cache = fields.Boolean(load_default=True) + force = fields.Boolean(load_default=False) + cache_timeout = fields.Integer( + allow_none=True, + load_default=None, + # -1 is CACHE_DISABLED_TIMEOUT; anything below it is meaningless and + # would reach the cache backend as an arbitrary negative timeout. + validate=[Range(min=-1)], + metadata={"description": "Seconds to cache for; -1 disables caching."}, + ) + + @validates_schema + def validate_not_empty(self, data: dict[str, object], **_kwargs: object) -> None: + if not data.get("metrics") and not data.get("dimensions"): + raise ValidationError("Provide at least one metric or dimension.") diff --git a/superset/explorables/base.py b/superset/explorables/base.py index 7ab9b3b7a1ec..545fa3ce947e 100644 --- a/superset/explorables/base.py +++ b/superset/explorables/base.py @@ -485,6 +485,16 @@ def has_drill_by_columns(self, column_names: list[str]) -> bool: # Optional Properties # ========================================================================= + def raise_for_access(self) -> None: + """ + Raise if the current user may not access this explorable. + + Implemented by every explorable and relied on by callers before any + query is built, so it belongs on the protocol. + + :raises SupersetSecurityException: if access is denied + """ + @property def is_rls_supported(self) -> bool: """ diff --git a/superset/mcp_service/dataset/tool/query_dataset.py b/superset/mcp_service/dataset/tool/query_dataset.py index eb843a07e24a..f138ab95ce41 100644 --- a/superset/mcp_service/dataset/tool/query_dataset.py +++ b/superset/mcp_service/dataset/tool/query_dataset.py @@ -31,8 +31,12 @@ from sqlalchemy.orm import joinedload, subqueryload from superset_core.mcp.decorators import tool, ToolAnnotations -from superset.charts.data.form_data import set_query_context_form_data from superset.commands.exceptions import CommandException +from superset.common.tabular_query import ( + build_query_dict, + execute_tabular_query, + validate_query_names, +) from superset.exceptions import OAuth2Error, OAuth2RedirectError, SupersetException from superset.extensions import event_logger from superset.mcp_service.chart.schemas import DataColumn, PerformanceMetadata @@ -50,7 +54,6 @@ ) from superset.mcp_service.utils.cache_utils import get_cache_status_from_result from superset.mcp_service.utils.oauth2_utils import build_oauth2_redirect_message -from superset.mcp_service.utils.query_utils import validate_names from superset.mcp_service.utils.response_utils import format_data_columns logger = logging.getLogger(__name__) @@ -115,8 +118,6 @@ async def query_dataset( # noqa: C901 ) try: - from superset.commands.chart.data.get_data_command import ChartDataCommand - from superset.common.query_context_factory import QueryContextFactory from superset.connectors.sqla.models import SqlaTable # ------------------------------------------------------------------ @@ -176,30 +177,15 @@ async def query_dataset( # noqa: C901 valid_columns = {c.column_name for c in dataset.columns} valid_metrics = {m.metric_name for m in dataset.metrics} - validation_errors: list[str] = [] - validation_errors.extend( - validate_names(request.columns, valid_columns, "column") - ) - validation_errors.extend( - validate_names( - request.metrics, - valid_metrics, - "metric", - empty_hint=_NO_SAVED_METRICS_HINT, - list_valid_on_miss=True, - ) + validation_errors: list[str] = validate_query_names( + valid_metrics, + valid_columns, + metrics=request.metrics, + dimensions=request.columns, + filters=[{"col": f.col} for f in request.filters], + order_names=request.order_by, + metrics_empty_hint=_NO_SAVED_METRICS_HINT, ) - # Validate filter column names against dataset columns - filter_cols = [f.col for f in request.filters] - validation_errors.extend( - validate_names(filter_cols, valid_columns, "filter column") - ) - # Validate order_by names against columns + metrics - if request.order_by: - valid_orderby = valid_columns | valid_metrics - validation_errors.extend( - validate_names(request.order_by, valid_orderby, "order_by") - ) if validation_errors: error_msg = "; ".join(validation_errors) @@ -275,20 +261,17 @@ async def query_dataset( # noqa: C901 # Step 4: Build query dict # ------------------------------------------------------------------ await ctx.report_progress(3, 5, "Building query") - query_dict: dict[str, Any] = { - "filters": query_filters, - "columns": request.columns, - "metrics": request.metrics, - "row_limit": request.row_limit, - "order_desc": request.order_desc, - } - if granularity: - query_dict["granularity"] = granularity - if request.order_by: - # OrderBy = tuple[Metric | Column, bool] where bool is ascending - query_dict["orderby"] = [ - (col, not request.order_desc) for col in request.order_by - ] + # time_range is not passed through: the TEMPORAL_RANGE clause is already + # in query_filters above, alongside the effective_filters bookkeeping. + query_dict: dict[str, Any] = build_query_dict( + time_column=granularity, + metrics=request.metrics, + dimensions=request.columns, + filters=query_filters, + limit=request.row_limit, + order=[(name, request.order_desc) for name in (request.order_by or [])], + order_desc=request.order_desc, + ) await ctx.debug("Query dict keys: %s" % (sorted(query_dict.keys()),)) @@ -299,25 +282,15 @@ async def query_dataset( # noqa: C901 start_time = time.time() with event_logger.log_context(action="mcp.query_dataset.execute"): - factory = QueryContextFactory() - # datasource_type is "table" because this tool queries SqlaTable - # datasets (Superset's built-in semantic layer). External semantic - # layers (dbt, Snowflake Cortex, etc.) use "semantic_view" and have - # a different query path — see SemanticView + mapper.py. - query_context = factory.create( - datasource={"id": dataset.id, "type": "table"}, - queries=[query_dict], - form_data={}, - force=not request.use_cache or request.force_refresh, - custom_cache_timeout=request.cache_timeout, + result = execute_tabular_query( + dataset.id, + "table", + query_dict, + use_cache=request.use_cache, + force=request.force_refresh, + cache_timeout=request.cache_timeout, ) - set_query_context_form_data(query_context, dataset.id, "table") - - command = ChartDataCommand(query_context) - command.validate() - result = command.run() - query_duration_ms = int((time.time() - start_time) * 1000) if not result or "queries" not in result or len(result["queries"]) == 0: diff --git a/superset/mcp_service/semantic_layer/tool/get_table.py b/superset/mcp_service/semantic_layer/tool/get_table.py index 39078b1116a9..089bd8c92987 100644 --- a/superset/mcp_service/semantic_layer/tool/get_table.py +++ b/superset/mcp_service/semantic_layer/tool/get_table.py @@ -31,6 +31,11 @@ from superset_core.mcp.decorators import tool, ToolAnnotations from superset.commands.exceptions import CommandException +from superset.common.tabular_query import ( + build_query_dict, + execute_tabular_query, + validate_query_names, +) from superset.exceptions import OAuth2Error, OAuth2RedirectError, SupersetException from superset.extensions import event_logger from superset.mcp_service.chart.schemas import PerformanceMetadata @@ -46,7 +51,6 @@ ) from superset.mcp_service.utils.cache_utils import get_cache_status_from_result from superset.mcp_service.utils.oauth2_utils import build_oauth2_redirect_message -from superset.mcp_service.utils.query_utils import validate_names from superset.mcp_service.utils.response_utils import format_data_columns logger = logging.getLogger(__name__) @@ -191,30 +195,18 @@ def _validate_request_names( request: GetTableRequest, valid_columns: set[str], valid_metrics: set[str] ) -> list[str]: """Validate requested dimensions, metrics, filters, and order_by names.""" - validation_errors: list[str] = [] - validation_errors.extend( - validate_names(request.dimensions, valid_columns, "dimension") - ) - validation_errors.extend( - validate_names( - request.metrics, - valid_metrics, - "metric", - empty_hint=_NO_METRICS_HINT, - list_valid_on_miss=True, - full_list_hint="call list_metrics for the full list", - ) - ) - filter_cols = [f.col for f in request.filters] - validation_errors.extend( - validate_names(filter_cols, valid_columns, "filter column") + return validate_query_names( + valid_metrics, + valid_columns, + metrics=request.metrics, + dimensions=request.dimensions, + filters=[{"col": f.col} for f in request.filters], + order_names=request.order_by, + metrics_empty_hint=_NO_METRICS_HINT, + # get_table also serves semantic views, which get_dataset_info + # cannot resolve. + metrics_full_list_hint="call list_metrics for the full list", ) - if request.order_by: - valid_orderby = valid_columns | valid_metrics - validation_errors.extend( - validate_names(request.order_by, valid_orderby, "order_by") - ) - return validation_errors def _build_query_dict( @@ -222,28 +214,17 @@ def _build_query_dict( time_col: str | None, ) -> dict[str, Any]: """Assemble the query dict for QueryContextFactory.""" - filters: list[dict[str, Any]] = [ - {"col": f.col, "op": f.op, "val": f.val} for f in request.filters - ] - if request.time_range and time_col: - filters.append( - {"col": time_col, "op": "TEMPORAL_RANGE", "val": request.time_range} - ) - - query_dict: dict[str, Any] = { - "filters": filters, - "columns": request.dimensions, - "metrics": request.metrics, - "row_limit": request.row_limit, - "order_desc": request.order_desc, - } - if time_col: - query_dict["granularity"] = time_col - if request.order_by: - query_dict["orderby"] = [ - (col, not request.order_desc) for col in request.order_by - ] - return query_dict + return build_query_dict( + time_column=time_col, + metrics=request.metrics, + dimensions=request.dimensions, + filters=[{"col": f.col, "op": f.op, "val": f.val} for f in request.filters], + time_range=request.time_range, + limit=request.row_limit, + order=[(name, request.order_desc) for name in request.order_by], + order_desc=request.order_desc, + rewrite_one_sided_time_range=request.view_id is not None, + ) def _build_response( @@ -316,9 +297,6 @@ async def _run_get_table_query( datasource_type: str, ) -> GetTableResponse | SemanticLayerError: """Resolve, validate, execute, and format a get_table request.""" - from superset.commands.chart.data.get_data_command import ChartDataCommand - from superset.common.query_context_factory import QueryContextFactory - await ctx.report_progress(1, 5, "Resolving data source") resolved = ( _resolve_builtin_dataset(request) @@ -348,16 +326,13 @@ async def _run_get_table_query( start_time = time.time() with event_logger.log_context(action="mcp.get_table.execute"): - factory = QueryContextFactory() - query_context = factory.create( - datasource={"id": datasource_id, "type": datasource_type}, - queries=[query_dict], - form_data={}, - force=not request.use_cache or request.force_refresh, + result = execute_tabular_query( + datasource_id, + datasource_type, + query_dict, + use_cache=request.use_cache, + force=request.force_refresh, ) - command = ChartDataCommand(query_context) - command.validate() - result = command.run() query_duration_ms = int((time.time() - start_time) * 1000) diff --git a/superset/mcp_service/utils/query_utils.py b/superset/mcp_service/utils/query_utils.py index a91a4669feeb..1e10ed27cce5 100644 --- a/superset/mcp_service/utils/query_utils.py +++ b/superset/mcp_service/utils/query_utils.py @@ -15,43 +15,12 @@ # specific language governing permissions and limitations # under the License. -"""Shared query validation utilities for MCP tools.""" +"""Backwards-compatible re-export of the shared name validator. -import difflib +The implementation now lives in ``superset.common.tabular_query`` so the REST +endpoint and the MCP tools cannot drift apart. +""" +from superset.common.tabular_query import validate_names -def validate_names( - requested: list[str], - valid: set[str], - kind: str, - *, - empty_hint: str | None = None, - list_valid_on_miss: bool = False, - full_list_hint: str = "call get_dataset_info for the full list", -) -> list[str]: - """Return list of error messages for names not found in *valid*. - - Includes close-match suggestions when available. When *valid* is empty, - appends *empty_hint* instead of a useless fuzzy match. When no close - match exists and *list_valid_on_miss* is set, lists the valid names so - the caller does not have to guess again; *full_list_hint* names the tool - to call when the valid list is truncated. - """ - errors: list[str] = [] - for name in requested: - if name not in valid: - msg = f"Unknown {kind}: '{name}'" - if not valid: - if empty_hint: - msg += f". {empty_hint}" - else: - suggestions = difflib.get_close_matches(name, valid, n=3, cutoff=0.6) - if suggestions: - msg += f". Did you mean: {', '.join(suggestions)}?" - elif list_valid_on_miss: - shown = sorted(valid)[:10] - more = len(valid) - len(shown) - suffix = f" (and {more} more; {full_list_hint})" if more > 0 else "" - msg += f". Valid {kind}s: {', '.join(shown)}{suffix}" - errors.append(msg) - return errors +__all__ = ["validate_names"] diff --git a/superset/security/manager.py b/superset/security/manager.py index a59cbb74ad8b..a12f80cb93fe 100644 --- a/superset/security/manager.py +++ b/superset/security/manager.py @@ -1807,6 +1807,10 @@ class SupersetSecurityManager( # pylint: disable=too-many-public-methods "can_external_metadata_by_name", "can_read", "can_get_drill_info", + # Datasource querying is a read operation. Without this, Datasource + # being in GAMMA_READ_ONLY_MODEL_VIEWS makes _is_alpha_only withhold + # can_query from Gamma. + "can_query", } ALPHA_ONLY_PERMISSIONS = { diff --git a/superset/semantic_layers/mapper.py b/superset/semantic_layers/mapper.py index 936a0d576dc1..32a6ea2c4501 100644 --- a/superset/semantic_layers/mapper.py +++ b/superset/semantic_layers/mapper.py @@ -68,6 +68,30 @@ ) from superset.utils.date_parser import get_past_or_future +OPERATOR_MAP = { + FilterOperator.EQUALS.value: Operator.EQUALS, + FilterOperator.NOT_EQUALS.value: Operator.NOT_EQUALS, + FilterOperator.GREATER_THAN.value: Operator.GREATER_THAN, + FilterOperator.LESS_THAN.value: Operator.LESS_THAN, + FilterOperator.GREATER_THAN_OR_EQUALS.value: Operator.GREATER_THAN_OR_EQUAL, + FilterOperator.LESS_THAN_OR_EQUALS.value: Operator.LESS_THAN_OR_EQUAL, + FilterOperator.IN.value: Operator.IN, + FilterOperator.NOT_IN.value: Operator.NOT_IN, + FilterOperator.LIKE.value: Operator.LIKE, + FilterOperator.NOT_LIKE.value: Operator.NOT_LIKE, + # Case-insensitive matching is passed through to the provider, which + # resolves it per its own collation rules. There is no capability flag for + # this yet, so a provider that cannot express it will surface an error. + FilterOperator.ILIKE.value: Operator.ILIKE, + FilterOperator.NOT_ILIKE.value: Operator.NOT_ILIKE, + FilterOperator.IS_NULL.value: Operator.IS_NULL, + FilterOperator.IS_NOT_NULL.value: Operator.IS_NOT_NULL, +} + +SUPPORTED_FILTER_OPERATORS = frozenset(OPERATOR_MAP) | { + FilterOperator.TEMPORAL_RANGE.value +} + class ValidatedQueryObjectFilterClause(QueryObjectFilterClause): """ @@ -699,36 +723,7 @@ def _convert_query_object_filter( value = _coerce_filter_value(value, dimension) - # Map QueryObject operators to semantic layer operators. The Operator enum - # exposes only LIKE (case-sensitive), so case-insensitive variants are - # rejected up front rather than silently collapsed: doing so leaves the - # actual case handling at the mercy of the semantic backend's collation - # and silently diverges from the operator the dashboard author chose. - if operator_str in { - FilterOperator.ILIKE.value, - FilterOperator.NOT_ILIKE.value, - }: - raise ValueError( - f"Operator {operator_str} (case-insensitive match) is not supported " - "by Semantic Views; use the case-sensitive LIKE/NOT_LIKE instead." - ) - - operator_mapping = { - FilterOperator.EQUALS.value: Operator.EQUALS, - FilterOperator.NOT_EQUALS.value: Operator.NOT_EQUALS, - FilterOperator.GREATER_THAN.value: Operator.GREATER_THAN, - FilterOperator.LESS_THAN.value: Operator.LESS_THAN, - FilterOperator.GREATER_THAN_OR_EQUALS.value: Operator.GREATER_THAN_OR_EQUAL, - FilterOperator.LESS_THAN_OR_EQUALS.value: Operator.LESS_THAN_OR_EQUAL, - FilterOperator.IN.value: Operator.IN, - FilterOperator.NOT_IN.value: Operator.NOT_IN, - FilterOperator.LIKE.value: Operator.LIKE, - FilterOperator.NOT_LIKE.value: Operator.NOT_LIKE, - FilterOperator.IS_NULL.value: Operator.IS_NULL, - FilterOperator.IS_NOT_NULL.value: Operator.IS_NOT_NULL, - } - - operator = operator_mapping.get(operator_str) + operator = OPERATOR_MAP.get(operator_str) if not operator: # Unknown operator - raise error to prevent unauthorized access raise ValueError(f"Unsupported filter operator: {operator_str}") diff --git a/tests/unit_tests/common/test_tabular_query.py b/tests/unit_tests/common/test_tabular_query.py new file mode 100644 index 000000000000..b9f3377fe23f --- /dev/null +++ b/tests/unit_tests/common/test_tabular_query.py @@ -0,0 +1,426 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +"""Unit tests for the shared name-based tabular query core.""" + +from unittest.mock import MagicMock + +import pytest + +from superset.common.tabular_query import ( + build_query_dict, + TabularQueryValidationError, + validate_names, + validate_query_names, +) +from superset.superset_typing import AdhocColumn, AdhocMetric + + +def _column(name: str, is_dttm: bool = False) -> MagicMock: + column = MagicMock() + column.column_name = name + column.is_dttm = is_dttm + return column + + +def test_build_query_dict_synthesizes_temporal_filter() -> None: + """A time_range becomes a TEMPORAL_RANGE clause on the resolved column.""" + query_dict = build_query_dict( + time_column="ds", + metrics=["count"], + dimensions=["region"], + time_range="Last 30 days", + ) + + assert query_dict["granularity"] == "ds" + assert { + "col": "ds", + "op": "TEMPORAL_RANGE", + "val": "Last 30 days", + } in query_dict["filters"] + + +def test_build_query_dict_time_range_without_column_adds_no_filter() -> None: + """Without a resolved temporal column there is nothing to filter on.""" + query_dict = build_query_dict(metrics=["count"], time_range="Last 30 days") + + assert query_dict["filters"] == [] + assert "granularity" not in query_dict + + +def test_build_query_dict_time_grain_emits_base_axis_column() -> None: + """A grain only applies via a BASE_AXIS adhoc column. + + ``SqlaTable.adhoc_column_to_sqla`` gates grain handling on + ``columnType == "BASE_AXIS"``; ``extras.time_grain_sqla`` alone is read by + the semantic-layer mapper but silently ignored for datasets. + """ + query_dict = build_query_dict( + time_column="ds", metrics=["count"], time_grain="P1D", grain_column="ds" + ) + + assert query_dict["columns"][0] == { + "label": "ds", + "sqlExpression": "ds", + "isColumnReference": True, + "columnType": "BASE_AXIS", + "timeGrain": "P1D", + } + # Still emitted for the semantic-view path. + assert query_dict["extras"] == {"time_grain_sqla": "P1D"} + + +def test_build_query_dict_grain_replaces_plain_dimension() -> None: + """Naming the temporal column as a dimension must not duplicate it.""" + query_dict = build_query_dict( + metrics=["count"], + dimensions=["ds", "gender"], + time_grain="P1M", + grain_column="ds", + ) + + assert query_dict["columns"][0]["columnType"] == "BASE_AXIS" + assert query_dict["columns"][1] == "gender" + assert "ds" not in [c for c in query_dict["columns"] if isinstance(c, str)] + + +def test_build_query_dict_grain_without_column_is_not_applied() -> None: + """No grain column means no BASE_AXIS column; the API rejects this case.""" + query_dict = build_query_dict(metrics=["count"], time_grain="P1D") + + assert query_dict["columns"] == [] + + +def test_resolve_grain_column_precedence() -> None: + from superset.common.tabular_query import ResolvedExplorable + + resolved = ResolvedExplorable( + explorable=MagicMock(), + display_name="sales", + time_column="ds", + valid_dimensions={"ds", "created", "gender"}, + valid_metrics={"count"}, + dttm_columns={"ds", "created"}, + ) + + # Explicit time_column wins. + assert resolved.resolve_grain_column("created", ["ds"]) == "created" + # Else a temporal dimension already requested. + assert resolved.resolve_grain_column(None, ["gender", "created"]) == "created" + # Else whatever time_range resolved to. + assert resolved.resolve_grain_column(None, ["gender"]) == "ds" + + +def test_resolve_grain_column_returns_none_when_no_temporal() -> None: + from superset.common.tabular_query import ResolvedExplorable + + resolved = ResolvedExplorable( + explorable=MagicMock(), + display_name="sales", + time_column=None, + valid_dimensions={"gender"}, + valid_metrics={"count"}, + dttm_columns=set(), + ) + + assert resolved.resolve_grain_column(None, ["gender"]) is None + + +def test_build_query_dict_maps_limit_offset_to_query_object_names() -> None: + """The wire uses SemanticQuery's limit/offset; QueryObject wants row_*.""" + assert build_query_dict(metrics=["count"], limit=25)["row_limit"] == 25 + assert "row_offset" not in build_query_dict(metrics=["count"]) + assert build_query_dict(metrics=["count"], offset=100)["row_offset"] == 100 + + +def test_build_query_dict_orderby_inverts_each_direction() -> None: + """QueryObject.orderby is (name, ascending); the wire sends descending.""" + query_dict = build_query_dict( + metrics=["count"], + dimensions=["region"], + order=[("count", True), ("region", False)], + ) + + assert query_dict["orderby"] == [("count", False), ("region", True)] + + +def test_build_query_dict_passes_adhoc_metrics_through() -> None: + """Ad-hoc metric dicts survive untouched; datasets accept them.""" + adhoc: AdhocMetric = { + "expressionType": "SQL", + "sqlExpression": "SUM(a)/SUM(b)", + "label": "Ratio", + } + assert build_query_dict(metrics=["count", adhoc])["metrics"] == ["count", adhoc] + + +def test_validate_query_names_reports_unknown_names() -> None: + """Unknown names are named back to the caller, per kind.""" + errors = validate_query_names( + {"revenue"}, + {"region"}, + metrics=["revenu"], + dimensions=["regionn"], + filters=[{"col": "bogus_col"}], + order_names=["bogus_order"], + ) + + joined = "; ".join(errors) + assert "Unknown metric: 'revenu'" in joined + assert "Unknown dimension: 'regionn'" in joined + assert "Unknown filter column: 'bogus_col'" in joined + assert "Unknown order_by: 'bogus_order'" in joined + + +def test_validate_query_names_accepts_valid_names() -> None: + assert ( + validate_query_names( + {"revenue"}, + {"region"}, + metrics=["revenue"], + dimensions=["region"], + filters=[{"col": "region"}], + order_names=["revenue"], + ) + == [] + ) + + +def test_validate_query_names_skips_adhoc_expressions() -> None: + """Ad-hoc metrics/columns are dicts, not names, so they bypass name checks. + + Semantic views reject them downstream in the mapper, which owns that rule. + """ + adhoc_metric: AdhocMetric = {"expressionType": "SQL", "sqlExpression": "SUM(a)"} + adhoc_column: AdhocColumn = { + "sqlExpression": "LOWER(region)", + "label": "region_lc", + } + + assert ( + validate_query_names( + set(), set(), metrics=[adhoc_metric], dimensions=[adhoc_column] + ) + == [] + ) + + +def test_validate_names_suggests_close_matches() -> None: + (error,) = validate_names(["sum__sale"], {"sum__sales"}, "metric") + assert "Did you mean: sum__sales?" in error + + +def test_validate_names_hints_when_no_metrics_defined() -> None: + (error,) = validate_names( + ["anything"], set(), "metric", empty_hint="No metrics here." + ) + assert "No metrics here." in error + + +def test_validate_names_lists_valid_when_no_close_match() -> None: + (error,) = validate_names(["zzz"], {"revenue"}, "metric", list_valid_on_miss=True) + assert "Valid metrics: revenue" in error + + +def test_resolve_time_column_rejects_non_temporal_column() -> None: + from superset.common.tabular_query import _resolve_time_column + + explorable = MagicMock() + explorable.columns = [_column("region"), _column("ds", is_dttm=True)] + + with pytest.raises(TabularQueryValidationError, match="not marked as a datetime"): + _resolve_time_column(explorable, "sales", "region", False) + + +def test_resolve_time_column_rejects_unknown_column() -> None: + from superset.common.tabular_query import _resolve_time_column + + explorable = MagicMock() + explorable.columns = [_column("ds", is_dttm=True)] + + with pytest.raises(TabularQueryValidationError, match="Unknown time_column"): + _resolve_time_column(explorable, "sales", "nope", False) + + +def test_resolve_time_column_infers_from_main_dttm_col() -> None: + """Datasets carry main_dttm_col; it wins over positional inference.""" + from superset.common.tabular_query import _resolve_time_column + + explorable = MagicMock() + explorable.columns = [_column("created", is_dttm=True), _column("ds", is_dttm=True)] + explorable.main_dttm_col = "ds" + + assert _resolve_time_column(explorable, "sales", None, True) == "ds" + + +def test_resolve_time_column_requires_one_when_time_range_given() -> None: + from superset.common.tabular_query import _resolve_time_column + + explorable = MagicMock() + explorable.columns = [_column("region")] + explorable.main_dttm_col = None + + with pytest.raises(TabularQueryValidationError, match="no temporal column"): + _resolve_time_column(explorable, "view", None, True) + + +def test_resolve_time_column_not_inferred_without_time_range() -> None: + """An unfiltered query must not acquire a temporal axis it did not ask for.""" + from superset.common.tabular_query import _resolve_time_column + + explorable = MagicMock() + explorable.columns = [_column("ds", is_dttm=True)] + explorable.main_dttm_col = "ds" + + assert _resolve_time_column(explorable, "sales", None, False) is None + + +def test_metrics_hint_names_the_callers_own_discovery_tool() -> None: + """The default hint points at get_dataset_info, which cannot resolve a + semantic view; get_table must be able to name list_metrics instead. + + The hint only appears once the valid list is truncated, i.e. above ten + metrics — which is why a single-metric fixture never exercised it. + """ + many = {f"metric_{i:02d}" for i in range(15)} + + (default,) = validate_query_names(many, set(), metrics=["zzz"]) + assert "call get_dataset_info for the full list" in default + + (overridden,) = validate_query_names( + many, + set(), + metrics=["zzz"], + metrics_full_list_hint="call list_metrics for the full list", + ) + assert "call list_metrics for the full list" in overridden + assert "get_dataset_info" not in overridden + + +def test_order_desc_is_independent_of_order() -> None: + """order_desc drives series-limit ordering and must not be inferred from + ``order``; deriving it flipped the value when ``order`` was empty.""" + for order_desc in (True, False): + assert ( + build_query_dict(metrics=["count"], order=[], order_desc=order_desc)[ + "order_desc" + ] + is order_desc + ) + assert ( + build_query_dict( + metrics=["count"], order=[("count", True)], order_desc=order_desc + )["order_desc"] + is order_desc + ) + + +def test_grain_column_is_marked_as_a_column_reference() -> None: + """Semantic views reject adhoc dimensions without this flag, so omitting it + made every semantic-view time_grain query raise.""" + query_dict = build_query_dict( + metrics=["count"], time_grain="P1D", grain_column="ds" + ) + + assert query_dict["columns"][0]["isColumnReference"] is True + + +def test_validation_error_is_a_value_error() -> None: + """The endpoint maps ValueError to 400 so the semantic-layer mapper's bare + ValueError validation failures do not escape as 500s; this subclassing is + what keeps TabularQueryValidationError covered by that handler.""" + assert issubclass(TabularQueryValidationError, ValueError) + + +def test_resolve_time_column_requires_a_choice_when_ambiguous() -> None: + from superset.common.tabular_query import _resolve_time_column + + explorable = MagicMock() + explorable.columns = [ + _column("event_time", is_dttm=True), + _column("created_at", is_dttm=True), + ] + explorable.main_dttm_col = None + + with pytest.raises(TabularQueryValidationError, match="multiple datetime"): + _resolve_time_column(explorable, "view", None, True) + + assert _resolve_time_column(explorable, "view", "created_at", True) == "created_at" + + +def test_resolve_time_column_still_infers_a_lone_candidate() -> None: + from superset.common.tabular_query import _resolve_time_column + + explorable = MagicMock() + explorable.columns = [_column("region"), _column("event_time", is_dttm=True)] + explorable.main_dttm_col = None + + assert _resolve_time_column(explorable, "view", None, True) == "event_time" + + +def test_two_sided_range_stays_a_temporal_range_filter() -> None: + (clause,) = build_query_dict( + time_column="ds", metrics=["count"], time_range="1965-01-01 : 1968-01-01" + )["filters"] + + assert clause["op"] == "TEMPORAL_RANGE" + assert clause["val"] == "1965-01-01 : 1968-01-01" + + +def test_one_sided_range_becomes_an_explicit_comparison() -> None: + """Semantic views only. ``_apply_granularity`` deletes the TEMPORAL_RANGE + filter once ``granularity`` is set, and the mapper emits nothing unless both + bounds resolve, so the range would vanish. + """ + for time_range, op, value in [ + ("1966-01-01 : ", ">=", "1966-01-01 00:00:00"), + (" : 1966-01-01", "<", "1966-01-01 00:00:00"), + ]: + (clause,) = build_query_dict( + time_column="ds", + metrics=["count"], + time_range=time_range, + rewrite_one_sided_time_range=True, + )["filters"] + + assert clause == {"col": "ds", "op": op, "val": value} + + +def test_datasets_keep_temporal_range_for_one_sided_ranges() -> None: + """``SqlaTable.get_time_filter`` takes either bound alone and is the only + path applying the dataset timezone, hour offset and grain truncation, so + rewriting would shift one-sided results relative to two-sided ones. + """ + (clause,) = build_query_dict( + time_column="ds", metrics=["count"], time_range="1966-01-01 : " + )["filters"] + + assert clause["op"] == "TEMPORAL_RANGE" + assert clause["val"] == "1966-01-01 : " + + +def test_one_sided_bound_uses_a_space_separator() -> None: + """``isoformat()`` would emit ``1966-01-01T00:00:00``, which sorts after + stored ``1966-01-01 00:00:00`` values and moves the boundary.""" + (clause,) = build_query_dict( + time_column="ds", + metrics=["count"], + time_range="1966-01-01 : ", + rewrite_one_sided_time_range=True, + )["filters"] + + assert "T" not in clause["val"] diff --git a/tests/unit_tests/datasource/test_query_api.py b/tests/unit_tests/datasource/test_query_api.py new file mode 100644 index 000000000000..a20510eda69c --- /dev/null +++ b/tests/unit_tests/datasource/test_query_api.py @@ -0,0 +1,269 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +"""Unit tests for the datasource query endpoint's schema and wiring.""" + +from typing import Any + +import pandas as pd +import pytest +from marshmallow import ValidationError + +from superset.common.chart_data import ChartDataResultFormat + + +@pytest.fixture +def schema(): + from superset.datasource.schemas import DatasourceQuerySchema + + return DatasourceQuerySchema() + + +def test_defaults_to_json_result_format(schema) -> None: + """JSON is the primary contract; Arrow is an explicit opt-in.""" + loaded = schema.load({"metrics": ["count"]}) + + assert loaded["result_format"] == ChartDataResultFormat.JSON + assert loaded["offset"] == 0 + assert loaded["order"] == [] + assert loaded["use_cache"] is True + assert loaded["force"] is False + + +def test_accepts_arrow_result_format(schema) -> None: + loaded = schema.load({"metrics": ["count"], "result_format": "arrow"}) + + assert loaded["result_format"] == ChartDataResultFormat.ARROW + + +def test_accepts_adhoc_metric_objects(schema) -> None: + """metrics is Raw because Metric is `AdhocMetric | str`.""" + adhoc = { + "expressionType": "SQL", + "sqlExpression": "SUM(a)/SUM(b)", + "label": "Ratio", + } + assert schema.load({"metrics": [adhoc]})["metrics"] == [adhoc] + + +def test_rejects_empty_request(schema) -> None: + """A query with neither metrics nor dimensions has nothing to select.""" + with pytest.raises(ValidationError, match="at least one metric or dimension"): + schema.load({}) + + +def test_time_grain_accepted_without_explicit_axis(schema) -> None: + """The schema cannot know which dimensions are temporal, so grain + resolution is validated in the API against the datasource's columns.""" + assert schema.load({"metrics": ["count"], "time_grain": "P1D"})["time_grain"] == ( + "P1D" + ) + loaded = schema.load( + {"metrics": ["count"], "dimensions": ["ds"], "time_grain": "P1M"} + ) + assert loaded["time_grain"] == "P1M" + + +def test_rejects_limit_above_cap(schema) -> None: + with pytest.raises(ValidationError): + schema.load({"metrics": ["count"], "limit": 500_000}) + + +def test_rejects_negative_offset(schema) -> None: + with pytest.raises(ValidationError): + schema.load({"metrics": ["count"], "offset": -1}) + + +def test_order_carries_per_column_direction(schema) -> None: + """Mirrors SemanticQuery's OrderTuple rather than one flag for all columns.""" + loaded = schema.load( + { + "metrics": ["count"], + "order": [{"column": "count"}, {"column": "region", "descending": False}], + } + ) + + assert loaded["order"] == [ + {"column": "count", "descending": True}, + {"column": "region", "descending": False}, + ] + + +def test_order_requires_a_column(schema) -> None: + with pytest.raises(ValidationError): + schema.load({"metrics": ["count"], "order": [{"descending": True}]}) + + +def test_rejects_unknown_filter_operator(schema) -> None: + """Filters reuse ChartDataFilterSchema, which validates against + FilterOperator.""" + with pytest.raises(ValidationError): + schema.load( + {"metrics": ["count"], "filters": [{"col": "a", "op": "NOPE", "val": 1}]} + ) + + +def test_accepts_ilike_operator(schema) -> None: + """ILIKE is a valid wire operator and now reaches semantic views too.""" + loaded = schema.load( + {"metrics": ["count"], "filters": [{"col": "a", "op": "ILIKE", "val": "%x%"}]} + ) + assert loaded["filters"][0]["op"] == "ILIKE" + + +def test_query_routes_registered(app) -> None: + rules = { + rule.rule + for rule in app.url_map.iter_rules() + if "/api/v1/datasource" in rule.rule + } + + assert "/api/v1/datasource///query" in rules + assert "/api/v1/datasource//" in rules + + +def test_both_new_routes_share_can_query(app) -> None: + """Sharing can_query keeps the metadata route off can_get, which + PUBLIC_ROLE_PERMISSIONS already grants for chart rendering.""" + from superset.datasource.api import DatasourceRestApi + + assert DatasourceRestApi.method_permission_name["query"] == "query" + assert DatasourceRestApi.method_permission_name["datasource_info"] == "query" + + +def test_can_query_is_gamma_readable(app) -> None: + """Without this, Datasource being in GAMMA_READ_ONLY_MODEL_VIEWS makes + _is_alpha_only withhold can_query from Gamma.""" + from superset.security.manager import SupersetSecurityManager + + assert "can_query" in SupersetSecurityManager.READ_ONLY_PERMISSION + assert "Datasource" in SupersetSecurityManager.GAMMA_READ_ONLY_MODEL_VIEWS + + +def test_arrow_is_not_export_gated() -> None: + """Arrow is a programmatic transport, not a human file export, so it stays + out of table_like() and its can_export_data / can_csv gate.""" + assert ChartDataResultFormat.ARROW not in ChartDataResultFormat.table_like() + + +def test_arrow_serializer_round_trips() -> None: + import pyarrow as pa + + from superset.common.query_context_processor import QueryContextProcessor + + df = pd.DataFrame({"region": ["EMEA", "APAC"], "sales": [10, 20]}) + payload = QueryContextProcessor._to_arrow_ipc(df) + + assert isinstance(payload, bytes) + restored = pa.ipc.open_stream(payload).read_all().to_pandas() + pd.testing.assert_frame_equal(restored, df) + + +def test_chart_data_schema_rejects_arrow() -> None: + """`ARROW` lives on the shared enum so `get_data` can serialize it, but + `_send_chart_response` has no Arrow branch — accepting it on chart/data + would execute the query and only then fail with "Unsupported result_format". + """ + from superset.charts.schemas import ChartDataQueryContextSchema + + field = ChartDataQueryContextSchema().fields["result_format"] + + with pytest.raises(ValidationError) as excinfo: + field.deserialize("arrow") + assert "arrow" in str(excinfo.value) + assert "/api/v1/datasource/" in str(excinfo.value) + + # Its own formats are unaffected. + for fmt in ("json", "csv", "xlsx"): + assert field.deserialize(fmt) == ChartDataResultFormat(fmt) + + +def test_rejects_cache_timeout_below_disabled_sentinel(schema) -> None: + """-1 is CACHE_DISABLED_TIMEOUT; below that is meaningless and would reach + the cache backend as an arbitrary negative timeout.""" + assert ( + schema.load({"metrics": ["count"], "cache_timeout": -1})["cache_timeout"] == -1 + ) + assert ( + schema.load({"metrics": ["count"], "cache_timeout": 300})["cache_timeout"] + == 300 + ) + + with pytest.raises(ValidationError): + schema.load({"metrics": ["count"], "cache_timeout": -2}) + + +def test_rejects_unsupported_result_formats(schema) -> None: + for fmt in ("csv", "xlsx"): + with pytest.raises(ValidationError): + schema.load({"metrics": ["count"], "result_format": fmt}) + + +def test_semantic_views_advertise_only_mapper_supported_operators() -> None: + from superset.semantic_layers.mapper import SUPPORTED_FILTER_OPERATORS + from superset.utils.core import FilterOperator + + assert SUPPORTED_FILTER_OPERATORS < {op.value for op in FilterOperator} + assert FilterOperator.TEMPORAL_RANGE.value in SUPPORTED_FILTER_OPERATORS + assert FilterOperator.CONTAINS_ANY.value not in SUPPORTED_FILTER_OPERATORS + + +def test_offset_rejected_when_engine_cannot_paginate(app) -> None: + from unittest.mock import MagicMock, patch + + from superset.datasource.api import DatasourceRestApi + + resolved = MagicMock() + resolved.explorable.database.db_engine_spec.supports_offset = False + resolved.explorable.database.db_engine_spec.engine = "elasticsearch" + payload: dict[str, Any] = { + "offset": 10, + "time_grain": None, + "time_column": None, + "dimensions": [], + } + + api = DatasourceRestApi() + with patch.object(api, "response_400", side_effect=AssertionError("rejected")) as m: + with pytest.raises(AssertionError): + api._execute_and_respond(resolved, payload) + assert "offset" in m.call_args.kwargs["message"] + + +def test_rejects_unsupported_time_grain(app) -> None: + """A grain the engine cannot express reaches get_timestamp_expr, which + raises NotImplementedError rather than a validation error.""" + from unittest.mock import MagicMock, patch + + from superset.datasource.api import DatasourceRestApi + + resolved = MagicMock() + resolved.explorable.database.db_engine_spec.supports_offset = True + resolved.explorable.get_time_grains.return_value = [{"duration": "P1D"}] + resolved.resolve_grain_column.return_value = "ds" + payload: dict[str, Any] = { + "offset": 0, + "time_grain": "P1DD", + "time_column": "ds", + "dimensions": [], + } + + api = DatasourceRestApi() + with patch.object(api, "response_400", side_effect=AssertionError) as m: + with pytest.raises(AssertionError): + api._execute_and_respond(resolved, payload) + assert "Unsupported time_grain" in m.call_args.kwargs["message"] diff --git a/tests/unit_tests/semantic_layers/mapper_test.py b/tests/unit_tests/semantic_layers/mapper_test.py index 32d6f7d0eb46..47afe4434d37 100644 --- a/tests/unit_tests/semantic_layers/mapper_test.py +++ b/tests/unit_tests/semantic_layers/mapper_test.py @@ -376,26 +376,34 @@ def test_convert_query_object_filter_in(mock_datasource: MagicMock) -> None: } -def test_convert_query_object_filter_ilike_rejected( +def test_convert_query_object_filter_ilike( mock_datasource: MagicMock, ) -> None: """ - Case-insensitive operators are rejected explicitly rather than silently - collapsed into LIKE — that collapse would let the backend's collation - decide case sensitivity, silently diverging from the filter the dashboard - author selected. + Case-insensitive operators map through to the provider, which resolves + them per its own collation rules. Providers unable to express ILIKE should + advertise that through a SemanticViewFeature rather than having the mapper + reject the operator for every provider. """ all_dimensions = { dim.name: dim for dim in mock_datasource.implementation.dimensions } - for op in (FilterOperator.ILIKE.value, FilterOperator.NOT_ILIKE.value): + for op, expected in ( + (FilterOperator.ILIKE.value, Operator.ILIKE), + (FilterOperator.NOT_ILIKE.value, Operator.NOT_ILIKE), + ): filter_: ValidatedQueryObjectFilterClause = { "op": op, "col": "category", "val": "%book%", } - with pytest.raises(ValueError, match="case-insensitive"): - _convert_query_object_filter(filter_, all_dimensions) + result = _convert_query_object_filter(filter_, all_dimensions) + assert result is not None + assert len(result) == 1 + converted = next(iter(result)) + assert converted.operator == expected + assert converted.column == all_dimensions["category"] + assert converted.value == "%book%" def test_convert_query_object_filter_is_null(mock_datasource: MagicMock) -> None: @@ -4016,3 +4024,30 @@ def test_get_filters_from_query_object_preserves_open_ended_temporal_range( value=datetime(2020, 1, 1), ), } + + +def test_mapper_accepts_grain_column_built_by_tabular_query( + mock_datasource: MagicMock, +) -> None: + """The BASE_AXIS column that ``build_query_dict`` emits for ``time_grain`` + must survive ``_normalize_column``. + + That helper rejects any adhoc dimension lacking ``isColumnReference``, so + without the flag every semantic-view query carrying a time grain raised + "Adhoc dimensions are not supported in Semantic Views." + """ + from superset.common.tabular_query import build_query_dict + + query_dict = build_query_dict( + metrics=["total_sales"], + dimensions=["order_date"], + time_grain="P1D", + grain_column="order_date", + ) + base_axis = query_dict["columns"][0] + assert base_axis["columnType"] == "BASE_AXIS" + + all_dimensions = { + dim.name: dim for dim in mock_datasource.implementation.dimensions + } + assert _normalize_column(base_axis, set(all_dimensions)) == "order_date" From 9b2bb15ececb8c5af41713901d417e03c76922e7 Mon Sep 17 00:00:00 2001 From: Rafael Benitez Date: Wed, 2 Sep 2026 12:31:17 -0400 Subject: [PATCH 02/12] fix(themes): apply system default/dark theme changes live without a page refresh (#43778) Co-authored-by: Claude Opus 4.8 (1M context) --- .../packages/superset-core/src/theme/types.ts | 6 + .../src/pages/ThemeList/ThemeList.test.tsx | 227 ++++++++++++ .../src/pages/ThemeList/index.tsx | 67 +++- .../src/theme/ThemeController.ts | 121 ++++++- superset-frontend/src/theme/ThemeProvider.tsx | 7 + .../src/theme/tests/ThemeController.test.ts | 332 ++++++++++++++++++ .../src/theme/tests/ThemeProvider.test.tsx | 15 + superset/themes/api.py | 53 +++ .../themes/test_theme_api_permissions.py | 55 +++ 9 files changed, 874 insertions(+), 9 deletions(-) diff --git a/superset-frontend/packages/superset-core/src/theme/types.ts b/superset-frontend/packages/superset-core/src/theme/types.ts index f72ca7388fac..af58581a608f 100644 --- a/superset-frontend/packages/superset-core/src/theme/types.ts +++ b/superset-frontend/packages/superset-core/src/theme/types.ts @@ -550,6 +550,12 @@ export interface ThemeContextType { canDetectOSPreference: () => boolean; createDashboardThemeProvider: (themeId: string) => Promise; getAppliedThemeId: () => number | null; + /** + * Re-reads the persisted system default/dark themes from the server and + * re-applies them live, so changes made on the Themes admin page take effect + * without a full page reload. + */ + refreshSystemThemes: () => Promise; } /** diff --git a/superset-frontend/src/pages/ThemeList/ThemeList.test.tsx b/superset-frontend/src/pages/ThemeList/ThemeList.test.tsx index 19921fefa701..08d4086e4011 100644 --- a/superset-frontend/src/pages/ThemeList/ThemeList.test.tsx +++ b/superset-frontend/src/pages/ThemeList/ThemeList.test.tsx @@ -25,6 +25,7 @@ import { import fetchMock from 'fetch-mock'; import * as hooks from 'src/views/CRUD/hooks'; import { useThemeContext } from 'src/theme/ThemeProvider'; +import { setSystemDefaultTheme } from 'src/features/themes/api'; import ThemesList from './index'; // Mock the getBootstrapData function @@ -54,6 +55,32 @@ jest.mock('src/features/themes/api', () => ({ unsetSystemDarkTheme: jest.fn(() => Promise.resolve()), })); +// Mock ThemeModal so we can trigger its save callback directly, without +// rendering the full editor. onThemeAdd wiring is what we assert on. +jest.mock('src/features/themes/ThemeModal', () => ({ + __esModule: true, + default: ({ + onThemeAdd, + show, + }: { + onThemeAdd: () => void; + show: boolean; + }) => { + const React = jest.requireActual('react'); + return show + ? React.createElement( + 'button', + { + type: 'button', + 'data-test': 'mock-modal-save', + onClick: () => onThemeAdd(), + }, + 'save', + ) + : null; + }, +})); + // Mock the CRUD hooks jest.mock('src/views/CRUD/hooks', () => ({ ...jest.requireActual('src/views/CRUD/hooks'), @@ -63,6 +90,7 @@ jest.mock('src/views/CRUD/hooks', () => ({ // Mock the useThemeContext hook const mockSetTemporaryTheme = jest.fn(); const mockGetAppliedThemeId = jest.fn(); +const mockRefreshSystemThemes = jest.fn(() => Promise.resolve()); jest.mock('src/theme/ThemeProvider', () => ({ ...jest.requireActual('src/theme/ThemeProvider'), useThemeContext: jest.fn(), @@ -149,6 +177,7 @@ beforeEach(() => { setTemporaryTheme: mockSetTemporaryTheme, hasDevOverride: jest.fn().mockReturnValue(false), getAppliedThemeId: mockGetAppliedThemeId, + refreshSystemThemes: mockRefreshSystemThemes, }); fetchMock.clearHistory().removeRoutes(); @@ -562,6 +591,7 @@ test('component loads successfully with applied theme ID set', async () => { setTemporaryTheme: mockSetTemporaryTheme, hasDevOverride: jest.fn().mockReturnValue(true), getAppliedThemeId: mockGetAppliedThemeId, + refreshSystemThemes: mockRefreshSystemThemes, }); render( @@ -594,6 +624,7 @@ test('component loads successfully and preserves applied theme state', async () setTemporaryTheme: mockSetTemporaryTheme, hasDevOverride: jest.fn().mockReturnValue(true), getAppliedThemeId: mockGetAppliedThemeId, + refreshSystemThemes: mockRefreshSystemThemes, }); render( @@ -616,3 +647,199 @@ test('component loads successfully and preserves applied theme state', async () // Verify getAppliedThemeId is called during component mount expect(mockGetAppliedThemeId).toHaveBeenCalled(); }); + +test('setting a system default theme applies it live and refreshes the list', async () => { + // NOTE: the default export is withToasts(ThemesList), so react-redux connect + // overrides the addSuccessToast/addDangerToast props with its own dispatch- + // bound versions. Assert on the controllable mocks instead of the toast props. + render( + , + { + useRedux: true, + useRouter: true, + useQueryParams: true, + useTheme: true, + }, + ); + + const setDefaultButtons = await screen.findAllByTestId('set-default-action'); + await userEvent.click(setDefaultButtons[0]); + + const confirmButton = await screen.findByRole('button', { name: 'Confirm' }); + await userEvent.click(confirmButton); + + await waitFor(() => { + expect(setSystemDefaultTheme as jest.Mock).toHaveBeenCalled(); + }); + // The live re-apply and the CRUD list refresh both run on success. + await waitFor(() => { + expect(mockRefreshSystemThemes).toHaveBeenCalled(); + }); + expect(mockRefreshData).toHaveBeenCalled(); +}); + +test('a failed system default mutation skips the live refresh', async () => { + (setSystemDefaultTheme as jest.Mock).mockRejectedValueOnce(new Error('nope')); + + render( + , + { + useRedux: true, + useRouter: true, + useQueryParams: true, + useTheme: true, + }, + ); + + const setDefaultButtons = await screen.findAllByTestId('set-default-action'); + await userEvent.click(setDefaultButtons[0]); + + const confirmButton = await screen.findByRole('button', { name: 'Confirm' }); + await userEvent.click(confirmButton); + + await waitFor(() => { + expect(setSystemDefaultTheme as jest.Mock).toHaveBeenCalled(); + }); + // A failed mutation must not attempt the live re-apply. + expect(mockRefreshSystemThemes).not.toHaveBeenCalled(); +}); + +test('editing the current system default theme re-applies it live on save', async () => { + render( + , + { + useRedux: true, + useRouter: true, + useQueryParams: true, + useTheme: true, + }, + ); + + // The first row (Light Theme) is the current system default. + const editButtons = await screen.findAllByTestId('edit-action'); + await userEvent.click(editButtons[0]); + + const save = await screen.findByTestId('mock-modal-save'); + await userEvent.click(save); + + await waitFor(() => { + expect(mockRefreshSystemThemes).toHaveBeenCalled(); + }); + expect(mockRefreshData).toHaveBeenCalled(); +}); + +test('editing a non-system theme does not re-apply live on save', async () => { + render( + , + { + useRedux: true, + useRouter: true, + useQueryParams: true, + useTheme: true, + }, + ); + + // The third row (Custom Theme) is neither system default nor system dark. + const editButtons = await screen.findAllByTestId('edit-action'); + await userEvent.click(editButtons[2]); + + const save = await screen.findByTestId('mock-modal-save'); + await userEvent.click(save); + + await waitFor(() => { + expect(mockRefreshData).toHaveBeenCalled(); + }); + expect(mockRefreshSystemThemes).not.toHaveBeenCalled(); +}); + +test('editing the current system dark theme re-applies it live on save', async () => { + render( + , + { + useRedux: true, + useRouter: true, + useQueryParams: true, + useTheme: true, + }, + ); + + // The second row (Dark Theme) is the current system dark theme. + const editButtons = await screen.findAllByTestId('edit-action'); + await userEvent.click(editButtons[1]); + + const save = await screen.findByTestId('mock-modal-save'); + await userEvent.click(save); + + await waitFor(() => { + expect(mockRefreshSystemThemes).toHaveBeenCalled(); + }); + expect(mockRefreshData).toHaveBeenCalled(); +}); + +test('a slow live re-apply does not block the confirm modal, list refresh, or toast', async () => { + // Make the live re-apply hang to simulate a slow /system request. + let resolveRefresh: () => void = () => {}; + mockRefreshSystemThemes.mockImplementationOnce( + () => + new Promise(resolve => { + resolveRefresh = resolve; + }), + ); + + render( + , + { + useRedux: true, + useRouter: true, + useQueryParams: true, + useTheme: true, + }, + ); + + const setDefaultButtons = await screen.findAllByTestId('set-default-action'); + await userEvent.click(setDefaultButtons[0]); + + const confirmButton = await screen.findByRole('button', { name: 'Confirm' }); + await userEvent.click(confirmButton); + + // The mutation ran and the list refreshed without waiting on the re-apply. + await waitFor(() => { + expect(setSystemDefaultTheme as jest.Mock).toHaveBeenCalled(); + }); + expect(mockRefreshData).toHaveBeenCalled(); + expect(mockRefreshSystemThemes).toHaveBeenCalled(); + + // The confirm dialog closes even though the re-apply is still pending + // (it would stay open if the handler awaited refreshSystemThemes). + await waitFor(() => { + expect( + screen.queryByRole('button', { name: 'Confirm' }), + ).not.toBeInTheDocument(); + }); + + resolveRefresh(); +}); diff --git a/superset-frontend/src/pages/ThemeList/index.tsx b/superset-frontend/src/pages/ThemeList/index.tsx index 7aa9990f1755..a48ef8fb9d65 100644 --- a/superset-frontend/src/pages/ThemeList/index.tsx +++ b/superset-frontend/src/pages/ThemeList/index.tsx @@ -113,8 +113,12 @@ function ThemesList({ refreshData, toggleBulkSelect, } = useListViewResource('theme', t('Themes'), addDangerToast); - const { setTemporaryTheme, hasDevOverride, getAppliedThemeId } = - useThemeContext(); + const { + setTemporaryTheme, + hasDevOverride, + getAppliedThemeId, + refreshSystemThemes, + } = useThemeContext(); const [themeModalOpen, setThemeModalOpen] = useState(false); const [currentTheme, setCurrentTheme] = useState(null); const [preparingExport, setPreparingExport] = useState(false); @@ -298,6 +302,10 @@ function ThemesList({ addSuccessToast( t('"%s" is now the system default theme', theme.theme_name), ); + // Re-apply the new system theme live in the background. Not awaited + // (and non-throwing) so a slow /system request never blocks the + // confirm modal from closing, the list refresh, or the toast. + refreshSystemThemes(); } catch (err: any) { addDangerToast( t('Failed to set system default theme: %s', err.message), @@ -306,7 +314,13 @@ function ThemesList({ }, }); }, - [showConfirm, refreshData, addSuccessToast, addDangerToast], + [ + showConfirm, + refreshData, + refreshSystemThemes, + addSuccessToast, + addDangerToast, + ], ); const handleSetSystemDark = useCallback( @@ -337,6 +351,10 @@ function ThemesList({ addSuccessToast( t('"%s" is now the system dark theme', theme.theme_name), ); + // Re-apply the new system theme live in the background. Not awaited + // (and non-throwing) so a slow /system request never blocks the + // confirm modal from closing, the list refresh, or the toast. + refreshSystemThemes(); } catch (err: any) { addDangerToast( t('Failed to set system dark theme: %s', err.message), @@ -345,7 +363,13 @@ function ThemesList({ }, }); }, - [showConfirm, refreshData, addSuccessToast, addDangerToast], + [ + showConfirm, + refreshData, + refreshSystemThemes, + addSuccessToast, + addDangerToast, + ], ); const handleUnsetSystemDefault = useCallback(() => { @@ -359,6 +383,10 @@ function ThemesList({ await unsetSystemDefaultTheme(); refreshData(); addSuccessToast(t('System default theme removed')); + // Revert to the fallback theme live in the background. Not awaited + // (and non-throwing) so a slow /system request never blocks the + // confirm modal from closing, the list refresh, or the toast. + refreshSystemThemes(); } catch (err: any) { addDangerToast( t('Failed to remove system default theme: %s', err.message), @@ -366,7 +394,13 @@ function ThemesList({ } }, }); - }, [showConfirm, refreshData, addSuccessToast, addDangerToast]); + }, [ + showConfirm, + refreshData, + refreshSystemThemes, + addSuccessToast, + addDangerToast, + ]); const handleUnsetSystemDark = useCallback(() => { showConfirm({ @@ -379,6 +413,10 @@ function ThemesList({ await unsetSystemDarkTheme(); refreshData(); addSuccessToast(t('System dark theme removed')); + // Revert to the fallback theme live in the background. Not awaited + // (and non-throwing) so a slow /system request never blocks the + // confirm modal from closing, the list refresh, or the toast. + refreshSystemThemes(); } catch (err: any) { addDangerToast( t('Failed to remove system dark theme: %s', err.message), @@ -386,7 +424,13 @@ function ThemesList({ } }, }); - }, [showConfirm, refreshData, addSuccessToast, addDangerToast]); + }, [ + showConfirm, + refreshData, + refreshSystemThemes, + addSuccessToast, + addDangerToast, + ]); const initialSort = [{ id: 'theme_name', desc: true }]; const columns = useMemo( @@ -658,7 +702,16 @@ function ThemesList({ refreshData()} + onThemeAdd={async () => { + // Refresh the list row first so it is decoupled from the live + // re-apply below (a slow /system request must not block it). + refreshData(); + // If the edited theme is the current system default/dark, re-apply it + // live so JSON edits take effect without a full page reload. + if (currentTheme?.is_system_default || currentTheme?.is_system_dark) { + await refreshSystemThemes(); + } + }} onThemeApply={handleThemeModalApply} onHide={() => setThemeModalOpen(false)} show={themeModalOpen} diff --git a/superset-frontend/src/theme/ThemeController.ts b/superset-frontend/src/theme/ThemeController.ts index a51157e92f57..3b1195f3ac9f 100644 --- a/superset-frontend/src/theme/ThemeController.ts +++ b/superset-frontend/src/theme/ThemeController.ts @@ -82,13 +82,18 @@ export class ThemeController { private darkTheme: AnyThemeConfig | null; + // The built-in/config fallback default theme captured at construction. Used + // when no system default theme is set, so a live refresh reproduces the + // constructor's default-theme fallback without a page reload. + private builtInDefaultTheme: AnyThemeConfig | null; + private systemMode: ThemeMode.DARK | ThemeMode.DEFAULT; private currentMode: ThemeMode; private onChangeCallbacks: Set<(theme: Theme) => void> = new Set(); - private mediaQuery: MediaQueryList; + private mediaQuery: MediaQueryList | undefined; private crudThemeId: string | null = null; @@ -111,6 +116,13 @@ export class ThemeController { private initialMode: ThemeMode | undefined; + // Assigns a monotonically increasing id to each refreshSystemThemes call, and + // tracks the highest id that has actually applied a slice, so out-of-order or + // superseded /system responses can be dropped ("newest applied wins"). + private refreshSeq = 0; + + private appliedRefreshSeq = 0; + constructor({ storage = new LocalStorageAdapter(), modeStorageKey = STORAGE_KEYS.THEME_MODE, @@ -133,9 +145,14 @@ export class ThemeController { bootstrapDefaultMode, }: BootstrapThemeData = this.loadBootstrapData(); + // Capture the built-in/config fallback default theme so a live refresh can + // reproduce this same fallback (see refreshSystemThemes). + this.builtInDefaultTheme = defaultTheme; + // Set themes from bootstrap data // These will be the THEME_DEFAULT and THEME_DARK from config - this.defaultTheme = bootstrapDefaultTheme || defaultTheme || null; + this.defaultTheme = + bootstrapDefaultTheme || this.builtInDefaultTheme || null; this.darkTheme = bootstrapDarkTheme; this.bootstrapDefaultMode = bootstrapDefaultMode; @@ -560,6 +577,78 @@ export class ThemeController { this.updateTheme(themeToApply); } + /** + * Re-reads the persisted system default/dark themes from the server and + * re-applies them live, so changes made on the Themes admin page take effect + * without a full page reload. The endpoint returns the same resolved theme + * slice used to bootstrap the page, so the live result matches a reload. + * + * Bails before applying whenever an explicit theme-config override is active + * (e.g. from the Embedded SDK) — checked both at entry and again after the + * fetch resolves — so it does not overwrite an externally-provided theme. + * + * Non-throwing: the server mutation has already succeeded by the time this + * runs, so a failed refresh must not surface a failure to the caller. A + * failed fetch or parse logs and leaves the current theme unchanged; if a + * fetched slice is valid-shaped but throws while applying, updateTheme's own + * recovery path handles the fallback. + */ + public async refreshSystemThemes(): Promise { + // An explicit theme-config override takes precedence over system themes. + if (this.themeConfigOverride) return; + + // Assign this refresh a monotonically increasing id so out-of-order + // responses can be resolved by "newest successfully-applied wins". + this.refreshSeq += 1; + const seq = this.refreshSeq; + + try { + const response = await SupersetClient.get({ + endpoint: '/api/v1/theme/system', + }); + // Drop this response if a newer refresh has already applied a slice (so a + // slow older request can't clobber it, and a newer request that fails to + // fetch can't discard this valid one), or if an embedded theme-config + // override took over while this request was in flight. + if (seq <= this.appliedRefreshSeq || this.themeConfigOverride) return; + + const themeConfig = response.json?.result as + | BootstrapThemeDataConfig + | undefined; + if (!themeConfig) return; + + // This response wins; record it before mutating so an older in-flight + // response can't overwrite it. + this.appliedRefreshSeq = seq; + + const { + bootstrapDefaultTheme, + bootstrapDarkTheme, + bootstrapDefaultMode, + } = this.parseThemeConfig(themeConfig); + + // Reproduce the constructor's slot assignments so live == reload. + this.defaultTheme = + bootstrapDefaultTheme || this.builtInDefaultTheme || null; + this.darkTheme = bootstrapDarkTheme; + this.bootstrapDefaultMode = bootstrapDefaultMode; + + // Dark-theme availability may have changed (set or unset); re-sync the + // prefers-color-scheme listener so SYSTEM-mode OS switching stays correct. + this.reconcileMediaQueryListener(); + + // Recompute the mode exactly as the constructor would on a reload. + this.currentMode = this.determineInitialMode(); + + // No-arg updateTheme re-resolves via getThemeForMode(currentMode) and + // notifies subscribers, repainting the app without a reload. It honors an + // active devThemeOverride and never sets themeConfigOverride. + await this.updateTheme(); + } catch (error) { + console.warn('Failed to refresh system themes:', error); + } + } + /** * Handles system theme changes with error recovery. */ @@ -684,6 +773,23 @@ export class ThemeController { } } + /** + * Re-syncs the prefers-color-scheme listener with the current dark-theme + * availability. Idempotent: always removes any existing listener before + * conditionally re-adding one, so repeated refreshes never double-register. + */ + private reconcileMediaQueryListener(): void { + if (this.mediaQuery) { + this.mediaQuery.removeEventListener( + 'change', + this.handleSystemThemeChange, + ); + this.mediaQuery = undefined; + } + if (this.shouldInitializeMediaQueryListener()) + this.initializeMediaQueryListener(); + } + /** * Loads and validates bootstrap theme data. */ @@ -692,6 +798,17 @@ export class ThemeController { common: { theme = {} as BootstrapThemeDataConfig }, } = getBootstrapData(); + return this.parseThemeConfig(theme); + } + + /** + * Parses and validates a resolved theme config slice (the shape shared by the + * page bootstrap and the /api/v1/theme/system endpoint) into the controller's + * internal theme representation. + */ + private parseThemeConfig( + theme: BootstrapThemeDataConfig, + ): BootstrapThemeData { const { default: defaultTheme, dark: darkTheme, defaultMode } = theme; const hasValidDefault: boolean = this.isNonEmptyObject(defaultTheme); diff --git a/superset-frontend/src/theme/ThemeProvider.tsx b/superset-frontend/src/theme/ThemeProvider.tsx index 707729c1d6be..4cb8a3e8c4a8 100644 --- a/superset-frontend/src/theme/ThemeProvider.tsx +++ b/superset-frontend/src/theme/ThemeProvider.tsx @@ -137,6 +137,11 @@ export function SupersetThemeProvider({ [themeController], ); + const refreshSystemThemes = useCallback( + () => themeController.refreshSystemThemes(), + [themeController], + ); + const contextValue = useMemo( () => ({ theme: currentTheme, @@ -154,6 +159,7 @@ export function SupersetThemeProvider({ canDetectOSPreference, createDashboardThemeProvider, getAppliedThemeId, + refreshSystemThemes, }), [ currentTheme, @@ -171,6 +177,7 @@ export function SupersetThemeProvider({ canDetectOSPreference, createDashboardThemeProvider, getAppliedThemeId, + refreshSystemThemes, ], ); diff --git a/superset-frontend/src/theme/tests/ThemeController.test.ts b/superset-frontend/src/theme/tests/ThemeController.test.ts index 32a174a43ecb..62abe4f0be6f 100644 --- a/superset-frontend/src/theme/tests/ThemeController.test.ts +++ b/superset-frontend/src/theme/tests/ThemeController.test.ts @@ -100,6 +100,7 @@ const createMockBootstrapData = ( const mockThemeObject = { setConfig: mockSetConfig, theme: DEFAULT_THEME, + toSerializedConfig: jest.fn(() => DEFAULT_THEME), } as unknown as Theme; // Helper to create a fresh ThemeController with common setup @@ -2210,3 +2211,334 @@ test('bootstrapDefaultMode: explicit initialMode takes precedence over bootstrap const controller = createController({ initialMode: ThemeMode.DEFAULT }); expect(controller.getCurrentMode()).toBe(ThemeMode.DEFAULT); }); + +// refreshSystemThemes tests +test('refreshSystemThemes applies a new system default live and notifies subscribers', async () => { + const callback = jest.fn(); + const controller = createController({ onChange: callback }); + callback.mockClear(); + mockSetConfig.mockClear(); + + const NEW_DEFAULT: AnyThemeConfig = { + token: { colorBgBase: '#abcdef', colorPrimary: '#123456' }, + }; + const getSpy = jest.spyOn(SupersetClient, 'get').mockResolvedValue({ + json: { + result: { + default: NEW_DEFAULT, + dark: DARK_THEME, + defaultMode: 'default', + }, + }, + } as any); + + await controller.refreshSystemThemes(); + + expect(getSpy).toHaveBeenCalledWith({ endpoint: '/api/v1/theme/system' }); + // A subscriber fired, proving the app re-rendered without a reload. + expect(callback).toHaveBeenCalled(); + // The refresh must not trip the embedded-SDK precedence flag. + expect(controller.hasThemeConfigOverride()).toBe(false); + const lastConfig = + mockSetConfig.mock.calls[mockSetConfig.mock.calls.length - 1][0]; + expect(lastConfig.token.colorBgBase).toBe('#abcdef'); + + getSpy.mockRestore(); +}); + +test('refreshSystemThemes preserves an active dev theme override', async () => { + const controller = createController(); + controller.setTemporaryTheme({ token: { colorPrimary: '#dev' } }, 42); + expect(controller.hasDevOverride()).toBe(true); + + const getSpy = jest.spyOn(SupersetClient, 'get').mockResolvedValue({ + json: { + result: { + default: DEFAULT_THEME, + dark: DARK_THEME, + defaultMode: 'default', + }, + }, + } as any); + + await controller.refreshSystemThemes(); + + expect(controller.hasDevOverride()).toBe(true); + expect(controller.hasThemeConfigOverride()).toBe(false); + + getSpy.mockRestore(); +}); + +test('refreshSystemThemes removes the OS listener when dark is unset and does not double-register', async () => { + const mockMediaQuery = { + matches: false, + addEventListener: jest.fn(), + removeEventListener: jest.fn(), + }; + mockMatchMedia.mockReturnValue(mockMediaQuery); + + // Dark present at construction → listener registered once. + const controller = createController(); + expect(mockMediaQuery.addEventListener).toHaveBeenCalledTimes(1); + + const getSpy = jest.spyOn(SupersetClient, 'get').mockResolvedValue({ + json: { + result: { default: DEFAULT_THEME, dark: {}, defaultMode: 'default' }, + }, + } as any); + + await controller.refreshSystemThemes(); + + expect(controller.canDetectOSPreference()).toBe(false); + expect(controller.canSetMode()).toBe(false); + expect(mockMediaQuery.removeEventListener).toHaveBeenCalledTimes(1); + + // A second refresh with dark still unset must not re-register the listener. + await controller.refreshSystemThemes(); + expect(mockMediaQuery.addEventListener).toHaveBeenCalledTimes(1); + + getSpy.mockRestore(); +}); + +test('refreshSystemThemes registers the OS listener once when dark is set for the first time', async () => { + mockGetBootstrapData.mockReturnValue( + createMockBootstrapData({ default: DEFAULT_THEME, dark: {} }), + ); + const mockMediaQuery = { + matches: false, + addEventListener: jest.fn(), + removeEventListener: jest.fn(), + }; + mockMatchMedia.mockReturnValue(mockMediaQuery); + + // No dark at construction → no listener registered. + const controller = createController(); + expect(mockMediaQuery.addEventListener).not.toHaveBeenCalled(); + expect(controller.canDetectOSPreference()).toBe(false); + + const getSpy = jest.spyOn(SupersetClient, 'get').mockResolvedValue({ + json: { + result: { + default: DEFAULT_THEME, + dark: DARK_THEME, + defaultMode: 'system', + }, + }, + } as any); + + await controller.refreshSystemThemes(); + + expect(controller.canDetectOSPreference()).toBe(true); + expect(mockMediaQuery.addEventListener).toHaveBeenCalledTimes(1); + + getSpy.mockRestore(); +}); + +test('refreshSystemThemes falls back to the built-in default when the server default is empty', async () => { + const BUILT_IN: AnyThemeConfig = { + token: { colorBgBase: '#builtin', colorPrimary: '#000fff' }, + }; + const controller = createController({ defaultTheme: BUILT_IN }); + mockSetConfig.mockClear(); + + const getSpy = jest.spyOn(SupersetClient, 'get').mockResolvedValue({ + json: { result: { default: {}, dark: DARK_THEME, defaultMode: 'default' } }, + } as any); + + await controller.refreshSystemThemes(); + + const lastConfig = + mockSetConfig.mock.calls[mockSetConfig.mock.calls.length - 1][0]; + expect(lastConfig.token.colorBgBase).toBe('#builtin'); + + getSpy.mockRestore(); +}); + +test('refreshSystemThemes does not throw and leaves the theme unchanged when the request fails', async () => { + const controller = createController(); + mockSetConfig.mockClear(); + const getSpy = jest + .spyOn(SupersetClient, 'get') + .mockRejectedValue(new Error('boom')); + + await expect(controller.refreshSystemThemes()).resolves.toBeUndefined(); + + expect(mockSetConfig).not.toHaveBeenCalled(); + expect(consoleSpy).toHaveBeenCalledWith( + 'Failed to refresh system themes:', + expect.any(Error), + ); + + getSpy.mockRestore(); +}); + +test('refreshSystemThemes is a no-op when the server returns no result', async () => { + const controller = createController(); + mockSetConfig.mockClear(); + const getSpy = jest + .spyOn(SupersetClient, 'get') + .mockResolvedValue({ json: {} } as any); + + await controller.refreshSystemThemes(); + + expect(mockSetConfig).not.toHaveBeenCalled(); + + getSpy.mockRestore(); +}); + +test('refreshSystemThemes is skipped when an embedded theme-config override is active', async () => { + const controller = createController(); + controller.setThemeConfig({ + theme_default: DEFAULT_THEME, + theme_dark: DARK_THEME, + }); + expect(controller.hasThemeConfigOverride()).toBe(true); + + mockSetConfig.mockClear(); + const getSpy = jest.spyOn(SupersetClient, 'get').mockResolvedValue({ + json: { result: { default: DEFAULT_THEME, dark: DARK_THEME } }, + } as any); + + await controller.refreshSystemThemes(); + + // An SDK-provided theme must not be clobbered: no fetch, no re-apply. + expect(getSpy).not.toHaveBeenCalled(); + expect(mockSetConfig).not.toHaveBeenCalled(); + + getSpy.mockRestore(); +}); + +test('refreshSystemThemes ignores a stale out-of-order response', async () => { + const controller = createController(); + mockSetConfig.mockClear(); + + const NEW_DEFAULT: AnyThemeConfig = { + token: { colorBgBase: '#new111', colorPrimary: '#111' }, + }; + const STALE_DEFAULT: AnyThemeConfig = { + token: { colorBgBase: '#old999', colorPrimary: '#999' }, + }; + + let resolveStale: (value: unknown) => void = () => {}; + const stalePending = new Promise(resolve => { + resolveStale = resolve; + }); + + const getSpy = jest + .spyOn(SupersetClient, 'get') + // The first (older) request stays pending until we resolve it last. + .mockImplementationOnce(() => stalePending as any) + // The second (newer) request resolves immediately and should win. + .mockResolvedValueOnce({ + json: { + result: { + default: NEW_DEFAULT, + dark: DARK_THEME, + defaultMode: 'default', + }, + }, + } as any); + + const older = controller.refreshSystemThemes(); // seq 1, pending + const newer = controller.refreshSystemThemes(); // seq 2, applies NEW_DEFAULT + await newer; + + // Deliver the stale response last; it must be dropped, not applied. + resolveStale({ + json: { + result: { + default: STALE_DEFAULT, + dark: DARK_THEME, + defaultMode: 'default', + }, + }, + }); + await older; + + const lastConfig = + mockSetConfig.mock.calls[mockSetConfig.mock.calls.length - 1][0]; + expect(lastConfig.token.colorBgBase).toBe('#new111'); + + getSpy.mockRestore(); +}); + +test('refreshSystemThemes applies a valid earlier response when a newer refresh fails', async () => { + const controller = createController(); + mockSetConfig.mockClear(); + + const EARLIER_DEFAULT: AnyThemeConfig = { + token: { colorBgBase: '#aaa111', colorPrimary: '#a1' }, + }; + + let resolveEarlier: (value: unknown) => void = () => {}; + const earlierPending = new Promise(resolve => { + resolveEarlier = resolve; + }); + + const getSpy = jest + .spyOn(SupersetClient, 'get') + // Earlier request (seq 1) stays pending. + .mockImplementationOnce(() => earlierPending as any) + // Newer request (seq 2) fails outright. + .mockRejectedValueOnce(new Error('newer refresh failed')); + + const earlier = controller.refreshSystemThemes(); // seq 1, pending + const newer = controller.refreshSystemThemes(); // seq 2, rejects, applies nothing + await newer; + + // The earlier request now resolves with a valid slice. Because the newer one + // never applied, the earlier (still-valid) response must not be discarded. + resolveEarlier({ + json: { + result: { + default: EARLIER_DEFAULT, + dark: DARK_THEME, + defaultMode: 'default', + }, + }, + }); + await earlier; + + const lastConfig = + mockSetConfig.mock.calls[mockSetConfig.mock.calls.length - 1][0]; + expect(lastConfig.token.colorBgBase).toBe('#aaa111'); + + getSpy.mockRestore(); +}); + +test('refreshSystemThemes does not clobber an override applied while its fetch was in flight', async () => { + const controller = createController(); + + let resolveGet: (value: unknown) => void = () => {}; + const pending = new Promise(resolve => { + resolveGet = resolve; + }); + const getSpy = jest + .spyOn(SupersetClient, 'get') + .mockImplementationOnce(() => pending as any); + + // Override is inactive at entry, so the refresh proceeds and awaits the GET. + const refresh = controller.refreshSystemThemes(); + + // An embedded theme-config override is applied while the request is in flight. + controller.setThemeConfig({ + theme_default: DEFAULT_THEME, + theme_dark: DARK_THEME, + }); + expect(controller.hasThemeConfigOverride()).toBe(true); + mockSetConfig.mockClear(); + + // The in-flight refresh resolves; the post-await guard must drop it so the + // SDK-provided theme is preserved. + resolveGet({ + json: { + result: { default: { token: { colorBgBase: '#stale' } }, dark: {} }, + }, + }); + await refresh; + + expect(mockSetConfig).not.toHaveBeenCalled(); + expect(controller.hasThemeConfigOverride()).toBe(true); + + getSpy.mockRestore(); +}); diff --git a/superset-frontend/src/theme/tests/ThemeProvider.test.tsx b/superset-frontend/src/theme/tests/ThemeProvider.test.tsx index 07b3e84fcda3..ed434a000f72 100644 --- a/superset-frontend/src/theme/tests/ThemeProvider.test.tsx +++ b/superset-frontend/src/theme/tests/ThemeProvider.test.tsx @@ -92,6 +92,7 @@ describe('SupersetThemeProvider', () => { canDetectOSPreference: jest.fn().mockReturnValue(true), createDashboardThemeProvider: jest.fn(), getAppliedThemeId: jest.fn().mockReturnValue(null), + refreshSystemThemes: jest.fn().mockResolvedValue(undefined), destroy: jest.fn(), } as unknown as jest.Mocked; @@ -133,6 +134,20 @@ describe('SupersetThemeProvider', () => { expect(result.current.themeMode).toBe(ThemeMode.DEFAULT); }); + test('exposes refreshSystemThemes and delegates to the controller', async () => { + const wrapper = createWrapper(mockThemeController); + + const { result } = renderHook((): ThemeContextType => useThemeContext(), { + wrapper, + }); + + await act(async () => { + await result.current.refreshSystemThemes(); + }); + + expect(mockThemeController.refreshSystemThemes).toHaveBeenCalledTimes(1); + }); + test('should register onChange listener on mount', () => { const wrapper = createWrapper(mockThemeController); diff --git a/superset/themes/api.py b/superset/themes/api.py index c02efadece4e..e6fd370f2ee9 100644 --- a/superset/themes/api.py +++ b/superset/themes/api.py @@ -79,6 +79,7 @@ class ThemeRestApi(BaseSupersetModelRestApi): "set_system_dark", "unset_system_default", "unset_system_dark", + "system", } class_permission_name = "Theme" method_permission_name = { @@ -87,6 +88,7 @@ class ThemeRestApi(BaseSupersetModelRestApi): "set_system_dark": "write", "unset_system_default": "write", "unset_system_dark": "write", + "system": "read", } resource_name = "theme" @@ -782,3 +784,54 @@ def unset_system_dark(self) -> Response: return self.response(200, result="success") except Exception as ex: return self.response_422(message=str(ex)) + + @expose("/system", methods=("GET",)) + @protect() + @safe + @statsd_metrics + @event_logger.log_this_with_context( + action=lambda self, *args, **kwargs: f"{self.__class__.__name__}.system", + log_to_statsd=False, + ) + def system(self) -> Response: + """Return the resolved system theme slice used to bootstrap the page. + --- + get: + summary: Get the resolved system default and dark themes + description: >- + Returns the same processed theme payload embedded in the page + bootstrap: the resolved system default and dark themes, the default + mode, and the UI theme administration flag. The client uses this to + apply system theme changes live without a full page reload, keeping + the result identical to what a reload would render. + responses: + 200: + description: Resolved system theme slice + content: + application/json: + schema: + type: object + properties: + result: + type: object + properties: + default: + type: object + dark: + type: object + defaultMode: + type: string + enableUiThemeAdministration: + type: boolean + 401: + $ref: '#/components/responses/401' + 403: + $ref: '#/components/responses/403' + 500: + $ref: '#/components/responses/500' + """ + # Local import to avoid a circular import between superset.views.base + # and this module (mirrors the security_manager import pattern above). + from superset.views.base import get_theme_bootstrap_data + + return self.response(200, result=get_theme_bootstrap_data()["theme"]) diff --git a/tests/integration_tests/themes/test_theme_api_permissions.py b/tests/integration_tests/themes/test_theme_api_permissions.py index 1ac6b2d2e20c..2aa803a28729 100644 --- a/tests/integration_tests/themes/test_theme_api_permissions.py +++ b/tests/integration_tests/themes/test_theme_api_permissions.py @@ -284,3 +284,58 @@ def test_gamma_user_can_read_themes(self): # Note: Gamma users' ability to create/update/delete themes # depends on the specific permissions configuration + + def test_admin_can_get_system_theme_slice(self): + """Admin can read the resolved system theme slice used for bootstrap.""" + self.login(ADMIN_USERNAME) + + response = self.client.get("/api/v1/theme/system") + + assert response.status_code == 200 + result = response.get_json()["result"] + # Mirrors the page bootstrap theme payload shape. + assert "default" in result + assert "dark" in result + assert "defaultMode" in result + assert "enableUiThemeAdministration" in result + + def test_gamma_can_get_system_theme_slice(self): + """Reading the system theme slice requires only theme read access, so a + Gamma user (read-only) can fetch it, mirroring the list/show endpoints. + The slice is already sent to every user in the page bootstrap, so this + exposes nothing new.""" + self.login(GAMMA_USERNAME) + + response = self.client.get("/api/v1/theme/system") + + assert response.status_code == 200 + + @with_config({"ENABLE_UI_THEME_ADMINISTRATION": True}) + def test_system_theme_slice_reflects_a_freshly_set_default(self): + """A subsequent /system read reflects a newly set system default, + proving it reads current DB state rather than a cached payload.""" + self.login(ADMIN_USERNAME) + + # The enabled administration flag is surfaced in the slice. + before = self.client.get("/api/v1/theme/system").get_json()["result"] + assert before["enableUiThemeAdministration"] is True + + # Persist a DB-backed system default theme. + set_response = self.client.put( + f"/api/v1/theme/{self.regular_theme.id}/set_system_default" + ) + assert set_response.status_code == 200 + + # The subsequent read resolves the newly persisted theme. + after = self.client.get("/api/v1/theme/system").get_json()["result"] + assert after["enableUiThemeAdministration"] is True + assert isinstance(after["default"], dict) + assert after["default"] # non-empty: the DB theme is now resolved + + def test_anonymous_cannot_get_system_theme_slice(self): + """An unauthenticated request to /system is rejected with 401.""" + self.logout() + + response = self.client.get("/api/v1/theme/system") + + assert response.status_code == 401 From 0c7a47ef2319ece09c21c603247ddc510b4fe5b6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 2 Sep 2026 10:06:11 -0700 Subject: [PATCH 03/12] chore(deps): bump github/codeql-action/init from 4.37.8 to 4.37.9 (#43790) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql-analysis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 9fa4a628faf0..d543833b9df4 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -67,7 +67,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@db488ddef3bf6cb639b32c2e9a7c0a7ea8271d28 # v4.37.8 + uses: github/codeql-action/init@cdf488f595d80d6e07e03d4674febd5ab45fa938 # v4.37.9 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. From 7321d4aff6fe651ade13c3a9a275959ec67c4674 Mon Sep 17 00:00:00 2001 From: MsfPablo <129399053+MsfPablo@users.noreply.github.com> Date: Wed, 2 Sep 2026 19:06:41 +0200 Subject: [PATCH 04/12] chore: fix typos in comments and docstrings (#43785) --- superset/config.py | 4 ++-- superset/databases/filters.py | 2 +- superset/databases/schemas.py | 2 +- superset/datasets/api.py | 2 +- superset/models/core.py | 2 +- superset/sql_lab.py | 2 +- superset/utils/oauth2.py | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/superset/config.py b/superset/config.py index 114ccfcd0bb3..8e760d3cf063 100644 --- a/superset/config.py +++ b/superset/config.py @@ -94,7 +94,7 @@ SUPERSET_LOG_VIEW = True -# This config is used to enable/disable the folowing security menu items: +# This config is used to enable/disable the following security menu items: # List Users, List Roles, List Groups SUPERSET_SECURITY_VIEW_MENU = True @@ -2706,7 +2706,7 @@ def EMAIL_HEADER_MUTATOR( # pylint: disable=invalid-name,unused-argument # noq # }, } -# OAuth2 state is encoded in a JWT using the alogorithm below. +# OAuth2 state is encoded in a JWT using the algorithm below. DATABASE_OAUTH2_JWT_ALGORITHM = "HS256" # By default the redirect URI points to /api/v1/database/oauth2/ and doesn't have to be diff --git a/superset/databases/filters.py b/superset/databases/filters.py index 321eb621005e..8afc3acbe28c 100644 --- a/superset/databases/filters.py +++ b/superset/databases/filters.py @@ -45,7 +45,7 @@ def apply(self, query: Query, value: Any) -> Query: """ Dynamic Filters need to be applied to the Query before we filter databases with anything else. This way you can show/hide databases using - Feature Flags for example in conjuction with the regular role filtering. + Feature Flags for example in conjunction with the regular role filtering. If not, if an user has access to all Databases it would skip this dynamic filtering. """ diff --git a/superset/databases/schemas.py b/superset/databases/schemas.py index 4cb6f3b40baf..3d678921086f 100644 --- a/superset/databases/schemas.py +++ b/superset/databases/schemas.py @@ -1586,7 +1586,7 @@ class QualifiedTableSchema(Schema): """ Schema for a qualified table reference. - Catalog and schema can be ommited, to fallback to default values. Table name must be + Catalog and schema can be omitted, to fallback to default values. Table name must be present. """ diff --git a/superset/datasets/api.py b/superset/datasets/api.py index e65cc4a83d85..21607bf3e39a 100644 --- a/superset/datasets/api.py +++ b/superset/datasets/api.py @@ -1740,7 +1740,7 @@ def get(self, id_or_uuid: str, **kwargs: Any) -> Response: response["id"] = table.id response[API_RESULT_RES_KEY] = show_model_schema.dump(table, many=False) - # remove folders from resposne if `DATASET_FOLDERS` is disabled, so that it's + # remove folders from response if `DATASET_FOLDERS` is disabled, so that it's # possible to inspect if the feature is supported or not if ( not is_feature_enabled("DATASET_FOLDERS") diff --git a/superset/models/core.py b/superset/models/core.py index a941fd52acd3..58d46f996920 100755 --- a/superset/models/core.py +++ b/superset/models/core.py @@ -1038,7 +1038,7 @@ def compile_sqla_query( if engine.dialect.identifier_preparer._double_percents: # noqa sql = sql.replace("%%", "%") - # for nwo we only optimize queries on virtual datasources, since the only + # for now we only optimize queries on virtual datasources, since the only # optimization available is predicate pushdown if is_feature_enabled("OPTIMIZE_SQL") and is_virtual: script = SQLScript(sql, self.db_engine_spec.engine).optimize() diff --git a/superset/sql_lab.py b/superset/sql_lab.py index 251e1309bf08..4127c863cc3c 100644 --- a/superset/sql_lab.py +++ b/superset/sql_lab.py @@ -726,7 +726,7 @@ def cancel_query(query: Query) -> bool: """ Cancel a running query. - Note some engines implicitly handle the cancelation of a query and thus no explicit + Note some engines implicitly handle the cancellation of a query and thus no explicit action is required. :param query: Query to cancel diff --git a/superset/utils/oauth2.py b/superset/utils/oauth2.py index c173e5a579ce..071f54fd3714 100644 --- a/superset/utils/oauth2.py +++ b/superset/utils/oauth2.py @@ -102,7 +102,7 @@ def get_oauth2_access_token( return a fresh token and store it in the database for further requests. The function has a retry decorator, in case a dashboard with multiple charts triggers simultaneous requests for refreshing a stale token; in that case only the first - process to acquire the lock will perform the refresh, and othe process should find a + process to acquire the lock will perform the refresh, and other processes should find a valid token when they retry. """ # noqa: E501 # pylint: disable=import-outside-toplevel From 201a33f68f78c21504acd041427198f278c5331a Mon Sep 17 00:00:00 2001 From: Evan Rusackas Date: Wed, 2 Sep 2026 10:07:16 -0700 Subject: [PATCH 05/12] fix(charts): reject non-table datasource_type instead of crashing (#43500) Co-authored-by: Claude Sonnet 5 --- superset/commands/chart/create.py | 12 ++ superset/commands/chart/update.py | 34 +++- tests/integration_tests/charts/api_tests.py | 43 +++++ .../unit_tests/commands/chart/create_test.py | 154 ++++++++++++++++++ .../unit_tests/commands/chart/update_test.py | 104 +++++++++++- 5 files changed, 337 insertions(+), 10 deletions(-) create mode 100644 tests/unit_tests/commands/chart/create_test.py diff --git a/superset/commands/chart/create.py b/superset/commands/chart/create.py index a24459862677..103999a9b5d4 100644 --- a/superset/commands/chart/create.py +++ b/superset/commands/chart/create.py @@ -32,11 +32,13 @@ DashboardsForbiddenError, DashboardsNotFoundValidationError, ) +from superset.commands.exceptions import DatasourceTypeInvalidError from superset.commands.utils import get_datasource_by_id, populate_subjects from superset.daos.chart import ChartDAO from superset.daos.dashboard import DashboardDAO from superset.exceptions import SupersetSecurityException from superset.utils import json +from superset.utils.core import DatasourceType from superset.utils.decorators import on_error, transaction logger = logging.getLogger(__name__) @@ -71,6 +73,16 @@ def validate(self) -> None: # Validate/Populate datasource try: + # Slice.datasource only ever resolves the ``table`` relationship + # (see Slice.datasource in superset/models/slice.py), so a chart + # pointed at any other datasource_type would "create" + # successfully but could never actually render. Reject those + # up front instead of failing later -- either at this lookup + # (SavedQuery/Query have no ``.name`` attribute, so accessing it + # below raises an unhandled AttributeError) or silently, by + # producing a permanently broken chart. + if datasource_type != DatasourceType.TABLE: + raise DatasourceTypeInvalidError() datasource = get_datasource_by_id(datasource_id, datasource_type) self._properties["datasource_name"] = datasource.name security_manager.raise_for_access(datasource=datasource) diff --git a/superset/commands/chart/update.py b/superset/commands/chart/update.py index b7eebd5058bb..9b0f884bd089 100644 --- a/superset/commands/chart/update.py +++ b/superset/commands/chart/update.py @@ -35,6 +35,7 @@ DashboardsNotFoundValidationError, DatasourceTypeUpdateRequiredValidationError, ) +from superset.commands.exceptions import DatasourceTypeInvalidError from superset.commands.utils import ( compute_subjects, get_datasource_by_id, @@ -49,6 +50,7 @@ from superset.models.slice import Slice from superset.tags.models import ObjectType from superset.utils import json +from superset.utils.core import DatasourceType from superset.utils.decorators import on_error, transaction from superset.versioning.changes.normalization import ( register_matching_normalization_context, @@ -183,11 +185,9 @@ def validate(self) -> None: # noqa: C901 # Validate if datasource_id is provided datasource_type is required datasource_id = self._properties.get("datasource_id") - datasource_type = "" - if datasource_id is not None: - datasource_type = self._properties.get("datasource_type", "") - if not datasource_type: - exceptions.append(DatasourceTypeUpdateRequiredValidationError()) + datasource_type = self._properties.get("datasource_type", "") + if datasource_id is not None and not datasource_type: + exceptions.append(DatasourceTypeUpdateRequiredValidationError()) # Validate/populate model exists self._model = ChartDAO.find_by_id(self._model_id) @@ -221,11 +221,27 @@ def validate(self) -> None: # noqa: C901 exceptions.append(ex) # Validate/Populate datasource - if datasource_id is not None: + # An empty datasource_type was already flagged above via + # DatasourceTypeUpdateRequiredValidationError; skip this block so + # we don't clobber that message with DatasourceTypeInvalidError. + if datasource_type: try: - datasource = get_datasource_by_id(datasource_id, datasource_type) - self._properties["datasource_name"] = datasource.name - security_manager.raise_for_access(datasource=datasource) + # Slice.datasource only ever resolves the ``table`` + # relationship (see Slice.datasource in + # superset/models/slice.py), so setting datasource_type to + # anything else would "succeed" but leave the chart + # permanently unable to render -- even for a type-only + # update that leaves datasource_id untouched. Reject those + # up front instead of failing later -- either at the lookup + # below (SavedQuery/Query have no ``.name`` attribute, so + # accessing it raises an unhandled AttributeError) or + # silently. + if datasource_type != DatasourceType.TABLE: + raise DatasourceTypeInvalidError() + if datasource_id is not None: + datasource = get_datasource_by_id(datasource_id, datasource_type) + self._properties["datasource_name"] = datasource.name + security_manager.raise_for_access(datasource=datasource) except SupersetSecurityException as ex: raise ChartForbiddenError() from ex except ValidationError as ex: diff --git a/tests/integration_tests/charts/api_tests.py b/tests/integration_tests/charts/api_tests.py index fd6be78e0546..9338121c3579 100644 --- a/tests/integration_tests/charts/api_tests.py +++ b/tests/integration_tests/charts/api_tests.py @@ -35,12 +35,14 @@ from superset.models.core import Database, FavStar, FavStarClassName from superset.models.dashboard import Dashboard from superset.models.slice import Slice +from superset.models.sql_lab import SavedQuery from superset.reports.models import ReportSchedule, ReportScheduleType from superset.subjects.models import Subject from superset.subjects.types import SubjectType from superset.tags.models import ObjectType, Tag, TaggedObject, TagType from superset.utils import json from superset.utils.core import get_example_default_schema +from superset.utils.database import get_example_database from tests.integration_tests.base_api_tests import ApiEditorsTestCaseMixin from tests.integration_tests.base_tests import ( subjects_from_users, @@ -660,6 +662,47 @@ def test_create_chart_validate_datasource(self): response = json.loads(rv.data.decode("utf-8")) assert response == {"message": {"datasource_id": ["Datasource does not exist"]}} + def test_create_chart_from_saved_query_rejected_cleanly(self): + """ + Chart API: creating a chart with datasource_type="saved_query" must + fail with a clean validation error, not the unhandled 500 "Fatal + error" reported in apache/superset#29697. Slice.datasource only + ever resolves the "table" relationship, so even a chart that + "created" successfully with this datasource_type could never + actually render -- "saved_query" is a real, existing row here + (not a bad ID), reproducing the original report exactly rather + than a not-found case. + """ + self.login(ADMIN_USERNAME) + example_db = get_example_database() + saved_query = SavedQuery( + db_id=example_db.id, + label="issue-29697-repro", + schema=get_example_default_schema(), + sql="SELECT 1 AS value", + ) + db.session.add(saved_query) + db.session.commit() + saved_query_id = saved_query.id + + chart_data = { + "slice_name": "issue-29697-repro-chart", + "datasource_id": saved_query_id, + "datasource_type": "saved_query", + "viz_type": "table", + } + try: + rv = self.post_assert_metric("/api/v1/chart/", chart_data, "post") + + assert rv.status_code == 422 + response = json.loads(rv.data.decode("utf-8")) + assert response == { + "message": {"datasource_type": ["Datasource type is invalid"]} + } + finally: + db.session.delete(db.session.query(SavedQuery).get(saved_query_id)) + db.session.commit() + @pytest.mark.usefixtures("load_world_bank_dashboard_with_slices") def test_create_chart_validate_user_is_dashboard_editor(self): """ diff --git a/tests/unit_tests/commands/chart/create_test.py b/tests/unit_tests/commands/chart/create_test.py new file mode 100644 index 000000000000..3cc26b4e7a21 --- /dev/null +++ b/tests/unit_tests/commands/chart/create_test.py @@ -0,0 +1,154 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +"""Unit tests for CreateChartCommand. + +Regression coverage for apache/superset#29697: POST /api/v1/chart/ with +datasource_type="saved_query" (or "query") crashes with an unhandled +AttributeError -- reported to API clients as an opaque 500 "Fatal error" -- +because SavedQuery and Query models have no ``.name`` attribute, and because +Slice.datasource only ever resolves a ``table``-typed datasource, so even a +successfully created chart of another type could never actually render. +""" + +import pytest +from pytest_mock import MockerFixture + +from superset.commands.chart.create import CreateChartCommand +from superset.commands.chart.exceptions import ChartForbiddenError, ChartInvalidError +from superset.commands.exceptions import DatasourceTypeInvalidError +from superset.errors import ErrorLevel, SupersetError, SupersetErrorType +from superset.exceptions import SupersetSecurityException + + +def _base_mocks(mocker: MockerFixture) -> None: + mocker.patch( + "superset.commands.chart.create.DashboardDAO.find_by_ids", return_value=[] + ) + mocker.patch( + "superset.commands.chart.create.populate_subjects", + side_effect=lambda properties, exceptions: None, + ) + + +@pytest.mark.parametrize("datasource_type", ["saved_query", "query"]) +def test_create_chart_rejects_non_table_datasource_type( + mocker: MockerFixture, datasource_type: str +) -> None: + """A chart can only ever query a table-backed datasource -- Slice.datasource + only ever resolves the ``table`` relationship, so any other type would + produce a chart that "creates" successfully but can never render. + + The two types fail differently before this fix, which is exactly why + both are covered here: + - "saved_query": SavedQuery has no ``.name`` attribute, so validation + crashes with an unhandled AttributeError -- surfaced to API clients as + an opaque 500 "Fatal error" (apache/superset#29697). + - "query": Query *does* define a synthetic ``.name`` property (used for + CTAS table naming, not as a real display name), so this one doesn't + crash -- it silently "succeeds" and creates a chart with a nonsense + name and a datasource that Slice.datasource can never resolve. + + ``get_datasource_by_id`` is mocked with ``spec=`` the real model classes + so accessing ``.name`` on the mock behaves exactly like the real ORM + objects do if the new guard doesn't stop the code from getting there; + ``raise_for_access`` is mocked to a no-op so nothing downstream masks + that behavior. + """ + from superset.models.sql_lab import Query, SavedQuery + + _base_mocks(mocker) + model_cls = SavedQuery if datasource_type == "saved_query" else Query + get_datasource_by_id = mocker.patch( + "superset.commands.chart.create.get_datasource_by_id", + return_value=mocker.MagicMock(spec=model_cls), + ) + mocker.patch("superset.commands.chart.create.security_manager.raise_for_access") + + with pytest.raises(ChartInvalidError) as exc_info: + CreateChartCommand( + { + "datasource_id": 11, + "datasource_type": datasource_type, + "slice_name": "some_name", + "viz_type": "table", + } + ).validate() + + assert any( + isinstance(ex, DatasourceTypeInvalidError) for ex in exc_info.value._exceptions + ) + # The invalid type must be rejected before ever touching the datasource + # lookup, not caught incidentally by some downstream failure. + get_datasource_by_id.assert_not_called() + + +def test_create_chart_accepts_table_datasource(mocker: MockerFixture) -> None: + """The one supported datasource_type must keep working.""" + _base_mocks(mocker) + datasource = mocker.MagicMock(name="table_datasource") + datasource.name = "my_table" + mocker.patch( + "superset.commands.chart.create.get_datasource_by_id", + return_value=datasource, + ) + mocker.patch("superset.commands.chart.create.security_manager.raise_for_access") + + cmd = CreateChartCommand( + { + "datasource_id": 11, + "datasource_type": "table", + "slice_name": "some_name", + "viz_type": "table", + } + ) + cmd.validate() + + assert cmd._properties["datasource_name"] == "my_table" + + +def test_create_chart_datasource_access_denied_still_raises_forbidden( + mocker: MockerFixture, +) -> None: + """The invalid-type guard must not shadow the existing access-denied path + for a legitimately table-typed datasource the user can't access.""" + _base_mocks(mocker) + datasource = mocker.MagicMock() + datasource.name = "my_table" + mocker.patch( + "superset.commands.chart.create.get_datasource_by_id", + return_value=datasource, + ) + mocker.patch( + "superset.commands.chart.create.security_manager.raise_for_access", + side_effect=SupersetSecurityException( + SupersetError( + error_type=SupersetErrorType.DATASOURCE_SECURITY_ACCESS_ERROR, + message="No access", + level=ErrorLevel.ERROR, + ) + ), + ) + + with pytest.raises(ChartForbiddenError): + CreateChartCommand( + { + "datasource_id": 11, + "datasource_type": "table", + "slice_name": "some_name", + "viz_type": "table", + } + ).validate() diff --git a/tests/unit_tests/commands/chart/update_test.py b/tests/unit_tests/commands/chart/update_test.py index 440e98cf91fa..9626150437b6 100644 --- a/tests/unit_tests/commands/chart/update_test.py +++ b/tests/unit_tests/commands/chart/update_test.py @@ -17,8 +17,13 @@ import pytest from pytest_mock import MockerFixture -from superset.commands.chart.exceptions import ChartForbiddenError, ChartInvalidError +from superset.commands.chart.exceptions import ( + ChartForbiddenError, + ChartInvalidError, + DatasourceTypeUpdateRequiredValidationError, +) from superset.commands.chart.update import UpdateChartCommand +from superset.commands.exceptions import DatasourceTypeInvalidError from superset.errors import ErrorLevel, SupersetError, SupersetErrorType from superset.exceptions import SupersetSecurityException from superset.utils import json @@ -238,3 +243,100 @@ def test_update_chart_query_context_without_datasource_is_allowed( 1, {"query_context": query_context, "query_context_generation": True}, ).validate() + + +@pytest.mark.parametrize("datasource_type", ["saved_query", "query"]) +def test_update_chart_rejects_repointing_to_non_table_datasource( + mocker: MockerFixture, datasource_type: str +) -> None: + """Repointing a chart's datasource_id must be rejected the same way + CreateChartCommand rejects it (apache/superset#29697): Slice.datasource + only ever resolves the ``table`` relationship, so repointing at a + saved_query or query datasource would "succeed" but leave the chart + permanently unable to render -- or, for saved_query specifically, crash + on SavedQuery's missing ``.name`` attribute before that point is even + reached. This is a regular (non-query-context) update, so it goes + through editorship + compute_subjects, unlike the query-context-only + tests above.""" + find_by_id = mocker.patch("superset.commands.chart.update.ChartDAO.find_by_id") + find_by_id.return_value = mocker.MagicMock(id=1, tags=[], dashboards=[]) + mocker.patch("superset.commands.chart.update.security_manager.raise_for_editorship") + mocker.patch( + "superset.commands.chart.update.compute_subjects", + side_effect=lambda model, properties, exceptions: None, + ) + get_datasource_by_id = mocker.patch( + "superset.commands.chart.update.get_datasource_by_id" + ) + + with pytest.raises(ChartInvalidError) as exc_info: + UpdateChartCommand( + 1, {"datasource_id": 11, "datasource_type": datasource_type} + ).validate() + + assert any( + isinstance(ex, DatasourceTypeInvalidError) for ex in exc_info.value._exceptions + ) + get_datasource_by_id.assert_not_called() + + +def test_update_chart_missing_datasource_type_keeps_required_error( + mocker: MockerFixture, +) -> None: + """When datasource_id is given without datasource_type, the response + must keep reporting DatasourceTypeUpdateRequiredValidationError + ("Datasource type is required") rather than having it overwritten by + DatasourceTypeInvalidError ("Datasource type is invalid") -- both + exceptions key their message under ``datasource_type``, and + normalized_messages() only keeps the last one written for a given key.""" + find_by_id = mocker.patch("superset.commands.chart.update.ChartDAO.find_by_id") + find_by_id.return_value = mocker.MagicMock(id=1, tags=[], dashboards=[]) + mocker.patch("superset.commands.chart.update.security_manager.raise_for_editorship") + mocker.patch( + "superset.commands.chart.update.compute_subjects", + side_effect=lambda model, properties, exceptions: None, + ) + get_datasource_by_id = mocker.patch( + "superset.commands.chart.update.get_datasource_by_id" + ) + + with pytest.raises(ChartInvalidError) as exc_info: + UpdateChartCommand(1, {"datasource_id": 11}).validate() + + assert any( + isinstance(ex, DatasourceTypeUpdateRequiredValidationError) + for ex in exc_info.value._exceptions + ) + assert not any( + isinstance(ex, DatasourceTypeInvalidError) for ex in exc_info.value._exceptions + ) + get_datasource_by_id.assert_not_called() + + +@pytest.mark.parametrize("datasource_type", ["saved_query", "query"]) +def test_update_chart_rejects_type_only_non_table_datasource( + mocker: MockerFixture, datasource_type: str +) -> None: + """A type-only update (datasource_type given without datasource_id) + must be rejected the same way a repointing update is: leaving + datasource_id untouched while flipping datasource_type away from + ``table`` would still break Slice.datasource, since its relationship + only ever resolves the ``table`` type.""" + find_by_id = mocker.patch("superset.commands.chart.update.ChartDAO.find_by_id") + find_by_id.return_value = mocker.MagicMock(id=1, tags=[], dashboards=[]) + mocker.patch("superset.commands.chart.update.security_manager.raise_for_editorship") + mocker.patch( + "superset.commands.chart.update.compute_subjects", + side_effect=lambda model, properties, exceptions: None, + ) + get_datasource_by_id = mocker.patch( + "superset.commands.chart.update.get_datasource_by_id" + ) + + with pytest.raises(ChartInvalidError) as exc_info: + UpdateChartCommand(1, {"datasource_type": datasource_type}).validate() + + assert any( + isinstance(ex, DatasourceTypeInvalidError) for ex in exc_info.value._exceptions + ) + get_datasource_by_id.assert_not_called() From 316f6ad971a92c15ff8cf6184083a7a4540556d3 Mon Sep 17 00:00:00 2001 From: K HARSHAVARDHAN Date: Wed, 2 Sep 2026 22:39:42 +0530 Subject: [PATCH 06/12] chore(lint): scope in-repo eslint plugins under @superset-ui (#43054) --- scripts/check-type.js | 6 ++-- .../eslint-plugin-i18n-strings/package.json | 2 +- .../eslint-plugin-icons/package.json | 2 +- .../eslint-plugin-theme-colors/package.json | 2 +- superset-frontend/eslint.config.minimal.js | 6 ++-- superset-frontend/package-lock.json | 33 ++++++++++--------- superset-frontend/package.json | 6 ++-- 7 files changed, 30 insertions(+), 27 deletions(-) diff --git a/scripts/check-type.js b/scripts/check-type.js index 609b0cb391d6..966e483078b9 100755 --- a/scripts/check-type.js +++ b/scripts/check-type.js @@ -289,11 +289,11 @@ function extractArgs(args, regexes) { * For example: `superset-frontend/foo/bar.ts` -> `foo/bar.ts` * * @param {string[]} args - * @param {string} package + * @param {string} packageName * @returns {string[]} */ -function removePackageSegment(args, package) { - const packageSegment = package.concat(sep); +function removePackageSegment(args, packageName) { + const packageSegment = packageName.concat(sep); return args.map((arg) => { const normalizedPath = normalize(arg); diff --git a/superset-frontend/eslint-rules/eslint-plugin-i18n-strings/package.json b/superset-frontend/eslint-rules/eslint-plugin-i18n-strings/package.json index 3f390c0c858f..4c532c271750 100644 --- a/superset-frontend/eslint-rules/eslint-plugin-i18n-strings/package.json +++ b/superset-frontend/eslint-rules/eslint-plugin-i18n-strings/package.json @@ -1,5 +1,5 @@ { - "name": "eslint-plugin-i18n-strings", + "name": "@superset-ui/eslint-plugin-i18n-strings", "version": "1.0.0", "description": "Warns about translation variables", "keywords": [], diff --git a/superset-frontend/eslint-rules/eslint-plugin-icons/package.json b/superset-frontend/eslint-rules/eslint-plugin-icons/package.json index a4d3a8180246..fced5fa7e654 100644 --- a/superset-frontend/eslint-rules/eslint-plugin-icons/package.json +++ b/superset-frontend/eslint-rules/eslint-plugin-icons/package.json @@ -1,5 +1,5 @@ { - "name": "eslint-plugin-icons", + "name": "@superset-ui/eslint-plugin-icons", "version": "1.0.0", "description": "Warns about direct usage of Ant Design icons", "keywords": [], diff --git a/superset-frontend/eslint-rules/eslint-plugin-theme-colors/package.json b/superset-frontend/eslint-rules/eslint-plugin-theme-colors/package.json index 650ddff1f2f2..f42959718b25 100644 --- a/superset-frontend/eslint-rules/eslint-plugin-theme-colors/package.json +++ b/superset-frontend/eslint-rules/eslint-plugin-theme-colors/package.json @@ -1,5 +1,5 @@ { - "name": "eslint-plugin-theme-colors", + "name": "@superset-ui/eslint-plugin-theme-colors", "version": "1.0.0", "description": "Warns about rgb(a)/hex/literal colors", "keywords": [], diff --git a/superset-frontend/eslint.config.minimal.js b/superset-frontend/eslint.config.minimal.js index 7eb2d3b7273f..f183d7dae702 100644 --- a/superset-frontend/eslint.config.minimal.js +++ b/superset-frontend/eslint.config.minimal.js @@ -37,9 +37,9 @@ require('tsx/cjs'); const tsParser = require('@typescript-eslint/parser'); -const themeColorsPlugin = require('eslint-plugin-theme-colors'); -const iconsPlugin = require('eslint-plugin-icons'); -const i18nStringsPlugin = require('eslint-plugin-i18n-strings'); +const themeColorsPlugin = require('@superset-ui/eslint-plugin-theme-colors'); +const iconsPlugin = require('@superset-ui/eslint-plugin-icons'); +const i18nStringsPlugin = require('@superset-ui/eslint-plugin-i18n-strings'); module.exports = [ // Files this config applies to. Flat config has no `--ext`; globs live here. diff --git a/superset-frontend/package-lock.json b/superset-frontend/package-lock.json index 6e02bf39f7fd..2554ced01c9e 100644 --- a/superset-frontend/package-lock.json +++ b/superset-frontend/package-lock.json @@ -183,6 +183,9 @@ "@storybook/addon-links": "10.5.10", "@storybook/react-webpack5": "10.5.10", "@storybook/test-runner": "0.24.4", + "@superset-ui/eslint-plugin-i18n-strings": "file:eslint-rules/eslint-plugin-i18n-strings", + "@superset-ui/eslint-plugin-icons": "file:eslint-rules/eslint-plugin-icons", + "@superset-ui/eslint-plugin-theme-colors": "file:eslint-rules/eslint-plugin-theme-colors", "@svgr/webpack": "^8.1.0", "@swc/core": "^1.16.1", "@swc/plugin-emotion": "^15.0.0", @@ -226,8 +229,6 @@ "eslint": "^10.9.0", "eslint-import-resolver-alias": "^1.1.2", "eslint-import-resolver-typescript": "^4.4.5", - "eslint-plugin-i18n-strings": "file:eslint-rules/eslint-plugin-i18n-strings", - "eslint-plugin-icons": "file:eslint-rules/eslint-plugin-icons", "eslint-plugin-import": "^2.32.0", "eslint-plugin-jest-dom": "^5.10.1", "eslint-plugin-lodash": "^8.0.0", @@ -236,7 +237,6 @@ "eslint-plugin-react-you-might-not-need-an-effect": "^1.0.2", "eslint-plugin-storybook": "10.5.10", "eslint-plugin-testing-library": "^7.16.2", - "eslint-plugin-theme-colors": "file:eslint-rules/eslint-plugin-theme-colors", "fetch-mock": "^12.6.0", "fork-ts-checker-webpack-plugin": "^9.1.0", "history": "^5.3.0", @@ -296,6 +296,7 @@ } }, "eslint-rules/eslint-plugin-i18n-strings": { + "name": "@superset-ui/eslint-plugin-i18n-strings", "version": "1.0.0", "dev": true, "license": "Apache-2.0", @@ -304,6 +305,7 @@ } }, "eslint-rules/eslint-plugin-icons": { + "name": "@superset-ui/eslint-plugin-icons", "version": "1.0.0", "dev": true, "license": "Apache-2.0", @@ -312,6 +314,7 @@ } }, "eslint-rules/eslint-plugin-theme-colors": { + "name": "@superset-ui/eslint-plugin-theme-colors", "version": "1.0.0", "dev": true, "license": "Apache-2.0" @@ -11244,6 +11247,18 @@ "resolved": "packages/superset-ui-core", "link": true }, + "node_modules/@superset-ui/eslint-plugin-i18n-strings": { + "resolved": "eslint-rules/eslint-plugin-i18n-strings", + "link": true + }, + "node_modules/@superset-ui/eslint-plugin-icons": { + "resolved": "eslint-rules/eslint-plugin-icons", + "link": true + }, + "node_modules/@superset-ui/eslint-plugin-theme-colors": { + "resolved": "eslint-rules/eslint-plugin-theme-colors", + "link": true + }, "node_modules/@superset-ui/generator-superset": { "resolved": "packages/generator-superset", "link": true @@ -20010,14 +20025,6 @@ "ms": "^2.1.1" } }, - "node_modules/eslint-plugin-i18n-strings": { - "resolved": "eslint-rules/eslint-plugin-i18n-strings", - "link": true - }, - "node_modules/eslint-plugin-icons": { - "resolved": "eslint-rules/eslint-plugin-icons", - "link": true - }, "node_modules/eslint-plugin-import": { "version": "2.32.0", "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.32.0.tgz", @@ -20241,10 +20248,6 @@ "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0" } }, - "node_modules/eslint-plugin-theme-colors": { - "resolved": "eslint-rules/eslint-plugin-theme-colors", - "link": true - }, "node_modules/eslint-scope": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", diff --git a/superset-frontend/package.json b/superset-frontend/package.json index 986502daff7c..7fac1a874f2c 100644 --- a/superset-frontend/package.json +++ b/superset-frontend/package.json @@ -260,6 +260,9 @@ "@storybook/addon-links": "10.5.10", "@storybook/react-webpack5": "10.5.10", "@storybook/test-runner": "0.24.4", + "@superset-ui/eslint-plugin-i18n-strings": "file:eslint-rules/eslint-plugin-i18n-strings", + "@superset-ui/eslint-plugin-icons": "file:eslint-rules/eslint-plugin-icons", + "@superset-ui/eslint-plugin-theme-colors": "file:eslint-rules/eslint-plugin-theme-colors", "@svgr/webpack": "^8.1.0", "@swc/core": "^1.16.1", "@swc/plugin-emotion": "^15.0.0", @@ -303,8 +306,6 @@ "eslint": "^10.9.0", "eslint-import-resolver-alias": "^1.1.2", "eslint-import-resolver-typescript": "^4.4.5", - "eslint-plugin-i18n-strings": "file:eslint-rules/eslint-plugin-i18n-strings", - "eslint-plugin-icons": "file:eslint-rules/eslint-plugin-icons", "eslint-plugin-import": "^2.32.0", "eslint-plugin-jest-dom": "^5.10.1", "eslint-plugin-lodash": "^8.0.0", @@ -313,7 +314,6 @@ "eslint-plugin-react-you-might-not-need-an-effect": "^1.0.2", "eslint-plugin-storybook": "10.5.10", "eslint-plugin-testing-library": "^7.16.2", - "eslint-plugin-theme-colors": "file:eslint-rules/eslint-plugin-theme-colors", "fetch-mock": "^12.6.0", "fork-ts-checker-webpack-plugin": "^9.1.0", "history": "^5.3.0", From b7da5336d35bae2ebc1affa358db79851aa86688 Mon Sep 17 00:00:00 2001 From: Evan Rusackas Date: Wed, 2 Sep 2026 10:10:46 -0700 Subject: [PATCH 07/12] docs(mcp): document embedded guest-token authentication (#43637) Co-authored-by: Claude --- docs/admin_docs/configuration/mcp-server.mdx | 54 ++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/docs/admin_docs/configuration/mcp-server.mdx b/docs/admin_docs/configuration/mcp-server.mdx index 73daecdc3379..1bb9c0d9685e 100644 --- a/docs/admin_docs/configuration/mcp-server.mdx +++ b/docs/admin_docs/configuration/mcp-server.mdx @@ -253,6 +253,58 @@ def my_custom_auth_factory(app): MCP_AUTH_FACTORY = my_custom_auth_factory ``` +### Embedded Guest Authentication + +Superset's [embedded dashboards](/user-docs/using-superset/embedding) feature mints short-lived **guest tokens** for anonymous/embedded viewers. The MCP server can accept these same guest tokens, so an embedded guest (e.g. an in-app chatbot next to an embedded dashboard) can call MCP tools scoped to the dashboards/resources named in its token. + +This is opt-in and reuses the existing core guest-token configuration -- there is no MCP-specific guest secret or audience. + +```python +# superset_config.py +FEATURE_FLAGS = {"EMBEDDED_SUPERSET": True} # required -- guest tokens only exist when this is on +MCP_EMBEDDED_GUEST_AUTH_ENABLED = True # opt-in for the MCP transport (default False) +``` + +Present the guest token the same way as any other bearer token: + +```bash +curl -X POST http://localhost:5008/mcp \ + -H 'Content-Type: application/json' \ + -H 'Authorization: Bearer YOUR_GUEST_TOKEN' \ + -d '{"jsonrpc": "2.0", "method": "tools/list", "id": 1}' +``` + +**How it works** + +- A dedicated guest-token verifier validates the token against the same `GUEST_TOKEN_JWT_SECRET` / `GUEST_TOKEN_JWT_ALGO` / `GUEST_TOKEN_JWT_AUDIENCE` config used by embedded dashboards, replays the embedded structural checks, and enforces revocation (global version bumps and per-dashboard `guest_token_revoked_before` cutoffs). It runs *before* the JWT verifier described above, since guest tokens are signed with a different key/algorithm and would otherwise be rejected at the transport. +- A verified guest resolves to a Superset guest user as the highest-priority identity, so it's never downgraded to API-key / `MCP_DEV_USERNAME` / dev-mode resolution. Data access is scoped by the same checks (dataset allowlist, dashboard access, row-level security) that apply to embedded dashboard views. +- Guests are restricted to a default-deny allow-list, `MCP_GUEST_ALLOWED_TOOLS`, regardless of `MCP_RBAC_ENABLED`. Sensitive enumeration tools like `find_users` and `get_instance_info` are denied simply by being absent from the default list. +- Setting `MCP_AUTH_FACTORY` bypasses this whole path: a configured factory is tried first, and the default factory that wires up the guest-token verifier is never reached. If you rely on a custom auth factory (e.g. your own OIDC provider) alongside guest auth, that factory must verify guest tokens itself -- otherwise they're rejected regardless of `MCP_EMBEDDED_GUEST_AUTH_ENABLED`. + +```python +# superset_config.py +MCP_GUEST_ALLOWED_TOOLS = { + "get_dashboard_info", + "get_dashboard_layout", + "list_dashboards", + "list_charts", + "get_chart_info", + "get_chart_data", + "get_chart_preview", +} # default +``` + +**Deployment requirements** + +- The MCP server and the service that mints guest tokens (the Superset web app) must share `GUEST_TOKEN_JWT_SECRET` and `GUEST_TOKEN_JWT_AUDIENCE`. Set `GUEST_TOKEN_JWT_AUDIENCE` explicitly -- if it's unset, audience validation falls back to the URL host, which can differ between the two services and cause every guest token to fail validation. +- The `GUEST_ROLE_NAME` role (default `Public`) must exist -- a guest token is rejected if it does not. +- Don't set `MCP_DEV_USERNAME` on a deployment that also serves embedded guests. +- Restart the MCP process after toggling `EMBEDDED_SUPERSET` or `MCP_EMBEDDED_GUEST_AUTH_ENABLED` -- guest auth is wired up once at startup. + +:::warning +`GUEST_TOKEN_JWT_SECRET` guards both the web embedding and MCP guest-auth surfaces. With `MCP_EMBEDDED_GUEST_AUTH_ENABLED` on, leaving it at its insecure default isn't just a forgery risk -- the MCP server refuses to start (`MCPAuthConfigError`) until you set a real secret shared with the guest-token minting service. +::: + --- ## Connecting AI Clients @@ -523,6 +575,8 @@ All MCP settings go in `superset_config.py`. Defaults are defined in `superset/m | `MCP_JWT_DEBUG_ERRORS` | `False` | Log detailed JWT errors server-side (never exposed in HTTP responses per RFC 6750) | | `MCP_AUTH_FACTORY` | `None` | Custom auth provider factory `(flask_app) -> auth_provider`. Takes precedence over built-in JWT | | `MCP_USER_RESOLVER` | `None` | Custom function `(app, access_token) -> username` to extract a Superset username from a validated JWT token. When `None`, the default resolver checks `preferred_username`, `username`, `email`, and `sub` claims in that order. | +| `MCP_EMBEDDED_GUEST_AUTH_ENABLED` | `False` | Accept embedded [guest tokens](#embedded-guest-authentication) as Bearer auth. Also requires the `EMBEDDED_SUPERSET` feature flag. | +| `MCP_GUEST_ALLOWED_TOOLS` | see [default list](#embedded-guest-authentication) | The only tool names callable by embedded guests (default-deny), regardless of `MCP_RBAC_ENABLED`. | ### Response Size Guard From 8c2290fcf45c2ae337dbadc23967c562892be215 Mon Sep 17 00:00:00 2001 From: Evan Rusackas Date: Wed, 2 Sep 2026 10:14:35 -0700 Subject: [PATCH 08/12] docs(theming): document resultsGrid* Superset-specific tokens (#43638) Co-authored-by: Claude --- docs/admin_docs/configuration/theming.mdx | 33 +++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/docs/admin_docs/configuration/theming.mdx b/docs/admin_docs/configuration/theming.mdx index faee522163ac..d57dc2546afb 100644 --- a/docs/admin_docs/configuration/theming.mdx +++ b/docs/admin_docs/configuration/theming.mdx @@ -240,6 +240,39 @@ Font URLs are validated against a configurable allowlist. By default, fonts from This feature works with the stock Docker image - no custom build required! +## Results Grid Configuration Overrides + +Superset exposes a handful of opt-in tokens that customize the appearance of +the results grid in SQL Lab. These tokens have no effect unless explicitly +set, since the results grid otherwise falls back to its built-in defaults. + +```python +THEME_DEFAULT = { + "token": { + "colorPrimary": "#2893B3", + # ... other Ant Design tokens + + # Results grid overrides + "resultsGridRowHeight": 32, + "resultsGridHeaderFontSize": 13, + "resultsGridHeaderFontWeight": 600, + "resultsGridBorderRadius": 4, + "resultsGridNoStriping": True, + } +} +``` + +| Token | Type | Description | +| --- | --- | --- | +| `resultsGridRowHeight` | `number` | Row and header height, in pixels. | +| `resultsGridHeaderFontSize` | `number` | Header cell font size, in pixels. | +| `resultsGridHeaderFontWeight` | `number` | Header cell font weight. | +| `resultsGridBorderRadius` | `number` | Border radius applied to the grid and its wrapper, in pixels. | +| `resultsGridNoStriping` | `boolean` | When `true`, disables alternating row background striping. | + +These tokens can also be set through the theme CRUD interface's JSON editor, +alongside any other Superset-specific tokens. + ## ECharts Configuration Overrides :::note From 46c8c67a400f57031e3ec61298279470971071ce Mon Sep 17 00:00:00 2001 From: Evan Rusackas Date: Wed, 2 Sep 2026 10:16:59 -0700 Subject: [PATCH 09/12] fix(semantic_layers): mask write-only config fields, gate flag-off endpoints (#43474) Co-authored-by: Claude Opus 4.8 --- superset/commands/semantic_layer/update.py | 44 +++ superset/semantic_layers/api.py | 54 +++- .../commands/semantic_layer/update_test.py | 110 ++++++++ tests/unit_tests/semantic_layers/api_test.py | 251 +++++++++++++++++- 4 files changed, 457 insertions(+), 2 deletions(-) diff --git a/superset/commands/semantic_layer/update.py b/superset/commands/semantic_layer/update.py index a4ce66f077c6..f01072d41cee 100644 --- a/superset/commands/semantic_layer/update.py +++ b/superset/commands/semantic_layer/update.py @@ -34,6 +34,7 @@ SemanticViewUpdateFailedError, ) from superset.commands.utils import current_user_can_modify_object +from superset.constants import PASSWORD_MASK from superset.daos.semantic_layer import SemanticLayerDAO, SemanticViewDAO from superset.semantic_layers.models import SemanticLayer, SemanticView from superset.semantic_layers.registry import registry @@ -43,6 +44,43 @@ logger = logging.getLogger(__name__) +def _unmask_configuration( + existing_raw_configuration: str | None, + new_configuration: dict[str, Any], +) -> dict[str, Any]: + """ + Replace ``PASSWORD_MASK`` sentinels in an incoming update payload with + the value already stored. + + The GET/list endpoints mask write-only configuration values (see + ``superset.semantic_layers.api._mask_configuration``), and fail closed by + masking every truthy value when the connector's schema can't be + determined. A client that round-trips that response back on an update + (e.g. a name-only edit) would otherwise overwrite the real stored + values -- secret or not -- with the literal mask string. Restore any key + whose incoming value is exactly the mask sentinel from the stored + configuration regardless of whether the schema currently marks it + write-only, since a client only ever sends the sentinel back for a value + it previously received masked (including a value masked by the + fail-closed fallback). + """ + try: + existing_configuration = ( + json.loads(existing_raw_configuration) if existing_raw_configuration else {} + ) + except (TypeError, ValueError): + existing_configuration = {} + + return { + key: ( + existing_configuration[key] + if value == PASSWORD_MASK and key in existing_configuration + else value + ) + for key, value in new_configuration.items() + } + + class UpdateSemanticViewCommand(BaseCommand): def __init__(self, model_id: int, data: dict[str, Any]): self._model_id = model_id @@ -121,6 +159,12 @@ def validate(self) -> None: if name and not SemanticLayerDAO.validate_update_uniqueness(self._uuid, name): raise SemanticLayerInvalidError(f"Name already exists: {name}") + if isinstance(self._properties.get("configuration"), dict): + self._properties["configuration"] = _unmask_configuration( + self._model.configuration, + self._properties["configuration"], + ) + if configuration := self._properties.get("configuration"): sl_type = self._model.type cls = registry[sl_type] diff --git a/superset/semantic_layers/api.py b/superset/semantic_layers/api.py index 07f7ef51be5b..c597492efd53 100644 --- a/superset/semantic_layers/api.py +++ b/superset/semantic_layers/api.py @@ -56,7 +56,7 @@ UpdateSemanticLayerCommand, UpdateSemanticViewCommand, ) -from superset.constants import MODEL_API_RW_METHOD_PERMISSION_MAP +from superset.constants import MODEL_API_RW_METHOD_PERMISSION_MAP, PASSWORD_MASK from superset.daos.semantic_layer import SemanticLayerDAO from superset.datasets.schemas import get_delete_ids_schema from superset.exceptions import SupersetSecurityException @@ -81,10 +81,53 @@ logger = logging.getLogger(__name__) +def _mask_configuration(layer: SemanticLayer, config: dict[str, Any]) -> dict[str, Any]: + """ + Redact configuration values the connector's schema marks as write-only. + + A connector publishes its configuration shape via ``get_configuration_schema``; + a property with ``"writeOnly": true`` (the standard JSON Schema way of + marking a field that's set but never echoed back, e.g. a password or API + key) is replaced with ``PASSWORD_MASK`` here rather than returned in the + clear. + """ + schema: dict[str, Any] | None = None + if cls := registry.get(layer.type): + try: + schema = cls.get_configuration_schema() + except Exception: # pylint: disable=broad-except + schema = None + + if schema is None: + # Either the type isn't registered or its schema couldn't load, so we + # can't tell which fields are secret. Fail closed: mask every truthy + # value rather than risk echoing a credential back in the clear. + logger.warning( + "Could not determine the configuration schema for semantic layer " + "type %s; masking all configuration values.", + layer.type, + ) + return {key: PASSWORD_MASK if value else value for key, value in config.items()} + + secret_keys = { + key + for key, prop in schema.get("properties", {}).items() + if isinstance(prop, dict) and prop.get("writeOnly") + } + if not secret_keys: + return config + + return { + key: PASSWORD_MASK if key in secret_keys and value else value + for key, value in config.items() + } + + def _serialize_layer(layer: SemanticLayer) -> dict[str, Any]: config = layer.configuration if isinstance(config, str): config = json.loads(config) + config = _mask_configuration(layer, config or {}) return { "uuid": str(layer.uuid), "name": layer.name, @@ -683,6 +726,9 @@ def runtime_schema(self, uuid: str) -> FlaskResponse: 404: $ref: '#/components/responses/404' """ + if not is_feature_enabled("SEMANTIC_LAYERS"): + return self.response_404() + layer = SemanticLayerDAO.find_by_uuid(uuid) if not layer: return self.response_404() @@ -1164,6 +1210,9 @@ def get_list(self) -> FlaskResponse: 401: $ref: '#/components/responses/401' """ + if not is_feature_enabled("SEMANTIC_LAYERS"): + return self.response_404() + layers = SemanticLayerDAO.find_all() result = [_serialize_layer(layer) for layer in layers] return self.response(200, result=result) @@ -1192,6 +1241,9 @@ def get(self, uuid: str) -> FlaskResponse: 404: $ref: '#/components/responses/404' """ + if not is_feature_enabled("SEMANTIC_LAYERS"): + return self.response_404() + layer = SemanticLayerDAO.find_by_uuid(uuid) if not layer: return self.response_404() diff --git a/tests/unit_tests/commands/semantic_layer/update_test.py b/tests/unit_tests/commands/semantic_layer/update_test.py index ad64f9ae86d2..9ae58afccf38 100644 --- a/tests/unit_tests/commands/semantic_layer/update_test.py +++ b/tests/unit_tests/commands/semantic_layer/update_test.py @@ -28,10 +28,13 @@ SemanticViewNotFoundError, ) from superset.commands.semantic_layer.update import ( + _unmask_configuration, UpdateSemanticLayerCommand, UpdateSemanticViewCommand, ) +from superset.constants import PASSWORD_MASK from superset.exceptions import SupersetSecurityException +from superset.utils import json def test_update_semantic_view_success(mocker: MockerFixture) -> None: @@ -463,3 +466,110 @@ def test_update_uniqueness_same_config_same_name_fails( layer_uuid="layer-uuid-1", configuration={"schema": "prod"}, ) + + +# ============================================================================= +# _unmask_configuration tests +# ============================================================================= + + +def test_unmask_configuration_restores_masked_secret() -> None: + """A masked write-only field in the payload is replaced by the stored + value rather than overwriting the real credential with the mask.""" + result = _unmask_configuration( + '{"account": "test", "password": "hunter2"}', + {"account": "test", "password": PASSWORD_MASK}, + ) + + assert result == {"account": "test", "password": "hunter2"} + + +def test_unmask_configuration_keeps_fresh_secret() -> None: + """A genuinely new secret value (not the mask sentinel) passes through + unchanged.""" + result = _unmask_configuration( + '{"account": "test", "password": "old-secret"}', + {"account": "test", "password": "new-secret"}, + ) + + assert result == {"account": "test", "password": "new-secret"} + + +def test_unmask_configuration_restores_fail_closed_masked_fields() -> None: + """When the read path fell back to masking every value (schema + unavailable at GET time), the update path must restore all of them on + round-trip, not just write-only ones -- otherwise a name-only save + persists the literal mask into non-secret fields like ``account`` once + the schema becomes available again.""" + result = _unmask_configuration( + '{"account": "test", "database": "prod", "password": "hunter2"}', + { + "account": PASSWORD_MASK, + "database": PASSWORD_MASK, + "password": PASSWORD_MASK, + }, + ) + + assert result == { + "account": "test", + "database": "prod", + "password": "hunter2", + } + + +def test_unmask_configuration_missing_existing_key() -> None: + """A masked field with no corresponding stored value passes through + unchanged rather than raising.""" + result = _unmask_configuration( + '{"account": "test"}', + {"account": "test", "password": PASSWORD_MASK}, + ) + + assert result == {"account": "test", "password": PASSWORD_MASK} + + +def test_update_semantic_layer_preserves_masked_secret_end_to_end( + mocker: MockerFixture, +) -> None: + """A name-only PUT that round-trips the masked GET response does not + overwrite the stored credential with the literal mask.""" + mock_model = MagicMock() + mock_model.type = "snowflake" + mock_model.configuration = '{"account": "test", "password": "hunter2"}' + + dao = mocker.patch( + "superset.commands.semantic_layer.update.SemanticLayerDAO", + ) + dao.find_by_uuid.return_value = mock_model + dao.update.return_value = mock_model + + mocker.patch( + "superset.commands.semantic_layer.update.current_user_can_modify_object", + ) + + mock_cls = MagicMock() + mock_cls.get_configuration_schema.return_value = { + "properties": {"password": {"type": "string", "writeOnly": True}} + } + mocker.patch.dict( + "superset.commands.semantic_layer.update.registry", + {"snowflake": mock_cls}, + clear=True, + ) + + data = { + "name": "Renamed", + "configuration": {"account": "test", "password": PASSWORD_MASK}, + } + UpdateSemanticLayerCommand("some-uuid", data).run() + + mock_cls.from_configuration.assert_called_once_with( + {"account": "test", "password": "hunter2"} + ) + dao.update.assert_called_once_with( + mock_model, + attributes={ + "name": "Renamed", + "configuration": json.dumps({"account": "test", "password": "hunter2"}), + }, + ) diff --git a/tests/unit_tests/semantic_layers/api_test.py b/tests/unit_tests/semantic_layers/api_test.py index 385dcdbc6c83..603b38fccf65 100644 --- a/tests/unit_tests/semantic_layers/api_test.py +++ b/tests/unit_tests/semantic_layers/api_test.py @@ -36,9 +36,14 @@ SemanticViewNotFoundError, SemanticViewUpdateFailedError, ) +from superset.constants import PASSWORD_MASK from superset.errors import ErrorLevel, SupersetError, SupersetErrorType from superset.exceptions import SupersetSecurityException -from superset.semantic_layers.api import SemanticLayerRestApi, SemanticViewRestApi +from superset.semantic_layers.api import ( + _mask_configuration, + SemanticLayerRestApi, + SemanticViewRestApi, +) SEMANTIC_LAYERS_APP = pytest.mark.parametrize( "app", @@ -618,6 +623,21 @@ def test_runtime_schema_exception( assert "Bad config" in response.json["message"] +@pytest.mark.parametrize( + "app", + [{"FEATURE_FLAGS": {"SEMANTIC_LAYERS": False}}], + indirect=True, +) +def test_runtime_schema_flag_off_returns_404( + client: Any, + full_api_access: None, +) -> None: + response = client.post( + f"/api/v1/semantic_layer/{uuid_lib.uuid4()}/schema/runtime", + ) + assert response.status_code == 404 + + @SEMANTIC_LAYERS_APP def test_post_semantic_layer( client: Any, @@ -937,6 +957,11 @@ def test_get_list_semantic_layers( layer2.configuration = '{"account": "test"}' layer2.changed_on_delta_humanized.return_value = "2 hours ago" + mocker.patch.dict( + "superset.semantic_layers.api.registry", + {"snowflake": MagicMock(get_configuration_schema=lambda: {"properties": {}})}, + clear=True, + ) mock_dao = mocker.patch("superset.semantic_layers.api.SemanticLayerDAO") mock_dao.find_all.return_value = [layer1, layer2] @@ -967,6 +992,19 @@ def test_get_list_semantic_layers_empty( assert response.json["result"] == [] +@pytest.mark.parametrize( + "app", + [{"FEATURE_FLAGS": {"SEMANTIC_LAYERS": False}}], + indirect=True, +) +def test_get_list_semantic_layers_flag_off_returns_404( + client: Any, + full_api_access: None, +) -> None: + response = client.get("/api/v1/semantic_layer/") + assert response.status_code == 404 + + @SEMANTIC_LAYERS_APP def test_get_semantic_layer( client: Any, @@ -984,6 +1022,11 @@ def test_get_semantic_layer( layer.configuration = '{"account": "test"}' layer.changed_on_delta_humanized.return_value = "1 day ago" + mocker.patch.dict( + "superset.semantic_layers.api.registry", + {"snowflake": MagicMock(get_configuration_schema=lambda: {"properties": {}})}, + clear=True, + ) mock_dao = mocker.patch("superset.semantic_layers.api.SemanticLayerDAO") mock_dao.find_by_uuid.return_value = layer @@ -1013,6 +1056,19 @@ def test_get_semantic_layer_not_found( assert response.status_code == 404 +@pytest.mark.parametrize( + "app", + [{"FEATURE_FLAGS": {"SEMANTIC_LAYERS": False}}], + indirect=True, +) +def test_get_semantic_layer_flag_off_returns_404( + client: Any, + full_api_access: None, +) -> None: + response = client.get(f"/api/v1/semantic_layer/{uuid_lib.uuid4()}") + assert response.status_code == 404 + + @SEMANTIC_LAYERS_APP def test_get_semantic_layer_forbidden( client: Any, @@ -1056,6 +1112,11 @@ def test_serialize_layer_string_config( layer.configuration = '{"account": "test"}' layer.changed_on_delta_humanized.return_value = "1 day ago" + mocker.patch.dict( + "superset.semantic_layers.api.registry", + {"snowflake": MagicMock(get_configuration_schema=lambda: {"properties": {}})}, + clear=True, + ) mock_dao = mocker.patch("superset.semantic_layers.api.SemanticLayerDAO") mock_dao.find_by_uuid.return_value = layer @@ -1081,6 +1142,11 @@ def test_serialize_layer_dict_config( layer.configuration = {"account": "test"} layer.changed_on_delta_humanized.return_value = "1 day ago" + mocker.patch.dict( + "superset.semantic_layers.api.registry", + {"snowflake": MagicMock(get_configuration_schema=lambda: {"properties": {}})}, + clear=True, + ) mock_dao = mocker.patch("superset.semantic_layers.api.SemanticLayerDAO") mock_dao.find_by_uuid.return_value = layer @@ -1115,6 +1181,141 @@ def test_serialize_layer_none_config( assert response.json["result"]["configuration"] == {} +def test_mask_configuration_redacts_write_only_fields(mocker: MockerFixture) -> None: + """Test _mask_configuration redacts properties the schema marks writeOnly.""" + layer = MagicMock() + layer.type = "snowflake" + + mock_cls = MagicMock() + mock_cls.get_configuration_schema.return_value = { + "properties": { + "account": {"type": "string"}, + "password": {"type": "string", "writeOnly": True}, + }, + } + mocker.patch.dict( + "superset.semantic_layers.api.registry", + {"snowflake": mock_cls}, + clear=True, + ) + + result = _mask_configuration(layer, {"account": "test", "password": "hunter2"}) + + assert result == {"account": "test", "password": PASSWORD_MASK} + + +def test_mask_configuration_skips_falsy_secret_values( + mocker: MockerFixture, +) -> None: + """Test _mask_configuration leaves an unset write-only field alone.""" + layer = MagicMock() + layer.type = "snowflake" + + mock_cls = MagicMock() + mock_cls.get_configuration_schema.return_value = { + "properties": {"password": {"type": "string", "writeOnly": True}}, + } + mocker.patch.dict( + "superset.semantic_layers.api.registry", + {"snowflake": mock_cls}, + clear=True, + ) + + result = _mask_configuration(layer, {"password": ""}) + + assert result == {"password": ""} + + +def test_mask_configuration_no_write_only_properties(mocker: MockerFixture) -> None: + """Test _mask_configuration is a no-op when the schema has no writeOnly fields.""" + layer = MagicMock() + layer.type = "snowflake" + + mock_cls = MagicMock() + mock_cls.get_configuration_schema.return_value = { + "properties": {"account": {"type": "string"}}, + } + mocker.patch.dict( + "superset.semantic_layers.api.registry", + {"snowflake": mock_cls}, + clear=True, + ) + + config = {"account": "test"} + result = _mask_configuration(layer, config) + + assert result is config + + +def test_mask_configuration_no_registered_class(mocker: MockerFixture) -> None: + """Test _mask_configuration fails closed when the type has no connector.""" + layer = MagicMock() + layer.type = "unregistered" + + mocker.patch.dict("superset.semantic_layers.api.registry", {}, clear=True) + + config = {"account": "test", "password": "hunter2"} + result = _mask_configuration(layer, config) + + assert result == {"account": PASSWORD_MASK, "password": PASSWORD_MASK} + + +def test_mask_configuration_schema_error(mocker: MockerFixture) -> None: + """Test _mask_configuration fails closed if the schema can't load.""" + layer = MagicMock() + layer.type = "snowflake" + + mock_cls = MagicMock() + mock_cls.get_configuration_schema.side_effect = ValueError("boom") + mocker.patch.dict( + "superset.semantic_layers.api.registry", + {"snowflake": mock_cls}, + clear=True, + ) + + config = {"account": "test", "password": "hunter2"} + result = _mask_configuration(layer, config) + + assert result == {"account": PASSWORD_MASK, "password": PASSWORD_MASK} + + +@SEMANTIC_LAYERS_APP +def test_get_semantic_layer_masks_write_only_configuration( + client: Any, + full_api_access: None, + mocker: MockerFixture, +) -> None: + """Test GET / redacts write-only configuration fields.""" + layer = MagicMock() + layer.uuid = uuid_lib.uuid4() + layer.name = "Layer" + layer.description = None + layer.type = "snowflake" + layer.cache_timeout = None + layer.configuration = {"account": "test", "password": "hunter2"} + layer.changed_on_delta_humanized.return_value = "1 day ago" + + mock_dao = mocker.patch("superset.semantic_layers.api.SemanticLayerDAO") + mock_dao.find_by_uuid.return_value = layer + + mock_cls = MagicMock() + mock_cls.get_configuration_schema.return_value = { + "properties": {"password": {"type": "string", "writeOnly": True}}, + } + mocker.patch.dict( + "superset.semantic_layers.api.registry", + {"snowflake": mock_cls}, + clear=True, + ) + + response = client.get(f"/api/v1/semantic_layer/{layer.uuid}") + + assert response.status_code == 200 + configuration = response.json["result"]["configuration"] + assert configuration["account"] == "test" + assert configuration["password"] == PASSWORD_MASK + + def test_infer_discriminators_injects_discriminator() -> None: """Test _infer_discriminators injects discriminator values.""" from superset.semantic_layers.api import _infer_discriminators @@ -2500,3 +2701,51 @@ def test_semantic_layer_views_flag_off_unwrapped() -> None: assert response == ("404", 404) api.response_404.assert_called_once() + + +def test_semantic_layer_get_list_flag_off_unwrapped() -> None: + """Cover get_list() feature-flag guard without auth decorators.""" + api = SemanticLayerRestApi() + api.response_404 = MagicMock(return_value=("404", 404)) + get_list_fn = inspect.unwrap(SemanticLayerRestApi.get_list) + + with patch( + "superset.semantic_layers.api.is_feature_enabled", + return_value=False, + ): + response = get_list_fn(api) + + assert response == ("404", 404) + api.response_404.assert_called_once() + + +def test_semantic_layer_get_flag_off_unwrapped() -> None: + """Cover get() feature-flag guard without auth decorators.""" + api = SemanticLayerRestApi() + api.response_404 = MagicMock(return_value=("404", 404)) + get_fn = inspect.unwrap(SemanticLayerRestApi.get) + + with patch( + "superset.semantic_layers.api.is_feature_enabled", + return_value=False, + ): + response = get_fn(api, str(uuid_lib.uuid4())) + + assert response == ("404", 404) + api.response_404.assert_called_once() + + +def test_semantic_layer_runtime_schema_flag_off_unwrapped() -> None: + """Cover runtime_schema() feature-flag guard without auth decorators.""" + api = SemanticLayerRestApi() + api.response_404 = MagicMock(return_value=("404", 404)) + runtime_schema_fn = inspect.unwrap(SemanticLayerRestApi.runtime_schema) + + with patch( + "superset.semantic_layers.api.is_feature_enabled", + return_value=False, + ): + response = runtime_schema_fn(api, str(uuid_lib.uuid4())) + + assert response == ("404", 404) + api.response_404.assert_called_once() From c19879ffff2cedc255f89f63e3884747a62a10aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robin=20Emer=C5=A1i=C4=8D?= Date: Wed, 2 Sep 2026 19:25:15 +0200 Subject: [PATCH 10/12] chore(translations): updated Slovenian translations (#43735) --- .../translations/sl/LC_MESSAGES/messages.po | 5110 ++++++----------- 1 file changed, 1721 insertions(+), 3389 deletions(-) diff --git a/superset/translations/sl/LC_MESSAGES/messages.po b/superset/translations/sl/LC_MESSAGES/messages.po index 202c11ac4e6a..79dcc31266c9 100644 --- a/superset/translations/sl/LC_MESSAGES/messages.po +++ b/superset/translations/sl/LC_MESSAGES/messages.po @@ -15,19 +15,19 @@ # under the License. msgid "" msgstr "" -"Project-Id-Version: Superset\n" +"Project-Id-Version: Superset\n" "Report-Msgid-Bugs-To: dkrat7 @github.com\n" -"POT-Creation-Date: 2026-07-31 11:53+0100\n" -"PO-Revision-Date: 2024-10-05 23:46+0200\n" -"Last-Translator: dkrat7 \n" -"Language: sl_SI\n" +"POT-Creation-Date: 2026-07-17 15:46-0700\n" +"PO-Revision-Date: 2026-07-29 16:16+0200\n" +"Last-Translator: lapor-kris \n" "Language-Team: \n" -"Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100>=3 " -"&& n%100<=4 ? 2 : 3);\n" +"Language: sl_SI\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100>=3 && n%100<=4 ? 2 : 3);\n" "Generated-By: Babel 2.17.0\n" +"X-Generator: Poedit 3.9\n" msgid "" "\n" @@ -90,7 +90,7 @@ msgstr "" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fr, ja, lv, mi, pt_BR, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy, python-format +#, python-format msgid "" "\n" "

Your report/alert was unable to be generated because of " @@ -100,10 +100,8 @@ msgid "" " " msgstr "" "\n" -"

Vašega poročila/opozorila ni bilo mogoče ustvariti zaradi " -"naslednje napake: %(text)s

\n" -"

Prosimo, preverite nadzorno ploščo/grafikon za napake.

" -"\n" +"

Vašega poročila/opozorila ni bilo mogoče ustvariti zaradi naslednje napake: %(text)s

\n" +"

Preverite, ali nadzorna plošča oziroma grafikon vsebuje napake.

\n" "

%(call_to_action)s

\n" " " @@ -128,14 +126,16 @@ msgstr " v vrstici %(line)d" msgid " expression which needs to adhere to the " msgstr " , ki mora upoštevati " -#, fuzzy msgid " for details." -msgstr "Podrobnosti" +msgstr " za podrobnosti." #, python-format msgid " near '%(highlight)s'" msgstr " blizu '%(highlight)s'" +msgid " source code of Superset's sandboxed parser" +msgstr " izvorno kodo za Supersetov \"sandboxed parser\"" + msgid "" " standard to ensure that the lexicographical ordering\n" " coincides with the chronological ordering. If the\n" @@ -174,7 +174,6 @@ msgstr " za dodajanje mer" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, pt_BR, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid " to check for details." msgstr " za preverjanje podrobnosti." @@ -189,9 +188,8 @@ msgstr "" " za odpiranje SQL laboratorija. Tam lahko poizvedbo shranite kot " "podatkovni set." -#, fuzzy msgid " to see details." -msgstr "Podrobnosti poizvedbe" +msgstr " za ogled podrobnosti." msgid " to visualize your data." msgstr " za vizualizacijo podatkov." @@ -201,15 +199,15 @@ msgstr "!= (ni enako)" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, pt_BR, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy, python-format +#, python-format msgid "\"%s\" is now the system dark theme" -msgstr "\"%s\" je zdaj sistemska temna tema" +msgstr "»%s« je zdaj sistemska temna tema" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, pt_BR, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy, python-format +#, python-format msgid "\"%s\" is now the system default theme" -msgstr "\"%s\" je zdaj privzeta sistemska tema" +msgstr "»%s« je zdaj privzeta sistemska tema" #, no-python-format msgid "% calculation" @@ -225,7 +223,7 @@ msgstr "% celote" #, python-format msgid "%(alertType)s \"%(alertName)s\" triggered successfully" -msgstr "" +msgstr "%(alertType)s »%(alertName)s« je bil uspešno sprožen" #, python-format msgid "%(dialect)s cannot be used as a data source for security reasons." @@ -233,21 +231,13 @@ msgstr "" "%(dialect)s ni mogoče uporabiti kot podatkovni vir zaradi varnostnih " "razlogov." -#, fuzzy, python-format -msgid "%(label)s file" -msgstr "%(type)s datoteka" - #, python-format -msgid "%(name)s deleted successfully" -msgstr "" - -#, python-format -msgid "%(name)s restored successfully" -msgstr "" +msgid "%(label)s file" +msgstr "Datoteka %(label)s" #, python-format msgid "%(name)s.%(extension)s" -msgstr "" +msgstr "%(name)s.%(extension)s" #, python-format msgid "%(name)s.csv" @@ -257,30 +247,6 @@ msgstr "%(name)s.csv" msgid "%(name)s.pdf" msgstr "%(name)s.pdf" -#, python-format -msgid "%(num)d hour" -msgid_plural "%(num)d hours" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" - -#, python-format -msgid "%(num)d minute" -msgid_plural "%(num)d minutes" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" - -#, python-format -msgid "%(num)d second" -msgid_plural "%(num)d seconds" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" - #, python-format msgid "%(object)s does not exist in this database." msgstr "%(object)s ne obstaja v tej podatkovni bazi." @@ -291,13 +257,11 @@ msgstr "%(prefix)s %(title)s" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, es, sr, # sr_Latn] -#, fuzzy, python-format +#, python-format msgid "" "%(prefix)sResults truncated to %(row_count)s rows due to memory " "constraints." -msgstr "" -"%(prefix)sRezultati so bili skrajšani na %(row_count)s vrstic zaradi " -"omejitev pomnilnika." +msgstr "%(prefix)s Rezultati prirezani na %(row_count)s vrstic zaradi omejitev pomnilnika." #, python-format msgid "" @@ -317,18 +281,10 @@ msgid "%(suggestion)s instead of \"%(undefinedParameter)s?\"" msgid_plural "" "%(firstSuggestions)s or %(lastSuggestion)s instead of " "\"%(undefinedParameter)s\"?" -msgstr[0] "" -"%(firstSuggestions)s %(lastSuggestion)s namesto " -"\"%(undefinedParameter)s\"?" -msgstr[1] "" -"%(firstSuggestions)s ali %(lastSuggestion)s namesto " -"\"%(undefinedParameter)s\"?" -msgstr[2] "" -"%(firstSuggestions)s ali %(lastSuggestion)s namesto " -"\"%(undefinedParameter)s\"?" -msgstr[3] "" -"%(firstSuggestions)s ali %(lastSuggestion)s namesto " -"\"%(undefinedParameter)s\"?" +msgstr[0] "%(suggestion)s namesto »%(undefinedParameter)s?«" +msgstr[1] "%(firstSuggestions)s ali %(lastSuggestion)s namesto »%(undefinedParameter)s«?" +msgstr[2] "%(firstSuggestions)s ali %(lastSuggestion)s namesto »%(undefinedParameter)s«?" +msgstr[3] "%(firstSuggestions)s ali %(lastSuggestion)s namesto »%(undefinedParameter)s«?" #, python-format msgid "" @@ -340,13 +296,13 @@ msgstr "" "Ponovno preverite poizvedbo.\n" "Izjema: %(ex)s" -#, fuzzy, python-format +#, python-format msgid "%s %s" -msgstr "%s%s" +msgstr "%s %s" -#, fuzzy, python-format +#, python-format msgid "%s ENCRYPTED EXTRA" -msgstr "Dodatna varnost" +msgstr "%s ŠIFRIRANI DODATNI PODATKI" #, python-format msgid "%s Error" @@ -356,9 +312,9 @@ msgstr "%s napaka" msgid "%s PASSWORD" msgstr "%s GESLO" -#, fuzzy, python-format +#, python-format msgid "%s Physical" -msgstr "Fizičen" +msgstr "%s fizični" #, python-format msgid "%s SSH TUNNEL PASSWORD" @@ -376,9 +332,9 @@ msgstr "%s GESLO ZASEBNEGA KLJUČA ZA SSH TUNEL" msgid "%s Selected" msgstr "Izbranih: %s" -#, fuzzy, python-format +#, python-format msgid "%s Selected (%s)" -msgstr "Izbranih: %s" +msgstr "%s izbranih (%s)" #, python-format msgid "%s Selected (Physical)" @@ -390,65 +346,65 @@ msgstr "Izbranih: %s (virtualni)" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, es, sr, # sr_Latn] -#, fuzzy, python-format +#, python-format msgid "%s Semantic View" msgstr "%s Semantični pogled" -#, fuzzy, python-format +#, python-format msgid "%s URL" -msgstr "URL" +msgstr "URL za %s" -#, fuzzy, python-format +#, python-format msgid "%s Virtual" -msgstr "Virtualen" +msgstr "%s navidezni" #, python-format msgid "%s aggregates(s)" msgstr "Agreg. funkcije: %s" -#, fuzzy, python-format +#, python-format msgid "%s column" msgid_plural "%s columns" -msgstr[0] "Stolpci: %s" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" +msgstr[0] "%s stolpec" +msgstr[1] "%s stolpca" +msgstr[2] "%s stolpci" +msgstr[3] "%s stolpcev" #, python-format msgid "%s column(s)" msgstr "Stolpci: %s" -#, fuzzy, python-format +#, python-format msgid "%s day ago" msgid_plural "%s days ago" -msgstr[0] "1 day ago" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" +msgstr[0] "pred %s dnevom" +msgstr[1] "pred %s dnevoma" +msgstr[2] "pred %s dnevi" +msgstr[3] "pred %s dnevi" -#, fuzzy, python-format +#, python-format msgid "%s hr ago" msgid_plural "%s hr ago" -msgstr[0] "%s vrstica" -msgstr[1] "%s vrstici" -msgstr[2] "%s vrstice" -msgstr[3] "%s vrstic" +msgstr[0] "pred %s uro" +msgstr[1] "pred %s urama" +msgstr[2] "pred %s urami" +msgstr[3] "pred %s urami" -#, fuzzy, python-format +#, python-format msgid "%s imported" -msgstr "Podatki uvoženi" +msgstr "%s uvoženo" -#, fuzzy, python-format +#, python-format msgid "%s item" msgid_plural "%s items" -msgstr[0] "Možnosti: %s" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" +msgstr[0] "%s element" +msgstr[1] "%s elementa" +msgstr[2] "%s elementi" +msgstr[3] "%s elementov" -#, fuzzy, python-format +#, python-format msgid "%s item(s)" -msgstr "Možnosti: %s" +msgstr "%s element(i)" #, python-format msgid "" @@ -458,33 +414,21 @@ msgstr "" "%s elementov ni mogoče označiti, ker nimate pravic za urejanje vseh " "izbranih elementov." -#, fuzzy, python-format +#, python-format msgid "%s metric" msgid_plural "%s metrics" -msgstr[0] "Mera za razvrščanje" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" +msgstr[0] "%s mera" +msgstr[1] "%s meri" +msgstr[2] "%s mere" +msgstr[3] "%s mer" -#, fuzzy, python-format +#, python-format msgid "%s min ago" msgid_plural "%s min ago" -msgstr[0] "1 month ago" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" - -#, python-format -msgid "" -"%s of the selected items is a semantic view, which cannot be archived: it" -" will be deleted permanently and cannot be recovered." -msgid_plural "" -"%s of the selected items are semantic views, which cannot be archived: " -"they will be deleted permanently and cannot be recovered." -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" +msgstr[0] "pred %s minuto" +msgstr[1] "pred %s minutama" +msgstr[2] "pred %s minutami" +msgstr[3] "pred %s minutami" #, python-format msgid "%s operator(s)" @@ -502,37 +446,37 @@ msgstr[3] "%s možnosti" msgid "%s option(s)" msgstr "Možnosti: %s" -#, fuzzy, python-format +#, python-format msgid "%s out of %s column" msgid_plural "%s out of %s columns" -msgstr[0] "Prilagodi stolpce" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" +msgstr[0] "%s od %s stolpca" +msgstr[1] "%s od %s stolpcev" +msgstr[2] "%s od %s stolpcev" +msgstr[3] "%s od %s stolpcev" -#, fuzzy, python-format +#, python-format msgid "%s out of %s metric" msgid_plural "%s out of %s metrics" -msgstr[0] "Mera za razvrščanje" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" +msgstr[0] "%s od %s mere" +msgstr[1] "%s od %s mer" +msgstr[2] "%s od %s mer" +msgstr[3] "%s od %s mer" -#, fuzzy, python-format +#, python-format msgid "%s out of %s selected" -msgstr "Izbranih: %s" +msgstr "Izbranih %s od %s" #, python-format msgid "%s recipients" msgstr "%s prejemnikov" -#, fuzzy, python-format +#, python-format msgid "%s record..." msgid_plural "%s records..." -msgstr[0] "%s napaka" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" +msgstr[0] "%s zapis ..." +msgstr[1] "%s zapisa ..." +msgstr[2] "%s zapisi ..." +msgstr[3] "%s zapisov ..." #, python-format msgid "%s row" @@ -542,47 +486,47 @@ msgstr[1] "%s vrstici" msgstr[2] "%s vrstice" msgstr[3] "%s vrstic" -#, fuzzy, python-format +#, python-format msgid "%s s ago" msgid_plural "%s s ago" -msgstr[0] "30 days ago" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" +msgstr[0] "pred %s sekundo" +msgstr[1] "pred %s sekundama" +msgstr[2] "pred %s sekundami" +msgstr[3] "pred %s sekundami" #, python-format msgid "%s saved metric(s)" msgstr "Shranjene mere: %s" -#, fuzzy, python-format +#, python-format msgid "%s second" msgid_plural "%s seconds" -msgstr[0] "5 second" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" +msgstr[0] "%s sekunda" +msgstr[1] "%s sekundi" +msgstr[2] "%s sekunde" +msgstr[3] "%s sekund" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, es, sr, # sr_Latn] -#, fuzzy, python-format +#, python-format msgid "%s semantic view(s) added" -msgstr "%s semantičnih pogledov dodano" +msgstr "Dodanih semantičnih pogledov: %s" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, es, sr, # sr_Latn] -#, fuzzy, python-format +#, python-format msgid "%s semantic view(s) failed to add" -msgstr "Dodajanje %s semantičnih pogledov ni uspelo" +msgstr "Semantičnih pogledov ni bilo mogoče dodati: %s" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy, python-format +#, python-format msgid "%s semantic view(s) failed to add: %s" -msgstr "Dodajanje %s semantičnih pogledov ni uspelo: %s" +msgstr "Semantičnih pogledov (%s) ni bilo mogoče dodati: %s" -#, fuzzy, python-format +#, python-format msgid "%s tab selected" -msgstr "Izbranih: %s" +msgstr "Izbranih zavihkov: %s" #, python-format msgid "%s updated" @@ -644,9 +588,8 @@ msgstr "+ %s več" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, pt_BR, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid ", then paste the JSON below. See our" -msgstr ", nato prilepite JSON spodaj. Oglejte si naše" +msgstr ", nato prilepite spodnji JSON. Oglejte si naše" msgid "" "-- Note: Unless you save your query, these tabs will NOT persist if you " @@ -657,13 +600,13 @@ msgstr "" "boste počistili piškote ali zamenjali brskalnik.\n" "\n" -#, fuzzy, python-format +#, python-format msgid "... and %d more" -msgstr "... in %s drugih" +msgstr "... in še %d" -#, fuzzy, python-format +#, python-format msgid "... and %s more records" -msgstr "... in %s drugih" +msgstr "... in še %s zapisov" #, python-format msgid "... and %s others" @@ -729,17 +672,15 @@ msgstr "frekvenca: 1 leto - začetek" msgid "10 minute" msgstr "10 minute" -#, fuzzy msgid "10 seconds" -msgstr "30 seconds" +msgstr "10 sekund" -#, fuzzy msgid "10/90 percentiles" -msgstr "9/91 percentil" +msgstr "10/90 percentilov" #. do-not-translate msgid "10000" -msgstr "" +msgstr "10000" msgid "104 weeks" msgstr "104 weeks" @@ -747,9 +688,8 @@ msgstr "104 weeks" msgid "104 weeks ago" msgstr "104 weeks ago" -#, fuzzy msgid "12 hours" -msgstr "1 ura" +msgstr "12 ur" msgid "15 minute" msgstr "15 minute" @@ -787,9 +727,8 @@ msgstr "2/98 percentil" msgid "22" msgstr "22" -#, fuzzy msgid "24 hours" -msgstr "6 hour" +msgstr "24 ur" msgid "28 days" msgstr "28 days" @@ -845,9 +784,8 @@ msgstr "5 second" msgid "5 seconds" msgstr "5 seconds" -#, fuzzy msgid "5/95 percentiles" -msgstr "9/91 percentil" +msgstr "5/95 percentilov" msgid "52 weeks" msgstr "52 weeks" @@ -861,9 +799,8 @@ msgstr "52 tednov z začetkom v ponedeljek (freq=52W-MON)" msgid "6 hour" msgstr "6 hour" -#, fuzzy msgid "6 hours" -msgstr "6 hour" +msgstr "6 ur" msgid "60 days" msgstr "60 days" @@ -919,26 +856,30 @@ msgstr ">= (večje ali enako)" msgid "A Big Number" msgstr "Velika številka" +# Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, +# lv, pt_BR, ru, sk, sr, sr_Latn, tr, uk] +msgid "A JavaScript function that generates a label configuration object" +msgstr "Funkcija JavaScript, ki ustvari objekt konfiguracije oznake" + +# Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, +# lv, pt_BR, ru, sk, sr, sr_Latn, tr, uk] +msgid "A JavaScript function that generates an icon configuration object" +msgstr "Funkcija JavaScript, ki ustvari objekt konfiguracije ikone" + # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy, python-brace-format +#, python-brace-format msgid "" "A JavaScript object that adheres to the ECharts options specification, " "overriding other control options with higher precedence. (i.e. { title: {" " text: \"My Chart\" }, tooltip: { trigger: \"item\" } }). Details: " "https://echarts.apache.org/en/option.html. " msgstr "" -"Objekt JavaScript, ki ustreza specifikaciji možnosti ECharts in prepiše " -"druge možnosti kontrolnika z višjo prednostjo. (npr. { title: { text: " -"\"My Chart\" }, tooltip: { trigger: \"item\" } }). Podrobnosti: " -"https://echarts.apache.org/en/option.html. " - -msgid "A TTL is required for ephemeral state." -msgstr "" +"Predmet JavaScript, ki je v skladu s specifikacijo možnosti ECharts in preglasi druge možnosti nadzora z višjo prednostjo. (tj. { title: { text: \"My " +"Chart\" }, tooltip: { trigger: \"item\" } }). Podrobnosti: https://echarts.apache.org/en/option.html. " -#, fuzzy msgid "A comma separated list of columns that should be parsed as dates" -msgstr "Izberite stolpce, ki bodo prepoznani kot datumi" +msgstr "Seznam stolpcev, ločenih z vejico, ki jih je treba razčleniti kot datume" msgid "A comma-separated list of schemas that files are allowed to upload to." msgstr "Z vejicami ločen seznam shem, kjer je dovoljeno nalaganje datotek." @@ -951,12 +892,10 @@ msgstr "Podatkovna baza z enakim imenom že obstaja." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fr, ja, lv, mi, pt_BR, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "A date is required when using custom date shift" -msgstr "Datum je obvezen pri uporabi prilagojenega premika datuma" +msgstr "Pri uporabi datumskega premika po meri je potreben datum" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ja] -#, fuzzy msgid "A description for your dashboard" msgstr "Opis vaše nadzorne plošče" @@ -1001,9 +940,8 @@ msgstr "Seznam subjektov, ki lahko vidijo grafikon. Iskanje po imenu je omogoče msgid "A list of tags that have been applied to this chart." msgstr "Seznam oznak, ki so povezane s tem grafikonom." -#, fuzzy msgid "A list of tags that have been applied to this dashboard." -msgstr "Seznam oznak, ki so povezane s tem grafikonom." +msgstr "Seznam oznak, ki so bile uporabljene na tej nadzorni plošči." msgid "A map of the world, that can indicate values in different countries." msgstr "Zemljevid sveta, ki lahko prikazuje vrednosti po državah." @@ -1019,13 +957,10 @@ msgid "A metric to use for color" msgstr "Mera za barvo" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ja] -#, fuzzy msgid "" "A multiplier applied to the point radius. Use this to uniformly scale all" " points." -msgstr "" -"Množitelj, ki se uporabi za polmer točke. Uporabite ga za enakomerno " -"prilagajanje vseh točk." +msgstr "Množitelj, uporabljen za polmer točke. Uporabite to za enotno skaliranje vseh točk." msgid "A new chart and dashboard will be created." msgstr "Ustvarjena bosta nov grafikon in nadzorna plošča." @@ -1066,27 +1001,24 @@ msgstr "" " sintakse" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ja] -#, fuzzy, python-format +#, python-format msgid "" "A soft-deleted dataset (uuid %(uuid)s) already references this table. " "Restore it via POST /api/v1/dataset/%(uuid)s/restore before creating a " "new dataset over this table, or use a different table name." msgstr "" -"Mehko izbrisana podatkovna zbirka (uuid %(uuid)s) že sklicuje na to " -"tabelo. Obnovite jo prek POST /api/v1/dataset/%(uuid)s/restore, preden " -"ustvarite novo podatkovno zbirko nad to tabelo, ali uporabite drugo ime " -"tabele." +"Mehko izbrisan podatkovni niz (uuid %(uuid)s) se že sklicuje na to tabelo. Obnovite ga prek POST /api/v1/dataset/ %(uuid)s /restore, preden ustvarite nov " +"podatkovni niz v tej tabeli, ali uporabite drugo ime tabele." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ja] -#, fuzzy, python-format +#, python-format msgid "" "A soft-deleted dataset (uuid %(uuid)s) already references this table. " "Restore it via POST /api/v1/dataset/%(uuid)s/restore before uploading, or" " upload to a different table name." msgstr "" -"Mehko izbrisana podatkovna zbirka (uuid %(uuid)s) že sklicuje na to " -"tabelo. Obnovite jo prek POST /api/v1/dataset/%(uuid)s/restore pred " -"nalaganjem ali naložite v drugo ime tabele." +"Mehko izbrisan podatkovni niz (uuid %(uuid)s) se že sklicuje na to tabelo. Obnovite jo prek POST /api/v1/dataset/ %(uuid)s /restore pred nalaganjem ali " +"naložite v drugo ime tabele." msgid "A timeout occurred while executing the query." msgstr "Pri izvajanju poizvedbe je potekel čas." @@ -1098,7 +1030,7 @@ msgid "A timeout occurred while generating a dataframe." msgstr "Pri ustvarjanju podatkovnega okvira je potekel čas." msgid "A timeout occurred while generating an Excel file." -msgstr "" +msgstr "Med ustvarjanjem datoteke Excel je potekel čas." msgid "A timeout occurred while taking a screenshot." msgstr "Pri ustvarjanju zaslonske slike je potekel čas." @@ -1118,41 +1050,33 @@ msgstr "" "zaporedja negativnih ali pozitivnih vrednosti. Vmesne vrednosti so bodisi" " kategorične bodisi časovne." -#, fuzzy msgid "A-Z" -msgstr "a - ž" +msgstr "A-Ž" -#, fuzzy msgid "AND" -msgstr "naključno" +msgstr "IN" -#, fuzzy msgid "API Key Created" -msgstr "ustvarjeno" +msgstr "Ključ API ustvarjen" -#, fuzzy msgid "API Keys" -msgstr "Privatni ključ" +msgstr "API ključi" -#, fuzzy msgid "API key created successfully" -msgstr "Poročilo je bilo ustvarjeno" +msgstr "Ključ API je bil uspešno ustvarjen" -#, fuzzy msgid "API key name is required" -msgstr "Zahtevano je ime" +msgstr "Zahtevano je ime ključa API" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, ja, sr, # sr_Latn] -#, fuzzy msgid "API key revoked successfully" msgstr "Ključ API je bil uspešno preklican" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, es, sr, # sr_Latn] -#, fuzzy msgid "API keys allow scoped programmatic access to Superset." -msgstr "Ključi API omogočajo omejeni programski dostop do Superset." +msgstr "Ključi API-ja omogočajo omejen programski dostop do Superset." msgid "APR" msgstr "APR" @@ -1163,13 +1087,11 @@ msgstr "AQE" msgid "AUG" msgstr "AVG" -#, fuzzy msgid "Aborted" -msgstr "Začetek" +msgstr "Prekinjeno" -#, fuzzy msgid "Aborting" -msgstr "Delam" +msgstr "Prekinitev" msgid "About" msgstr "O programu" @@ -1180,9 +1102,8 @@ msgstr "Dostop" msgid "Access token" msgstr "Žeton za dostop" -#, fuzzy msgid "Account" -msgstr "število" +msgstr "Račun" msgid "Action" msgstr "Aktivnost" @@ -1190,9 +1111,8 @@ msgstr "Aktivnost" msgid "Action Log" msgstr "Dnevnik aktivnosti" -#, fuzzy msgid "Action Logs" -msgstr "Dnevnik aktivnosti" +msgstr "Dnevniki dejanj" msgid "Actions" msgstr "Aktivnosti" @@ -1221,9 +1141,9 @@ msgstr "Prilagodljiva oblika" msgid "Add" msgstr "Dodaj" -#, fuzzy, python-format +#, python-format msgid "Add %s view(s)" -msgstr "Možnosti: %s" +msgstr "Dodaj poglede (%s)" msgid "Add BCC Recipients" msgstr "Dodaj skrite (BCC) prejemnike" @@ -1237,44 +1157,36 @@ msgstr "Dodaj CSS predlogo" msgid "Add Dashboard" msgstr "Dodaj nadzorno ploščo" -#, fuzzy msgid "Add Group" -msgstr "Dodaj pravilo" +msgstr "Dodaj skupino" -#, fuzzy msgid "Add Layer" -msgstr "Skrij sloj" +msgstr "Dodaj plast" msgid "Add Log" msgstr "Dodaj dnevnik" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, pt_BR, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "" "Add Query A and Query B identifiers to tooltips to help differentiate " "series" -msgstr "" -"Dodaj identifikatorje Poizvedbe A in Poizvedbe B v opise orodij za lažje " -"razlikovanje serij" +msgstr "Dodajte identifikatorja poizvedbe A in poizvedbe B v opise orodij, da boste lažje razlikovali nize" -#, fuzzy msgid "Add Role" -msgstr "Izključene vloge" +msgstr "Dodaj vlogo" msgid "Add Rule" msgstr "Dodaj pravilo" -#, fuzzy msgid "Add Semantic View" -msgstr "Dodaj element" +msgstr "Dodaj semantični pogled" msgid "Add Tag" msgstr "Dodaj oznako" -#, fuzzy msgid "Add User" -msgstr "Dodaj pravilo" +msgstr "Dodaj uporabnika" msgid "Add a Plugin" msgstr "Dodaj vtičnik" @@ -1291,7 +1203,6 @@ msgstr "Dodaj nov zavihek za SQL-poizvedbo" msgid "Add additional custom parameters" msgstr "Dodaj dodatne parametre po meri" -#, fuzzy msgid "Add alert" msgstr "Dodaj opozorilo" @@ -1318,22 +1229,14 @@ msgstr "" "Dodaj izračunan časovni stolpec v podatkovni set v oknu \"Uredi " "podatkovni vir\"" -#, fuzzy msgid "Add certification details for this dashboard" -msgstr "Podrobnosti certifikacije" +msgstr "Dodajte podrobnosti o certifikatu za to nadzorno ploščo" msgid "Add color for positive/negative change" msgstr "Dodaj barvo za pozitivno/negativno spremembo" -#, fuzzy msgid "Add colors to cell bars for +/- for all columns" -msgstr "dodajte barvo za graf v celici za +/-" - -msgid "" -"Add columns to filter by. When typing or pasting filter values, commas " -"will separate values into multiple entries. To include a comma within a " -"value, wrap it in double quotes: \"San Francisco, CA\"" -msgstr "" +msgstr "Dodajte barve vrsticam celic za +/- za vse stolpce" msgid "Add cross-filter" msgstr "Dodaj medsebojni filter" @@ -1350,20 +1253,17 @@ msgstr "Dodajte način dostave" msgid "Add description of your tag" msgstr "Dodajte opis vaše oznake" -#, fuzzy msgid "Add display control" -msgstr "Prikaži nastavitve" +msgstr "Dodaj kontrolnik prikaza" -#, fuzzy msgid "Add divider" -msgstr "Ločilnik" +msgstr "Dodajte delilnik" msgid "Add extra connection information." msgstr "Dodatne informacije o povezavi." -#, fuzzy msgid "Add filter" -msgstr "Dodaj filter" +msgstr "Dodajte filter" msgid "" "Add filter clauses to control the filter's source query,\n" @@ -1384,9 +1284,8 @@ msgstr "" "poizvedbe filtra\n" " ali pa omejiti nabor prikazanih vrednosti filtra." -#, fuzzy msgid "Add folder" -msgstr "Dodaj filter" +msgstr "Dodaj mapo" msgid "Add item" msgstr "Dodaj" @@ -1403,19 +1302,15 @@ msgstr "Dodaj novo pravilo za barvo" msgid "Add new formatter" msgstr "Dodaj novo pravilo" -#, fuzzy msgid "Add numbered column" -msgstr " za dodajanje izračunanih stolpcev" +msgstr "Dodajte oštevilčen stolpec" -#, fuzzy msgid "Add or edit display controls" -msgstr "Dodaj in uredi filtre" +msgstr "Dodajte ali uredite kontrolnike zaslona" -#, fuzzy msgid "Add or edit filters and controls" -msgstr "Dodaj in uredi filtre" +msgstr "Dodajte ali uredite filtre in kontrolnike" -#, fuzzy msgid "Add report" msgstr "Dodaj poročilo" @@ -1426,7 +1321,7 @@ msgid "Add required control values to save chart" msgstr "Dodaj potrebne parametre za shranjenje grafikona" msgid "Add service credentials" -msgstr "" +msgstr "Dodaj poverilnice storitve" msgid "Add sheet" msgstr "Dodaj preglednico" @@ -1440,29 +1335,27 @@ msgstr "Dodajte naslov grafikona" msgid "Add the name of the dashboard" msgstr "Dodajte ime nadzorne plošče" -#, fuzzy msgid "Add theme" -msgstr "Dodaj" +msgstr "Dodaj temo" msgid "Add to dashboard" msgstr "Dodaj na nadzorno ploščo" -#, fuzzy msgid "Add to tabs" -msgstr "Dodaj na nadzorno ploščo" +msgstr "Dodaj na zavihke" msgid "Added" msgstr "Dodano" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, ja, lv, mi, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy, python-format +#, python-format msgid "Added 1 new column to the virtual dataset" msgid_plural "Added %s new columns to the virtual dataset" -msgstr[0] "V virtualni nabor podatkov je bil dodan 1 nov stolpec" -msgstr[1] "V virtualni nabor podatkov sta bila dodana %s nova stolpca" -msgstr[2] "V virtualni nabor podatkov so bili dodani %s novi stolpci" -msgstr[3] "V virtualni nabor podatkov je bilo dodanih %s novih stolpcev" +msgstr[0] "V virtualni podatkovni niz je bil dodan %s nov stolpec" +msgstr[1] "V virtualni podatkovni niz sta bila dodana %s nova stolpca" +msgstr[2] "V virtualni podatkovni niz so bili dodani %s novi stolpci" +msgstr[3] "V virtualni podatkovni niz je bilo dodanih %s novih stolpcev" #, python-format msgid "Added to 1 dashboard" @@ -1504,10 +1397,10 @@ msgstr "" "negativna sprememba." msgid "Adhoc metric SQL expression is invalid" -msgstr "" +msgstr "Izraz SQL priložnostne mere ni veljaven" msgid "Adhoc metric aggregate is invalid" -msgstr "" +msgstr "Agregacija priložnostne mere ni veljavna" msgid "Adjust how this database will interact with SQL Lab." msgstr "Nastavite kako bo ta podatkovna baza delovala z SQL laboratorijem." @@ -1539,9 +1432,8 @@ msgstr "Napredna analitika - poprocesiranje" msgid "Advanced data type" msgstr "Napredni podatkovni tip" -#, fuzzy msgid "Advanced settings" -msgstr "Napredna analitika" +msgstr "Napredne nastavitve" msgid "Advanced-Analytics" msgstr "Napredna analitika" @@ -1557,13 +1449,10 @@ msgstr "Potem" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, pt_BR, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "" "After making the changes, copy the query and paste in the virtual dataset" " SQL snippet settings." -msgstr "" -"Po izvedbi sprememb kopirajte poizvedbo in jo prilepite v nastavitve " -"delčka SQL virtualnega nabora podatkov." +msgstr "Ko naredite spremembe, kopirajte poizvedbo in jo prilepite v nastavitve izrezka SQL navideznega nabora podatkov." msgid "Aggregate" msgstr "Agregacija" @@ -1581,6 +1470,9 @@ msgstr "" "Agregacijska funkcija za seznam točk v vsaki gruči, s katero se ustvari " "oznaka gruče." +msgid "Aggregate function to apply when pivoting and computing the total rows and columns" +msgstr "Agregacijska funkcija za vrtenje in izračun vseh vrstic in stolpcev" + msgid "" "Aggregates data within the boundary of grid cells and maps the aggregated" " values to a dynamic color scale" @@ -1591,9 +1483,11 @@ msgstr "" msgid "Aggregation" msgstr "Agregacija" -#, fuzzy msgid "Aggregation Method" -msgstr "Agregacija" +msgstr "Metoda združevanja" + +msgid "Aggregation function" +msgstr "Agregacijska funkcija" msgid "Alert" msgstr "Opozorilo" @@ -1670,16 +1564,15 @@ msgstr "Opozorila in poročila" msgid "Align +/-" msgstr "Poravnaj +/-" -#, fuzzy msgid "Align +/- for all columns" -msgstr "Prikaži vse stolpce" +msgstr "Poravnajte +/- za vse stolpce" msgid "All" msgstr "Vse" -#, fuzzy, python-format +#, python-format msgid "All %s hidden columns" -msgstr "Stolpci tabele" +msgstr "Vseh skritih stolpcev: %s" msgid "All Text" msgstr "Celotno besedilo" @@ -1690,9 +1583,8 @@ msgstr "Vsi grafikoni" msgid "All charts/global scoping" msgstr "Vsi grafikoni/globalni doseg" -#, fuzzy msgid "All dimensions" -msgstr "Dimenzije" +msgstr "Vse dimenzije" msgid "All filters" msgstr "Vsi filtri" @@ -1700,12 +1592,8 @@ msgstr "Vsi filtri" msgid "All panels" msgstr "Vsi paneli" -#, fuzzy msgid "All records" -msgstr "Surovi podatki" - -msgid "All time" -msgstr "" +msgstr "Vsi zapisi" msgid "Allow CREATE TABLE AS" msgstr "Dovoli CREATE TABLE AS" @@ -1732,9 +1620,8 @@ msgstr "Omogoči razvrščanje stolpcev" msgid "Allow creation of new tables based on queries" msgstr "Dovoli ustvarjanje novih tabel s poizvedbami" -#, fuzzy msgid "Allow creation of new values" -msgstr "Dovoli ustvarjanje novih pogledov s poizvedbami" +msgstr "Dovolite ustvarjanje novih vrednosti" msgid "Allow creation of new views based on queries" msgstr "Dovoli ustvarjanje novih pogledov s poizvedbami" @@ -1769,9 +1656,8 @@ msgstr "Dovoli raziskovanje te podatkovne baze" msgid "Allow this database to be queried in SQL Lab" msgstr "Dovoli poizvedbo na to podatkovno bazo v SQL laboratoriju" -#, fuzzy msgid "Allow users to select multiple values" -msgstr "Dovoli izbiro več vrednosti" +msgstr "Uporabnikom dovoli izbiro več vrednosti" msgid "Allowed Domains (comma separated)" msgstr "Dovoljene domene (ločeno z vejico)" @@ -1790,9 +1676,6 @@ msgstr "" "povprečje, mediano in notranja 2 kvartila. Brki na vsaki škatli " "prikazujejo minimum, maksimum, območje in zunanja dva kvartila." -msgid "Also overwrite all assets (charts, datasets and databases)" -msgstr "" - msgid "Altered" msgstr "Spremenjeno" @@ -1832,20 +1715,17 @@ msgstr "Pri shranjevanju podatkovnega seta je prišlo do napake" msgid "An error occurred when running alert query" msgstr "Pri zaganjanju poizvedbe za opozorilo je prišlo do napake" -#, fuzzy msgid "An error occurred while accessing the copy link." -msgstr "Pri dostopanju do vednosti je prišlo do težave." +msgstr "Pri dostopu do povezave za kopiranje je prišlo do napake." -#, fuzzy msgid "An error occurred while accessing the extension." -msgstr "Pri dostopanju do vednosti je prišlo do težave." +msgstr "Pri dostopu do razširitve je prišlo do napake." msgid "An error occurred while accessing the value." msgstr "Pri dostopanju do vednosti je prišlo do težave." -#, fuzzy msgid "An error occurred while adding semantic views" -msgstr "Pri nalaganju SQL je prišlo do napake" +msgstr "Med dodajanjem semantičnih pogledov je prišlo do napake" msgid "" "An error occurred while collapsing the table schema. Please contact your " @@ -1858,27 +1738,23 @@ msgstr "" msgid "An error occurred while creating %ss: %s" msgstr "Napaka pri ustvarjanju %s: %s" -#, fuzzy msgid "An error occurred while creating the copy link." -msgstr "Pri ustvarjanju vrednosti je prišlo do težave." +msgstr "Med ustvarjanjem povezave za kopiranje je prišlo do napake." msgid "An error occurred while creating the data source" msgstr "Pri ustvarjanju podatkovnega vira je prišlo do težave" -#, fuzzy msgid "An error occurred while creating the extension." -msgstr "Pri ustvarjanju vrednosti je prišlo do težave." +msgstr "Med ustvarjanjem razširitve je prišlo do napake." -#, fuzzy msgid "An error occurred while creating the semantic layer" -msgstr "Pri ustvarjanju vrednosti je prišlo do težave." +msgstr "Med ustvarjanjem semantične plasti je prišlo do napake" msgid "An error occurred while creating the value." msgstr "Pri ustvarjanju vrednosti je prišlo do težave." -#, fuzzy msgid "An error occurred while deleting the extension." -msgstr "Pri brisanju vrednosti je prišlo do napake." +msgstr "Med brisanjem razširitve je prišlo do napake." msgid "An error occurred while deleting the value." msgstr "Pri brisanju vrednosti je prišlo do napake." @@ -1890,25 +1766,25 @@ msgstr "" "Pri širitvi sheme tabele je prišlo do napake. Kontaktirajte " "administratorja." -#, fuzzy, python-format +#, python-format msgid "An error occurred while fetching %s" -msgstr "Napaka pri pridobivanju informacij za %s: %s" +msgstr "Pri pridobivanju %s je prišlo do napake" #, python-format msgid "An error occurred while fetching %s info: %s" msgstr "Napaka pri pridobivanju informacij za %s: %s" -#, fuzzy, python-format +#, python-format msgid "An error occurred while fetching %s related data" -msgstr "Napaka pri pridobivanju podatkov iz podatkovnega seta" +msgstr "Pri pridobivanju podatkov, povezanih z %s, je prišlo do napake" -#, fuzzy, python-format +#, python-format msgid "An error occurred while fetching %s values: %s" -msgstr "Pri pridobivanju vrednosti uporabnika je prišlo do napake: %s" +msgstr "Pri pridobivanju vrednosti %s je prišlo do napake: %s" -#, fuzzy, python-format +#, python-format msgid "An error occurred while fetching %s: %s" -msgstr "Napaka pri pridobivanju informacij za %s: %s" +msgstr "Pri pridobivanju %s je prišlo do napake: %s" #, python-format msgid "An error occurred while fetching %ss: %s" @@ -1917,13 +1793,11 @@ msgstr "Napaka pri pridobivanju informacij za %s: %s" msgid "An error occurred while fetching available CSS templates" msgstr "Pri pridobivanju CSS predlog je prišlo do napake" -#, fuzzy msgid "An error occurred while fetching available themes" -msgstr "Pri pridobivanju CSS predlog je prišlo do napake" +msgstr "Pri pridobivanju razpoložljivih tem je prišlo do napake" -#, fuzzy msgid "An error occurred while fetching available views" -msgstr "Pri pridobivanju CSS predlog je prišlo do napake" +msgstr "Pri pridobivanju razpoložljivih pogledov je prišlo do napake" #, python-format msgid "An error occurred while fetching chart editor values: %s" @@ -1933,13 +1807,12 @@ msgstr "Pri pridobivanju vrednosti urednikov grafikona je prišlo do napake: %s" msgid "An error occurred while fetching chart viewer values: %s" msgstr "Pri pridobivanju vrednosti gledalcev grafikona je prišlo do napake: %s" -#, fuzzy msgid "An error occurred while fetching connections" -msgstr "Pri pridobivanju imen funkcij je prišlo do napake." +msgstr "Pri pridobivanju povezav je prišlo do napake" -#, fuzzy, python-format +#, python-format msgid "An error occurred while fetching created by values: %s" -msgstr "Pri pridobivanju vrednosti shem je prišlo do napake: %s" +msgstr "Pri pridobivanju ustvarjenih vrednosti je prišlo do napake: %s" #, python-format msgid "An error occurred while fetching dashboard editor values: %s" @@ -1993,78 +1866,60 @@ msgstr "Pri pridobivanju imen funkcij je prišlo do napake." #, python-format msgid "An error occurred while fetching row level security subject values: %s" -msgstr "" +msgstr "Pri pridobivanju vrednosti subjekta varnosti na ravni vrstic je prišlo do napake: %s" #, python-format msgid "An error occurred while fetching schema values: %s" msgstr "Pri pridobivanju vrednosti shem je prišlo do napake: %s" -#, fuzzy msgid "An error occurred while fetching semantic layer types" -msgstr "Pri pridobivanju CSS predlog je prišlo do napake" +msgstr "Pri pridobivanju vrst semantične plasti je prišlo do napake" -#, fuzzy msgid "An error occurred while fetching semantic layers" -msgstr "Pri pridobivanju vrednosti shem je prišlo do napake: %s" +msgstr "Pri pridobivanju semantičnih plasti je prišlo do napake" msgid "An error occurred while fetching tab state" msgstr "Pri pridobivanju stanja zavihka je prišlo do napake" -#, fuzzy, python-format +#, python-format msgid "An error occurred while fetching table metadata for %s" -msgstr "Pri pridobivanju metapodatkov tabele je prišlo do napake" +msgstr "Pri pridobivanju metapodatkov tabele za %s je prišlo do napake" -#, fuzzy msgid "An error occurred while fetching the configuration schema" -msgstr "Pri pridobivanju imen funkcij je prišlo do napake." +msgstr "Pri pridobivanju konfiguracijske sheme je prišlo do napake" -#, fuzzy msgid "An error occurred while fetching the runtime schema" -msgstr "Pri pridobivanju imen funkcij je prišlo do napake." +msgstr "Pri pridobivanju sheme izvajalnega časa je prišlo do napake" -#, fuzzy msgid "An error occurred while fetching the semantic layer" -msgstr "Pri pridobivanju stanja zavihka je prišlo do napake" +msgstr "Pri pridobivanju semantične plasti je prišlo do napake" -#, fuzzy msgid "An error occurred while fetching the semantic view structure" -msgstr "Pri pridobivanju stanja zavihka je prišlo do napake" +msgstr "Pri pridobivanju semantične strukture pogleda je prišlo do napake" -#, fuzzy, python-format +#, python-format msgid "An error occurred while fetching theme datasource values: %s" -msgstr "" -"Pri pridobivanju vrednosti podatkovnega vira podatkovnega seta je prišlo " -"do napake: %s" +msgstr "Pri pridobivanju vrednosti vira podatkov teme je prišlo do napake: %s" -#, fuzzy msgid "An error occurred while fetching usage data" -msgstr "Pri pridobivanju metapodatkov tabele je prišlo do napake" +msgstr "Pri pridobivanju podatkov o uporabi je prišlo do napake" #, python-format msgid "An error occurred while fetching user values: %s" msgstr "Pri pridobivanju vrednosti uporabnika je prišlo do napake: %s" -#, fuzzy msgid "An error occurred while formatting SQL" -msgstr "Pri nalaganju SQL je prišlo do napake" - -msgid "" -"An error occurred while generating the file. Please try again, or contact" -" your administrator if the problem persists." -msgstr "" +msgstr "Med formatiranjem SQL je prišlo do napake" #, python-format msgid "An error occurred while importing %s: %s" msgstr "Napaka pri uvažanju %s: %s" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ja] -#, fuzzy msgid "" "An error occurred while loading SQL Lab. This may be caused by a " "corrupted query state." -msgstr "" -"Med nalaganjem SQL Lab je prišlo do napake. To je morda posledica " -"poškodovanega stanja poizvedbe." +msgstr "Med nalaganjem SQL Lab je prišlo do napake. To je lahko posledica poškodovanega stanja poizvedbe." msgid "An error occurred while loading dashboard information." msgstr "Prišlo je do napake pri pridobivanju informacij o nadzorni plošči." @@ -2072,9 +1927,8 @@ msgstr "Prišlo je do napake pri pridobivanju informacij o nadzorni plošči." msgid "An error occurred while loading the SQL" msgstr "Pri nalaganju SQL je prišlo do napake" -#, fuzzy msgid "An error occurred while overwriting the dataset" -msgstr "Pri ustvarjanju podatkovnega vira je prišlo do težave" +msgstr "Med prepisovanjem nabora podatkov je prišlo do napake" msgid "An error occurred while parsing the key." msgstr "Pri branju ključa je prišlo do težave." @@ -2082,9 +1936,8 @@ msgstr "Pri branju ključa je prišlo do težave." msgid "An error occurred while pruning logs " msgstr "Pri krajšanju dnevnikov je prišlo do napake " -#, fuzzy msgid "An error occurred while refreshing the configuration schema" -msgstr "Pri prikazovanju vizualizacije je prišlo do napake: %s" +msgstr "Med osveževanjem konfiguracijske sheme je prišlo do napake" msgid "An error occurred while removing query. Please contact your administrator." msgstr "" @@ -2102,9 +1955,8 @@ msgstr "" msgid "An error occurred while rendering the visualization: %s" msgstr "Pri prikazovanju vizualizacije je prišlo do napake: %s" -#, fuzzy msgid "An error occurred while saving the semantic view" -msgstr "Pri nalaganju SQL je prišlo do napake" +msgstr "Med shranjevanjem semantičnega pogleda je prišlo do napake" msgid "An error occurred while starring this chart" msgstr "Pri ocenjevanju grafikona je prišlo do napake" @@ -2117,34 +1969,28 @@ msgstr "" "Pri shranjevanju vaše poizvedbe v sistem je prišlo do napake. Da ne " "izgubite sprememb, shranite poizvedbo z gumbom \"Shrani poizvedbo\"." -#, fuzzy, python-format +#, python-format msgid "An error occurred while syncing permissions for %s: %s" -msgstr "Napaka pri pridobivanju informacij za %s: %s" +msgstr "Med sinhronizacijo dovoljenj za %s je prišlo do napake: %s" msgid "An error occurred while triggering the report" -msgstr "" +msgstr "Pri sprožitvi poročila je prišlo do napake" -#, fuzzy msgid "An error occurred while updating the extension." -msgstr "Pri posodabljanju vrednosti je prišlo do težave." +msgstr "Med posodabljanjem razširitve je prišlo do napake." -#, fuzzy msgid "An error occurred while updating the semantic layer" -msgstr "Pri posodabljanju vrednosti je prišlo do težave." +msgstr "Med posodabljanjem semantične plasti je prišlo do napake" msgid "An error occurred while updating the value." msgstr "Pri posodabljanju vrednosti je prišlo do težave." -#, fuzzy msgid "An error occurred while upserting the extension." -msgstr "Pri posodabljanju/vstavljanju vrednosti je prišlo do težave." +msgstr "Med vstavljanjem razširitve je prišlo do napake." msgid "An error occurred while upserting the value." msgstr "Pri posodabljanju/vstavljanju vrednosti je prišlo do težave." -msgid "An export for this dashboard is already in progress." -msgstr "" - msgid "An unexpected error occurred" msgstr "Prišlo je do nepričakovane napake" @@ -2154,7 +2000,7 @@ msgstr "Sidraj na" msgid "" "Angle at which the first slice begins, in degrees. 90° starts at the top," " 0°/360° at the right, 270° at the bottom, and 180° at the left." -msgstr "" +msgstr "Kot v stopinjah, pri katerem se začne prvi izsek. 90° pomeni začetek na vrhu, 0°/360° na desni, 270° na dnu in 180° na levi." msgid "Angle at which to end progress axis" msgstr "Kot, pri katerem se konča številčnica" @@ -2267,7 +2113,6 @@ msgstr "Oznak ni mogoče izbrisati." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Ant Design Theme Editor" msgstr "Urejevalnik tem Ant Design" @@ -2286,7 +2131,6 @@ msgstr "" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "" "Any dashboards using these themes will be automatically dissociated from " "them." @@ -2296,7 +2140,6 @@ msgstr "" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Any dashboards using this theme will be automatically dissociated from it." msgstr "Vse nadzorne plošče, ki uporabljajo to temo, bodo samodejno ločene od nje." @@ -2337,25 +2180,20 @@ msgstr "" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "" "Applies only when \"Cell bars\" formatting is selected: the background of" " the histogram columns is displayed if the \"Show cell bars\" flag is " "enabled." -msgstr "" -"Velja samo, ko je izbrano oblikovanje »Celični trakovi«: ozadje stolpcev " -"histograma se prikaže, če je omogočena možnost »Prikaži celične trakove«." +msgstr "Velja le, če je izbrano oblikovanje »Celični stolpci«: ozadje stolpcev histograma je prikazano, če je omogočena zastavica »Prikaži celične stolpce«." msgid "Apply" msgstr "Uporabi" -#, fuzzy msgid "Apply Filter" -msgstr "Uporabi filtre" +msgstr "Uporabi filter" -#, fuzzy msgid "Apply another dashboard filter" -msgstr "Filtra ni mogoče naložiti" +msgstr "Uporabite drug filter nadzorne plošče" msgid "Apply conditional color formatting to metric" msgstr "Za mere uporabi pogojno oblikovanje z barvami" @@ -2368,13 +2206,10 @@ msgstr "Za numerične stolpce uporabi pogojno oblikovanje z barvami" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "" "Apply custom CSS to the dashboard. Use class names or element selectors " "to target specific components." -msgstr "" -"Nanesite lastni CSS na nadzorno ploščo. Uporabite imena razredov ali " -"selektorje elementov za ciljanje določenih komponent." +msgstr "Uporabite CSS po meri na nadzorni plošči. Za ciljanje na določene komponente uporabite imena razredov ali izbirnike elementov." msgid "Apply filters" msgstr "Uporabi filtre" @@ -2388,41 +2223,6 @@ msgstr "April" msgid "Arc" msgstr "Lok" -msgid "Archive" -msgstr "" - -#, python-format -msgid "Archive %(name)s?" -msgstr "" - -#, python-format -msgid "Archive selected %s?" -msgstr "" - -msgid "Archive selected charts?" -msgstr "" - -msgid "Archive selected dashboards?" -msgstr "" - -msgid "Archived" -msgstr "" - -#, python-format -msgid "Archived %s item(s)" -msgstr "" - -#, python-format -msgid "Archived %s item(s); permanently deleted %s semantic view(s)" -msgstr "" - -msgid "Archived by" -msgstr "" - -#, python-format -msgid "Archived: %s" -msgstr "" - msgid "Are you sure you intend to overwrite the following values?" msgstr "Ali ste prepričani, da želite prepisati naslednje vrednosti?" @@ -2449,19 +2249,17 @@ msgstr "Ali ste prepričani, da želite izbrisati izbrane grafikone?" msgid "Are you sure you want to delete the selected dashboards?" msgstr "Ali ste prepričani, da želite izbrisati izbrane nadzorne plošče?" -#, fuzzy msgid "Are you sure you want to delete the selected groups?" -msgstr "Ali ste prepričani, da želite izbrisati izbrana pravila?" +msgstr "Ali ste prepričani, da želite izbrisati izbrane skupine?" msgid "Are you sure you want to delete the selected layers?" msgstr "Ali ste prepričani, da želite izbrisati izbrane sloje?" msgid "Are you sure you want to delete the selected queries?" -msgstr "" +msgstr "Ali ste prepričani, da želite izbrisati izbrane poizvedbe?" -#, fuzzy msgid "Are you sure you want to delete the selected roles?" -msgstr "Ali ste prepričani, da želite izbrisati izbrana pravila?" +msgstr "Ali ste prepričani, da želite izbrisati izbrane vloge?" msgid "Are you sure you want to delete the selected rules?" msgstr "Ali ste prepričani, da želite izbrisati izbrana pravila?" @@ -2472,65 +2270,52 @@ msgstr "Ali ste prepričani, da želite izbrisati izbrane oznake?" msgid "Are you sure you want to delete the selected templates?" msgstr "Ali ste prepričani, da želite izbrisati izbrane predloge?" -#, fuzzy msgid "Are you sure you want to delete the selected themes?" -msgstr "Ali ste prepričani, da želite izbrisati izbrane predloge?" +msgstr "Ali ste prepričani, da želite izbrisati izbrane teme?" -#, fuzzy msgid "Are you sure you want to delete the selected users?" -msgstr "Ali ste prepričani, da želite izbrisati izbrane poizvedbe?" +msgstr "Ali ste prepričani, da želite izbrisati izbrane uporabnike?" msgid "Are you sure you want to overwrite this dataset?" msgstr "Ali ste prepričani, da želite prepisati podatkovni set?" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, pt_BR, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "" "Are you sure you want to remove the system dark theme? The application " "will fall back to the configuration file dark theme." -msgstr "" -"Ste prepričani, da želite odstraniti sistemsko temno temo? Aplikacija se " -"bo vrnila na temno temo iz konfiguracijske datoteke." +msgstr "Ali ste prepričani, da želite odstraniti temno temo sistema? Aplikacija se bo vrnila na temno temo konfiguracijske datoteke." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, pt_BR, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "" "Are you sure you want to remove the system default theme? The application" " will fall back to the configuration file default." -msgstr "" -"Ste prepričani, da želite odstraniti privzeto sistemsko temo? Aplikacija " -"se bo vrnila na privzeto nastavitev iz konfiguracijske datoteke." +msgstr "Ali ste prepričani, da želite odstraniti sistemsko privzeto temo? Aplikacija se bo vrnila na privzeto konfiguracijsko datoteko." -#, fuzzy msgid "" "Are you sure you want to revoke this API key? This action cannot be " "undone." -msgstr "Ali ste prepričani, da želite izbrisati izbrane oznake?" +msgstr "Ali ste prepričani, da želite preklicati ta ključ API? Tega dejanja ni mogoče razveljaviti." msgid "Are you sure you want to save and apply changes?" msgstr "Ali resnično želite shraniti in uporabiti spremembe?" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, pt_BR, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy, python-format +#, python-format msgid "" "Are you sure you want to set \"%s\" as the system dark theme? This will " "apply to all users who haven't set a personal preference." -msgstr "" -"Ste prepričani, da želite nastaviti \"%s\" kot sistemsko temno temo? To " -"bo veljalo za vse uporabnike, ki niso nastavili osebnih nastavitev." +msgstr "Ali ste prepričani, da želite nastaviti » %s « kot temno temo sistema? To bo veljalo za vse uporabnike, ki niso nastavili osebnih nastavitev." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, pt_BR, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy, python-format +#, python-format msgid "" "Are you sure you want to set \"%s\" as the system default theme? This " "will apply to all users who haven't set a personal preference." -msgstr "" -"Ste prepričani, da želite nastaviti \"%s\" kot privzeto sistemsko temo? " -"To bo veljalo za vse uporabnike, ki niso nastavili osebnih nastavitev." +msgstr "Ali ste prepričani, da želite nastaviti \" %s \" kot privzeto temo sistema? To bo veljalo za vse uporabnike, ki niso nastavili osebnih nastavitev." msgid "Area" msgstr "Ploščina" @@ -2565,16 +2350,14 @@ msgstr "Pomoč" msgid "Asynchronous query execution" msgstr "Asinhroni zagon poizvedb" -#, fuzzy msgid "Attribution" -msgstr "Porazdelitev" +msgstr "Pripisovanje" msgid "August" msgstr "Avgust" -#, fuzzy msgid "Authorization Request URI" -msgstr "Potrebna je avtorizacija" +msgstr "URI zahteve za avtorizacijo" msgid "Authorization needed" msgstr "Potrebna je avtorizacija" @@ -2587,25 +2370,22 @@ msgstr "Samodejna povečava" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy, python-format +#, python-format msgid "Auto refresh paused (set to %s seconds)" msgstr "Samodejno osveževanje je zaustavljeno (nastavljeno na %s sekund)" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy, python-format +#, python-format msgid "Auto refresh paused - tab inactive (set to %s seconds)" -msgstr "" -"Samodejno osveževanje je zaustavljeno – zavihek neaktiven (nastavljeno na" -" %s sekund)" +msgstr "Samodejno osveževanje je zaustavljeno – zavihek je neaktiven (nastavljen na %s sekund)" -#, fuzzy, python-format +#, python-format msgid "Auto refresh set to %s seconds" -msgstr "Nastavitve datoteke" +msgstr "Samodejno osveževanje je nastavljeno na %s sekund" -#, fuzzy msgid "Auto-detect" -msgstr "Samodokončaj" +msgstr "Samodejno zaznaj" msgid "Autocomplete" msgstr "Samodokončaj" @@ -2618,35 +2398,28 @@ msgstr "Predikat za samodokončanje poizvedb" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Automatically adjust column width based on available space" -msgstr "Samodejno prilagajanje širine stolpca glede na razpoložljiv prostor" +msgstr "Samodejno prilagodi širino stolpca glede na razpoložljiv prostor" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Automatically adjust column width based on content" -msgstr "Samodejno prilagajanje širine stolpca glede na vsebino" +msgstr "Samodejno prilagodi širino stolpca glede na vsebino" -#, fuzzy msgid "Automatically sync columns" -msgstr "Prilagodi stolpce" +msgstr "Samodejno sinhroniziraj stolpce" -#, fuzzy msgid "Autosize All Columns" -msgstr "Prilagodi stolpce" +msgstr "Samodejno določi velikost vseh stolpcev" -#, fuzzy msgid "Autosize Column" -msgstr "Prilagodi stolpce" +msgstr "Samodejna velikost stolpca" -#, fuzzy msgid "Autosize This Column" -msgstr "Prilagodi stolpce" +msgstr "Samodejno določi velikost tega stolpca" -#, fuzzy msgid "Autosize all columns" -msgstr "Prilagodi stolpce" +msgstr "Samodejno določi velikost vseh stolpcev" msgid "Available sorting modes:" msgstr "Razpoložljivi načini razvrščanja:" @@ -2657,9 +2430,8 @@ msgstr "Povprečje" msgid "Average value" msgstr "Povprečna vrednost" -#, fuzzy msgid "Awaiting filter selection" -msgstr "Invertiraj izbiro" +msgstr "Čakanje na izbiro filtra" msgid "Axis" msgstr "Os" @@ -2700,9 +2472,8 @@ msgstr "Nazaj na vse" msgid "Backend" msgstr "Zaledni sistem" -#, fuzzy msgid "Background Color" -msgstr "ozadje" +msgstr "Barva ozadja" msgid "Backward values" msgstr "Prejšnje vrednosti" @@ -2731,39 +2502,31 @@ msgstr "Orientacija stolpcev" msgid "Base" msgstr "Osnoven" -#, fuzzy msgid "Base exponent" -msgstr "Vrata podatkovne baze" +msgstr "Osnovni eksponent" -#, fuzzy msgid "Base height" -msgstr "Višina grafikona" +msgstr "Osnovna višina" -#, fuzzy msgid "Base layer map style. Accepts a MapLibre-compatible style URL." -msgstr "Slog osnovnega zemljevida. Glej dokumentacijo Mapbox: %s" +msgstr "Slog zemljevida osnovne plasti. Sprejema slog URL, združljiv z MapLibre." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "Base layer map style. Accepts a Mapbox style URL (mapbox://styles/...)." -msgstr "" -"Slog karte osnovnega sloja. Sprejema URL sloga Mapbox " -"(mapbox://styles/...)." +msgstr "Slog zemljevida osnovne plasti. Sprejema URL sloga Mapbox (mapbox://styles/...)." -#, fuzzy, python-format +#, python-format msgid "Base layer map style. See MapLibre documentation: %s" -msgstr "Slog osnovnega zemljevida. Glej dokumentacijo Mapbox: %s" +msgstr "Slog zemljevida osnovne plasti. Oglejte si dokumentacijo MapLibre: %s" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fr, ja, lv, mi, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Base slope" -msgstr "Osnovni naklon" +msgstr "Osnovni nagib" -#, fuzzy msgid "Base width" -msgstr "Debelina črte" +msgstr "Osnovna širina" msgid "Based on a metric" msgstr "Osnovan na meri" @@ -2778,11 +2541,10 @@ msgid "Basic" msgstr "Osnovno" msgid "Basic conditional formatting" -msgstr "osnovno pogojno oblikovanje" +msgstr "Osnovno pogojno oblikovanje" -#, fuzzy msgid "Basic information about the chart" -msgstr "Osnovne informacije" +msgstr "Osnovni podatki o grafikonu" #, python-format msgid "Batch editing %d filters:" @@ -2806,23 +2568,20 @@ msgstr "Velika številka s trendno krivuljo" msgid "Bins" msgstr "Razdelki" -#, fuzzy msgid "Blanks" -msgstr "BOOLEAN" +msgstr "Praznine" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy, python-format +#, python-format msgid "Block %(block_num)s out of %(block_count)s" msgstr "Blok %(block_num)s od %(block_count)s" -#, fuzzy msgid "Border color" -msgstr "Barve nizov" +msgstr "Barva obrobe" -#, fuzzy msgid "Border width" -msgstr "Debelina povezave" +msgstr "Širina obrobe" msgid "Bottom" msgstr "Spodaj" @@ -2842,9 +2601,8 @@ msgstr "Spodaj desno" msgid "Bottom to Top" msgstr "Od dna proti vrhu" -#, fuzzy msgid "Bounds" -msgstr "Meje Y-osi" +msgstr "Meje" msgid "" "Bounds for numerical X axis. Not applicable for temporal or categorical " @@ -2858,15 +2616,13 @@ msgstr "" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "" "Bounds for the X-axis. Selected time merges with min/max date of the " "data. When left empty, bounds dynamically defined based on the min/max of" " the data." msgstr "" -"Meje za os X. Izbrani čas se združi z minimalnim/maksimalnim datumom " -"podatkov. Kadar je prazno, so meje dinamično določene na podlagi " -"minimuma/maksimuma podatkov." +"Meje za os X. Izbrani čas se združi z najmanjšim/največjim datumom podatkov. Ko ostane prazno, so meje dinamično določene na podlagi najmanjše/največje " +"vrednosti podatkov." msgid "" "Bounds for the Y-axis. When left empty, the bounds are dynamically " @@ -2915,9 +2671,8 @@ msgstr "Box Plot" msgid "Breakdowns" msgstr "Razčlenitev" -#, fuzzy msgid "Breakpoint Metric" -msgstr "Osnovan na meri" +msgstr "Mera prelomne točke" msgid "" "Breaks down the series by the category specified in this control.\n" @@ -3016,15 +2771,13 @@ msgstr "CSS slogi uporabljeni za grafikon" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "" "CSS styles may be removed by server-side HTML sanitization. If styles are" " not applying, ask your Superset administrator to adjust the HTML " "sanitization configuration." msgstr "" -"Slogi CSS so morda odstranjeni s strežniško sanitizacijo HTML. Če se " -"slogi ne uveljavljajo, prosite skrbnika Superset, da prilagodi " -"konfiguracijo sanitizacije HTML." +"Slogi CSS se lahko odstranijo s čiščenjem HTML na strani strežnika. Če slogi ne veljajo, prosite skrbnika Superseta, da prilagodi konfiguracijo saniranja " +"HTML." msgid "CSS template" msgstr "CSS predloga" @@ -3038,17 +2791,14 @@ msgstr "CSS predloge" msgid "CSS templates could not be deleted." msgstr "CSS predlog ni mogoče izbrisati." -#, fuzzy msgid "CSV Export" -msgstr "Izvoz" +msgstr "Izvoz CSV" -#, fuzzy msgid "CSV file downloaded successfully" -msgstr "Nadzorna plošča je bila uspešno shranjena." +msgstr "Datoteka CSV je bila uspešno prenesena" -#, fuzzy msgid "CSV upload" -msgstr "Nalaganje datoteke" +msgstr "nalaganje CSV" msgid "CTAS & CVAS SCHEMA" msgstr "CTAS & CVAS SHEMA" @@ -3082,7 +2832,6 @@ msgstr "Trajanje predpomnilnika (sekunde)" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "" "Cache data separately for each user based on their data access roles and " "permissions. When disabled, a single cache will be used for all users." @@ -3094,9 +2843,8 @@ msgstr "" msgid "Cache timeout" msgstr "Časovna omejitev predpomnilnika" -#, fuzzy msgid "Cache timeout must be a number" -msgstr "Periode morajo biti celo število" +msgstr "Časovna omejitev predpomnilnika mora biti število" msgid "Cached" msgstr "Predpomnjeno" @@ -3139,18 +2887,16 @@ msgstr "Dovoli izbiro več vrednosti" msgid "Cancel" msgstr "Prekliči" -#, fuzzy msgid "Cancel Task" -msgstr "Prekliči" +msgstr "Prekliči nalogo" msgid "Cancel query on window unload event" msgstr "Prekini poizvedbo pri dogodku zaprtja okna (window unload event)" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, es, sr, # sr_Latn] -#, fuzzy msgid "Cancellation not available due to missing abort handler" -msgstr "Preklic ni na voljo zaradi manjkajočega upravljalnika prekinitve" +msgstr "Preklic ni na voljo zaradi manjkajočega upravljalnika za prekinitev" msgid "Cannot access the query" msgstr "Dostop do poizvedbe ni mogoč" @@ -3159,44 +2905,33 @@ msgid "Cannot delete a database that has datasets attached" msgstr "Podatkovne baze s povezanimi podatkovnimi viri ni mogoče izbrisati" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ja] -#, fuzzy msgid "" "Cannot delete a database whose only remaining datasets are soft-deleted. " "Restore them (POST /api/v1/dataset//restore) and delete them " "permanently once a purge capability ships, or remove the underlying rows " "out-of-band, before deleting the database." msgstr "" -"Ni mogoče izbrisati podatkovne baze, katere edine preostale podatkovne " -"zbirke so mehko izbrisane. Obnovite jih (POST " -"/api/v1/dataset//restore) in jih trajno izbrišite, ko bo na voljo " -"funkcija čiščenja, ali odstranite temeljne vrstice zunaj pasu, preden " -"izbrišete podatkovno bazo." +"Ni mogoče izbrisati zbirke podatkov, katere edini preostali nizi podatkov so mehko izbrisani. Obnovite jih (POST /api/v1/dataset/ /restore) in jih " +"trajno izbrišite, ko je poslana zmožnost čiščenja, ali zunajpasovno odstranite osnovne vrstice, preden izbrišete bazo podatkov." -#, fuzzy msgid "Cannot delete system themes" -msgstr "Dostop do poizvedbe ni mogoč" +msgstr "Sistemskih tem ni mogoče izbrisati" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Cannot delete theme that is set as system default or dark theme" -msgstr "" -"Ni mogoče izbrisati teme, ki je nastavljena kot privzeta sistemska ali " -"temna tema" +msgstr "Teme, ki je nastavljena kot sistemska privzeta ali temna tema, ni mogoče izbrisati" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Cannot delete theme that is set as system default or dark theme." -msgstr "" -"Ni mogoče izbrisati teme, ki je nastavljena kot privzeta sistemska ali " -"temna tema." +msgstr "Teme, ki je nastavljena kot sistemska privzeta ali temna tema, ni mogoče izbrisati." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fr, ja, lv, mi, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy, python-format +#, python-format msgid "Cannot find the table (%s) metadata." -msgstr "Ni mogoče najti metapodatkov tabele (%s)." +msgstr "Metapodatkov tabele ( %s ) ni mogoče najti." msgid "Cannot have multiple credentials for the SSH Tunnel" msgstr "Za SSH-tunel ne morete imeti več prijavnih podatkov" @@ -3206,27 +2941,23 @@ msgstr "Filtra ni mogoče naložiti" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Cannot modify system themes." msgstr "Sistemskih tem ni mogoče spreminjati." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Cannot nest folders in default folders" -msgstr "Ni mogoče gnezditi map v privzetih mapah" +msgstr "Map ni mogoče ugnezditi v privzetih mapah" #, python-format msgid "Cannot parse time string [%(human_readable)s]" msgstr "Ni mogoče razčleniti časovnega izraza [%(human_readable)s]" -#, fuzzy msgid "Captcha" -msgstr "Ustvarite grafikon" +msgstr "Captcha" -#, fuzzy msgid "Cartodiagram" -msgstr "Grafikon s pravokotniki" +msgstr "Kartodiagram" msgid "Catalog" msgstr "Katalog" @@ -3237,9 +2968,8 @@ msgstr "Kategorični" msgid "Categorical Color" msgstr "Kategorična barva" -#, fuzzy msgid "Categorical palette" -msgstr "Kategorični" +msgstr "Kategorična paleta" msgid "Categories to group by on the x-axis." msgstr "Kategorije za združevanje po x-osi." @@ -3279,16 +3009,14 @@ msgstr "Vsebina celice" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Cell layout & styling" -msgstr "Postavitev in slog celice" +msgstr "Postavitev in stil celice" msgid "Cell limit" msgstr "Omejitev števila celic" -#, fuzzy msgid "Cell title template" -msgstr "Izbriši predlogo" +msgstr "Predloga naslova celice" msgid "Centroid (Longitude and Latitude): " msgstr "Centroid (zemljepisna dolžina in širina): " @@ -3296,9 +3024,8 @@ msgstr "Centroid (zemljepisna dolžina in širina): " msgid "Certification" msgstr "Certifikacija" -#, fuzzy msgid "Certification and additional settings" -msgstr "Dodatne nastavitve." +msgstr "Certificiranje in dodatne nastavitve" msgid "Certification details" msgstr "Podrobnosti certifikacije" @@ -3325,18 +3052,16 @@ msgstr "Spremeni vrstni red vrstic." msgid "Changed by" msgstr "Spremenil" -#, fuzzy msgid "Changed on" -msgstr "sprememba" +msgstr "Spremenjeno" msgid "Changes saved." msgstr "Spremembe shranjene." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Changes the sort value of the items in the legend only" -msgstr "Spremeni vrednost razvrščanja samo za elemente v legendi" +msgstr "Spremeni samo vrednost razvrščanja elementov v legendi" msgid "Changing one or more of these dashboards is forbidden" msgstr "Spreminjanje teh nadzornih plošč ni dovoljeno" @@ -3376,17 +3101,14 @@ msgstr "Spreminjanje tega podatkovnega vira ni dovoljeno" msgid "Changing this report is forbidden" msgstr "Spreminjanje tega poročila ni dovoljeno" -#, fuzzy msgid "Changing this semantic layer is forbidden" -msgstr "Spreminjanje tega grafikona ni dovoljeno" +msgstr "Spreminjanje te semantične plasti ni dovoljeno" -#, fuzzy msgid "Changing this semantic view is forbidden" -msgstr "Spreminjanje tega podatkovnega seta ni dovoljeno" +msgstr "Spreminjanje tega semantičnega pogleda ni dovoljeno" -#, fuzzy msgid "Changing this task is forbidden" -msgstr "Spreminjanje tega podatkovnega seta ni dovoljeno" +msgstr "Spreminjanje te naloge je prepovedano" msgid "Character to interpret as decimal point" msgstr "Znak, ki bo prepoznan kot decimalno ločilo" @@ -3396,9 +3118,9 @@ msgstr "Grafikon" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy, python-format +#, python-format msgid "Chart %(chart_id)s is not on dashboard %(dashboard_id)s" -msgstr "Grafikon %(chart_id)s ni na nadzorni plošči %(dashboard_id)s" +msgstr "Grafikona %(chart_id)s ni na nadzorni plošči %(dashboard_id)s" #, python-format msgid "Chart %(id)s not found" @@ -3431,9 +3153,8 @@ msgstr "Podatkovni vir grafikona" msgid "Chart Title" msgstr "Naslov grafikona" -#, fuzzy msgid "Chart Type" -msgstr "Naslov grafikona" +msgstr "Vrsta grafikona" #, python-format msgid "Chart [%s] has been overwritten" @@ -3457,7 +3178,6 @@ msgid "Chart could not be created." msgstr "Grafikona ni mogoče ustvariti." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ja] -#, fuzzy msgid "Chart could not be restored." msgstr "Grafikona ni bilo mogoče obnoviti." @@ -3466,13 +3186,11 @@ msgstr "Grafikona ni mogoče posodobiti." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Chart customization to control deck.gl layer visibility" -msgstr "Prilagajanje grafikona za nadzor vidnosti sloja deck.gl" +msgstr "Prilagoditev grafikona za nadzor vidnosti sloja deck.gl" -#, fuzzy msgid "Chart customization value is required" -msgstr "Vrednost filtra je obvezna" +msgstr "Potrebna je vrednost prilagajanja grafikona" msgid "Chart does not exist" msgstr "Grafikon ne obstaja" @@ -3492,9 +3210,8 @@ msgstr "Grafikon uvožen" msgid "Chart name" msgstr "Ime grafikona" -#, fuzzy msgid "Chart name is required" -msgstr "Zahtevano je ime" +msgstr "Ime grafikona je obvezno" msgid "Chart not found" msgstr "Grafikon ni najden" @@ -3502,36 +3219,29 @@ msgstr "Grafikon ni najden" msgid "Chart options" msgstr "Možnosti grafikona" -msgid "Chart orientation" -msgstr "" - msgid "Chart parameters are invalid." msgstr "Parametri grafikona so neveljavni." -#, fuzzy msgid "Chart properties" -msgstr "Uredi lastnosti grafikona" +msgstr "Lastnosti grafikona" msgid "Chart properties updated" msgstr "Lastnosti grafikona posodobljene" -#, fuzzy msgid "Chart size" -msgstr "grafikoni" +msgstr "Velikost grafikona" msgid "Chart title" msgstr "Naslov grafikona" -#, fuzzy msgid "Chart type" -msgstr "Naslov grafikona" +msgstr "Vrsta grafikona" msgid "Chart type requires a dataset" msgstr "Grafikon zahteva podatkovni set" -#, fuzzy msgid "Chart was saved but could not be added to the selected tab." -msgstr "Grafikonov ni mogoče izbrisati." +msgstr "Grafikon je bil shranjen, vendar ga ni bilo mogoče dodati na izbrani zavihek." msgid "Chart width" msgstr "Širina grafikona" @@ -3542,9 +3252,8 @@ msgstr "Grafikoni" msgid "Charts could not be deleted." msgstr "Grafikonov ni mogoče izbrisati." -#, fuzzy msgid "Charts per row" -msgstr "Vrstica z glavo" +msgstr "Grafikoni na vrstico" msgid "Check for sorting ascending" msgstr "Označi za naraščajoče razvrščanje" @@ -3577,13 +3286,12 @@ msgstr "Izbira [Oznaka] mora biti prisotna v [Združevanje po]" msgid "Choice of [Point Radius] must be present in [Group By]" msgstr "Izbran [Radij točk] mora biti prisoten v [Združevanje po]" -#, fuzzy, python-format +#, python-format msgid "Choose a %s" -msgstr "Izberite izvor" +msgstr "Izberite %s" -#, fuzzy msgid "Choose a chart for displaying on the map" -msgstr "Izberite grafikon ali nadzorno ploščo, ne obojega" +msgstr "Izberite grafikon za prikaz na zemljevidu" msgid "Choose a chart or dashboard not both" msgstr "Izberite grafikon ali nadzorno ploščo, ne obojega" @@ -3620,39 +3328,32 @@ msgstr "Izberite stolpce za branje" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "" "Choose from existing dashboard filters and select a value to refine your " "report results." -msgstr "" -"Izberite med obstoječimi filtri nadzorne plošče in izberite vrednost za " -"natančnejšo opredelitev rezultatov poročila." +msgstr "Izberite med obstoječimi filtri nadzorne plošče in izberite vrednost, da izboljšate rezultate poročila." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Choose how many X-Axis labels to show" -msgstr "Izberite, koliko oznak osi X prikazati" +msgstr "Izberite, koliko oznak osi X želite prikazati" msgid "Choose index column" msgstr "Izberite Indeksni stolpec" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "" "Choose layers to hide from all deck.gl Multiple Layer charts in this " "dashboard." -msgstr "" -"Izberite sloje, ki jih želite skriti iz vseh večslojnih grafikonov " -"deck.gl na tej nadzorni plošči." +msgstr "Izberite plasti, ki jih želite skriti pred vsemi večplastnimi grafikoni deck.gl na tej nadzorni plošči." msgid "Choose notification method and recipients." msgstr "Dodajte način obveščanja in prejemnike." -#, fuzzy, python-format +#, python-format msgid "Choose numbers between %(min)s and %(max)s" -msgstr "Širina zaslonske slike mora biti med %(min)spx and %(max)spx" +msgstr "Izberite številke med %(min)s in %(max)s" msgid "Choose one of the available databases from the panel on the left." msgstr "Izberite eno od razpoložljivih podatkovnih baz v panelu na levi." @@ -3689,9 +3390,8 @@ msgstr "" "Izberite, če želite barvanje držav glede na mero ali kategorično določeno" " barvno paleto" -#, fuzzy msgid "Choose..." -msgstr "Izberite podatkovno bazo..." +msgstr "Izberite..." msgid "Chord Diagram" msgstr "Tetivni grafikon" @@ -3725,13 +3425,12 @@ msgstr "Dodatni WHERE pogoj" msgid "Clear" msgstr "Počisti" -#, fuzzy, python-format +#, python-format msgid "Clear %s filter" -msgstr "počisti vse filtre" +msgstr "Počisti filter %s" -#, fuzzy msgid "Clear Sort" -msgstr "Počisti polja" +msgstr "Počisti razvrščanje" msgid "Clear all" msgstr "Počisti vse" @@ -3739,43 +3438,35 @@ msgstr "Počisti vse" msgid "Clear all data" msgstr "Počisti vse podatke" -#, fuzzy msgid "Clear all filters" -msgstr "počisti vse filtre" +msgstr "Počisti vse filtre" -#, fuzzy msgid "Clear default dark theme" -msgstr "Privzet datumčas" +msgstr "Počisti privzeto temno temo" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Clear default light theme" -msgstr "Počisti privzeto svetlo temo" +msgstr "Počisti privzeto svetlobno temo" msgid "Clear form" msgstr "Počisti polja" -#, fuzzy msgid "Clear local theme" -msgstr "Linearna barvna shema" +msgstr "Počisti lokalno temo" msgid "Clear search" -msgstr "" +msgstr "Počisti iskanje" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Clear the selection to revert to the system default theme" -msgstr "Počisti izbiro, da se vrneš na privzeto sistemsko temo" +msgstr "Počistite izbiro, da se vrnete na privzeto temo sistema" -#, fuzzy msgid "" "Click on \"Add or edit filters and controls\" option in Settings to " "create new dashboard filters" -msgstr "" -"Kliknite na gumb \"Dodaj/Uredi filtre\" za kreiranje novih filtrov " -"nadzorne plošče" +msgstr "V nastavitvah kliknite možnost »Dodaj ali uredi filtre in kontrolnike«, da ustvarite nove filtre na nadzorni plošči" msgid "" "Click on \"Create chart\" button in the control panel on the left to " @@ -3807,13 +3498,11 @@ msgstr "" msgid "Click to add a contour" msgstr "Klikni za dodajanje plastnice" -#, fuzzy msgid "Click to add new breakpoint" -msgstr "Klikni za dodajanje plastnice" +msgstr "Kliknite, če želite dodati novo prelomno točko" -#, fuzzy msgid "Click to add new layer" -msgstr "Klikni za dodajanje plastnice" +msgstr "Kliknite, da dodate novo plast" msgid "Click to cancel sorting" msgstr "Kliknite za prekinitev razvrščanja" @@ -3846,13 +3535,11 @@ msgstr "Kliknite za naraščajoče razvrščanje" msgid "Click to sort descending" msgstr "Kliknite za padajoče razvrščanje" -#, fuzzy msgid "Client ID" -msgstr "Debelina črte" +msgstr "ID odjemalca" -#, fuzzy msgid "Client Secret" -msgstr "Izbira stolpca" +msgstr "Skrivnost odjemalca" msgid "Close" msgstr "Zapri" @@ -3862,7 +3549,6 @@ msgstr "Zapri vse ostale zavihke" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Close color breakpoint editor" msgstr "Zapri urejevalnik barvnih prelomnih točk" @@ -3878,20 +3564,14 @@ msgstr "Radij gručenja" msgid "Code" msgstr "Koda" -#, fuzzy msgid "Code Copied!" -msgstr "SQL kopiran!" +msgstr "Koda kopirana!" -#, fuzzy msgid "Collapse" -msgstr "Skrij vrstico" +msgstr "Strni" -#, fuzzy msgid "Collapse All" -msgstr "Skrči vse" - -msgid "Collapse Datasource panel" -msgstr "" +msgstr "Strni vse" msgid "Collapse all" msgstr "Skrči vse" @@ -3911,71 +3591,56 @@ msgstr "Barva" msgid "Color +/-" msgstr "Barva +/-" -#, fuzzy msgid "Color By X-Axis" -msgstr "Barva glede na" +msgstr "Barva po osi X" -#, fuzzy msgid "Color By Y-Axis" -msgstr "Barva glede na" +msgstr "Barva po osi Y" msgid "Color Metric" msgstr "Mera za barvo" -msgid "Color Range End" -msgstr "" - -msgid "Color Range Start" -msgstr "" - msgid "Color Scheme" msgstr "Barvna shema" -#, fuzzy msgid "Color Scheme Type" -msgstr "Barvna shema" +msgstr "Vrsta barvne sheme" msgid "Color Steps" msgstr "Barvni koraki" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "Color bars by x-axis" -msgstr "Pobarvaj stolpce po osi x" +msgstr "Obarvaj stolpce glede na os X" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "Color bars by y-axis" -msgstr "Pobarvaj stolpce po osi y" +msgstr "Obarvaj stolpce glede na os Y" msgid "Color bounds" msgstr "Barvne meje" -#, fuzzy msgid "Color breakpoints" -msgstr "Točke za razčlenitev razdelkov" +msgstr "Barvne mejne točke" msgid "Color by" msgstr "Barva glede na" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "Color field must be a hex color (#rrggbb) or 'rgb(r, g, b)'" -msgstr "Polje barve mora biti šestnajstiška barva (#rrggbb) ali 'rgb(r, g, b)'" +msgstr "Barvno polje mora biti šestnajstiška barva (#rrggbb) ali 'rgb(r, g, b)'" -#, fuzzy msgid "Color for breakpoint" -msgstr "Točke za razčlenitev razdelkov" +msgstr "Barva za prelomno točko" msgid "Color metric" msgstr "Mera za barvo" -#, fuzzy msgid "Color of the source location" -msgstr "Barva ciljne lokacije" +msgstr "Barva izvorne lokacije" msgid "Color of the target location" msgstr "Barva ciljne lokacije" @@ -4005,9 +3670,8 @@ msgstr "Stolpec \"%(column)s\" ni numeričen ali ne obstaja v rezultatu poizvedb msgid "Column Configuration" msgstr "Konfiguracija stolpca" -#, fuzzy msgid "Column Settings" -msgstr "Nastavitve poligonov" +msgstr "Nastavitve stolpca" msgid "" "Column containing ISO 3166-2 codes of region/province/department in your " @@ -4045,9 +3709,8 @@ msgstr "Stolpec referenciran z agregacijo ni definiran: %(column)s" msgid "Column select" msgstr "Izbira stolpca" -#, fuzzy msgid "Column to group by" -msgstr "Stolpci za združevanje po" +msgstr "Stolpec za razvrščanje v skupine" msgid "" "Column to use as the index of the dataframe. If None is given, Index " @@ -4056,38 +3719,32 @@ msgstr "" "Stolpec, ki se uporabi kot indeks v dataframe-u. Če je prazno, se uporabi" " oznaka Index." -#, fuzzy msgid "Column type" -msgstr "Podatkovni tipi stolpcev" +msgstr "Vrsta stolpca" -#, fuzzy msgid "Columnar upload" -msgstr "Nalaganje stolpčne datoteke" +msgstr "Nalaganje v stolpcu" msgid "Columns" msgstr "Stolpci" -#, fuzzy, python-format +#, python-format msgid "Columns (%s)" -msgstr "Stolpci: %s" +msgstr "Stolpci (%s)" -#, fuzzy msgid "Columns (horizontal layout)" -msgstr "Vodoravno (zgoraj)" +msgstr "Stolpci (vodoravna postavitev)" -#, fuzzy msgid "Columns and metrics" -msgstr " za dodajanje mer" +msgstr "Stolpci in mere" -#, fuzzy msgid "Columns and metrics should be inside folders" -msgstr " za dodajanje mer" +msgstr "Stolpci in mere morajo biti v mapah" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Columns folder can only contain column items" -msgstr "Mapa stolpcev lahko vsebuje samo elemente stolpcev" +msgstr "Mapa Stolpci lahko vsebuje samo elemente stolpcev" #, python-format msgid "Columns missing in dataset: %(invalid_columns)s" @@ -4099,16 +3756,14 @@ msgstr "V podatkovnem viru manjkajo stolpci: %(invalid_columns)s" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, es, sr, # sr_Latn] -#, fuzzy msgid "Columns should be inside folders" msgstr "Stolpci naj bodo znotraj map" msgid "Columns subtotal position" msgstr "Položaj delnih vsot stolpcev" -#, fuzzy msgid "Columns to be parsed as dates" -msgstr "Izberite stolpce, ki bodo prepoznani kot datumi" +msgstr "Stolpci, ki bodo razčlenjeni kot datumi" msgid "Columns to calculate distribution across." msgstr "Stolpci za izračun porazdelitve." @@ -4125,13 +3780,11 @@ msgstr "Stolpci za združevanje po stolpcih" msgid "Columns to group by on the rows" msgstr "Stolpci za združevanje po vrsticah" -#, fuzzy msgid "Columns to read" -msgstr "Izberite stolpce za branje" +msgstr "Stolpci za branje" -#, fuzzy msgid "Columns to show in the tooltip." -msgstr "Opis glave stolpca" +msgstr "Stolpci, prikazani v opisu orodja." msgid "Combine metrics" msgstr "Združuj mere" @@ -4153,9 +3806,8 @@ msgstr "" "Zadnja številka naj bo enaka vrednosti za MAX." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ja] -#, fuzzy msgid "Common (unit per pixel at zoom 0)" -msgstr "Skupno (enota na piksel pri povečavi 0)" +msgstr "Običajno (enota na slikovno piko pri povečavi 0)" msgid "Comparator option" msgstr "Možnosti komparatorja" @@ -4184,15 +3836,13 @@ msgstr "" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "" "Compares metrics between different time periods. Displays time series " "data across multiple periods (like weeks or months) to show period-over-" "period trends and patterns." msgstr "" -"Primerja meritve med različnimi časovnimi obdobji. Prikazuje podatke " -"časovnih vrst čez več obdobij (kot so tedni ali meseci), da prikaže " -"trende in vzorce med obdobji." +"Primerja meritve med različnimi časovnimi obdobji. Prikaže podatke o časovni vrsti v več obdobjih (kot so tedni ali meseci), da prikaže trende in vzorce med " +"posameznimi obdobji." msgid "Comparison" msgstr "Primerjava" @@ -4230,9 +3880,9 @@ msgstr "Interval zaupanja mora biti med 0 in 1 (odprt)" msgid "Configuration" msgstr "Nastavitve" -#, fuzzy, python-format +#, python-format msgid "Configure %s" -msgstr "Potrdite shranjevanje" +msgstr "Konfigurirajte %s" msgid "Configure Advanced Time Range " msgstr "Nastavi napredno časovno obdobje " @@ -4248,24 +3898,21 @@ msgstr "Nastavi časovno obdobje: Prejšnji ..." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Configure automatic dashboard refresh" -msgstr "Konfiguriraj samodejno osveževanje nadzorne plošče" +msgstr "Konfigurirajte samodejno osveževanje nadzorne plošče" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Configure caching and performance settings" -msgstr "Konfiguriraj nastavitve predpomnenja in zmogljivosti" +msgstr "Konfigurirajte predpomnjenje in nastavitve delovanja" msgid "Configure custom time range" msgstr "Nastavi prilagojeno časovno obdobje" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Configure dashboard appearance, colors, and custom CSS" -msgstr "Konfiguriraj videz nadzorne plošče, barve in CSS po meri" +msgstr "Konfigurirajte videz nadzorne plošče, barve in CSS po meri" msgid "Configure filter scopes" msgstr "Nastavi doseg filtrov" @@ -4275,9 +3922,8 @@ msgstr "Osnovne nastavitve sloja z oznakami." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fr, ja, lv, mi, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Configure the chart size for each zoom level" -msgstr "Konfiguriraj velikost grafikona za vsako raven povečave" +msgstr "Konfigurirajte velikost grafikona za vsako stopnjo povečave" msgid "Configure this dashboard to embed it into an external web application." msgstr "Nastavite nadzorno ploščo za vgradnjo v zunanjo spletno aplikacijo." @@ -4285,29 +3931,25 @@ msgstr "Nastavite nadzorno ploščo za vgradnjo v zunanjo spletno aplikacijo." msgid "Configure your how you overlay is displayed here." msgstr "Nastavite kako prikazuje vrhnja plast." -#, fuzzy msgid "Confirm" -msgstr "Potrdite shranjevanje" +msgstr "Potrdi" -#, fuzzy msgid "Confirm Password" -msgstr "Prikaži geslo." +msgstr "Potrdite geslo" msgid "Confirm overwrite" msgstr "Potrdite prepis" -#, fuzzy msgid "Confirm password" -msgstr "Prikaži geslo." +msgstr "Potrdite geslo" msgid "Confirm save" msgstr "Potrdite shranjevanje" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fr, ja, lv, mi, pt_BR, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Confirm the user's password" -msgstr "Potrdi geslo uporabnika" +msgstr "Potrdite geslo uporabnika" msgid "Connect" msgstr "Poveži" @@ -4330,9 +3972,8 @@ msgstr "S podatkovno bazo se povežite z dinamičnim obrazcem" msgid "Connect this database with a SQLAlchemy URI string instead" msgstr "S to podatkovno bazo se raje povežite z SQLAlchemy URI nizom" -#, fuzzy msgid "Connect to engine" -msgstr "Povezava" +msgstr "Poveži se z mehanizmom" msgid "Connection" msgstr "Povezava" @@ -4344,15 +3985,14 @@ msgid "Connection failed, please check your connection settings." msgstr "Povezava neuspešna. Preverite nastavitve povezave." msgid "Connection looks good!" -msgstr "" +msgstr "Povezava deluje!" -#, fuzzy msgid "Contains" -msgstr "Zvezno" +msgstr "Vsebuje" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy, python-format +#, python-format msgid "Contains text (ILIKE %x%)" msgstr "Vsebuje besedilo (ILIKE %x%)" @@ -4389,16 +4029,14 @@ msgstr "Kontrolniki imenovani " msgid "Copied to clipboard!" msgstr "Kopirano na odložišče!" -#, fuzzy msgid "Copied!" -msgstr "SQL kopiran!" +msgstr "Kopirano!" msgid "Copy" msgstr "Kopiraj" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fr, ja, lv, mi, pt_BR, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Copy SELECT statement" msgstr "Kopiraj stavek SELECT" @@ -4407,20 +4045,17 @@ msgstr "Kopiraj stavek SELECT na odložišče" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fr, ja, lv, mi, pt_BR, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Copy URL" msgstr "Kopiraj URL" msgid "Copy and Paste JSON credentials" msgstr "Kopiraj in prilepi JSON prijavne podatke" -#, fuzzy msgid "Copy code to clipboard" -msgstr "Kopiraj na odložišče" +msgstr "Kopiraj kodo v odložišče" -#, fuzzy msgid "Copy column name" -msgstr "Ime stolpca" +msgstr "Kopiraj ime stolpca" #, python-format msgid "Copy of %s" @@ -4433,21 +4068,19 @@ msgid "Copy permalink to clipboard" msgstr "Kopiraj povezavo v odložišče" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: lv] -#, fuzzy msgid "Copy query" msgstr "Kopiraj poizvedbo" msgid "Copy query URL" -msgstr "" +msgstr "Kopiraj URL poizvedbe" msgid "Copy query link to your clipboard" msgstr "Kopiraj povezavo do poizvedbe v odložišče" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fr, ja, lv, mi, pt_BR, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Copy the current data" -msgstr "Kopiraj trenutne podatke" +msgstr "Kopirajte trenutne podatke" msgid "Copy the identifier of the account you are trying to connect to." msgstr "Kopirajte ID računa, s katerim se skušate povezati." @@ -4464,13 +4097,11 @@ msgstr "Kopiraj na odložišče" msgid "Copy to clipboard" msgstr "Kopiraj na odložišče" -#, fuzzy msgid "Copy with Headers" -msgstr "S podnaslovom" +msgstr "Kopiraj z glavami" -#, fuzzy msgid "Corner Radius" -msgstr "Notranji polmer" +msgstr "Radij kota" msgid "Correlation" msgstr "Korelacija" @@ -4492,21 +4123,15 @@ msgid "Could not find viz object" msgstr "Ni mogoče najti vizualizacijskega objekta" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ja] -#, fuzzy msgid "Could not load SQL Lab" msgstr "SQL Lab ni bilo mogoče naložiti" msgid "Could not load database driver" msgstr "Ni mogoče naložiti gonilnika podatkovne baze" -#, fuzzy, python-format +#, python-format msgid "Could not load database driver for: %(engine)s" -msgstr "Ni mogoče naložiti gonilnika podatkovne baze: {}" - -msgid "" -"Could not load metadata for this configuration; showing the default form." -" See the server logs for details." -msgstr "" +msgstr "Ni bilo mogoče naložiti gonilnika baze podatkov za: %(engine)s" #, python-format msgid "Could not resolve hostname: \"%(host)s\"." @@ -4514,13 +4139,24 @@ msgstr "Gostitelj ni dosegljiv: \"%(host)s\"." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fr, ja, lv, mi, pt_BR, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Could not validate the user in the current session." -msgstr "Uporabnika v trenutni seji ni bilo mogoče preveriti." +msgstr "Uporabnika v trenutni seji ni bilo mogoče potrditi." msgid "Count" msgstr "Število" +msgid "Count Unique Values" +msgstr "Število unikatnih" + +msgid "Count as Fraction of Columns" +msgstr "Štetje kot delež stolpcev" + +msgid "Count as Fraction of Rows" +msgstr "Štetje kot delež vrstic" + +msgid "Count as Fraction of Total" +msgstr "Štetje kot delež skupne vsote" + msgid "Country" msgstr "Država" @@ -4539,13 +4175,11 @@ msgstr "Zemljevid držav" msgid "Create" msgstr "Ustvari" -#, fuzzy msgid "Create API Key" -msgstr "Ustvaril" +msgstr "Ustvari ključ API" -#, fuzzy msgid "Create Tag" -msgstr "Ustvarite podatkovni set" +msgstr "Ustvari oznako" msgid "Create a dataset" msgstr "Ustvarite podatkovni set" @@ -4558,9 +4192,8 @@ msgstr "" "ali\n" " pojdite v SQL laboratorij za poizvedovanje nad podatki." -#, fuzzy msgid "Create a new Tag" -msgstr "ustvarite nov grafikon" +msgstr "Ustvarite novo oznako" msgid "Create a new chart" msgstr "Ustvarite nov grafikon" @@ -4568,11 +4201,10 @@ msgstr "Ustvarite nov grafikon" msgid "" "Create a new tag and assign it to existing entities like charts or " "dashboards" -msgstr "" +msgstr "Ustvarite novo oznako in jo dodelite obstoječim elementom, kot so grafikoni ali nadzorne plošče" -#, fuzzy msgid "Create and explore dataset" -msgstr "Ustvarite podatkovni set" +msgstr "Ustvarite in raziščite podatkovni niz" msgid "Create chart" msgstr "Ustvarite grafikon" @@ -4598,9 +4230,9 @@ msgstr "Ustvaril" msgid "Created by me" msgstr "Ustvarjeno z moje strani" -#, fuzzy, python-format +#, python-format msgid "Created by: %s" -msgstr "Ustvaril" +msgstr "Ustvaril: %s" msgid "Created on" msgstr "Ustvarjeno" @@ -4617,9 +4249,8 @@ msgstr "Avtor" msgid "Crimson" msgstr "Škrlatna" -#, fuzzy msgid "Cross-filter column" -msgstr "Doseg medsebojnih filtrov" +msgstr "Stolpec z navzkrižnim filtrom" msgid "Cross-filter will be applied to all of the charts that use this dataset." msgstr "" @@ -4644,9 +4275,8 @@ msgstr "Kumulativno" msgid "Currency" msgstr "Valuta" -#, fuzzy msgid "Currency code column" -msgstr "Simbol valute" +msgstr "Stolpec kode valute" msgid "Currency format" msgstr "Oblika zapisa valute" @@ -4660,9 +4290,8 @@ msgstr "Simbol valute" msgid "Current" msgstr "Tekoči" -#, fuzzy msgid "Current Zoom" -msgstr "Tekoči" +msgstr "Trenutna povečava" msgid "Current day" msgstr "Tekoči dan" @@ -4700,13 +4329,11 @@ msgstr "Prilagodljive ad-hoc SQL-mere za ta podatkovni set niso omogočene" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "Custom SQL fields cannot be parsed as a single SQL statement." msgstr "Polja SQL po meri ni mogoče razčleniti kot en sam stavek SQL." -#, fuzzy msgid "Custom SQL fields cannot contain set operations." -msgstr "Prilagojena SQL-polja ne smejo vsebovati podpoizvedb." +msgstr "Polja SQL po meri ne morejo vsebovati nabornih operacij." msgid "Custom SQL fields cannot contain sub-queries." msgstr "Prilagojena SQL-polja ne smejo vsebovati podpoizvedb." @@ -4716,9 +4343,8 @@ msgstr "Prilagojene barvne palete" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fr, ja, lv, mi, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Custom column name (leave blank for default)" -msgstr "Ime stolpca po meri (pusti prazno za privzeto)" +msgstr "Ime stolpca po meri (privzeto pustite prazno)" msgid "Custom conditional formatting" msgstr "Prilagojeno pogojno oblikovanje" @@ -4728,9 +4354,8 @@ msgstr "Prilagojen datum" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Custom fields not available in aggregated heatmap cells" -msgstr "Polja po meri niso na voljo v združenih celicah toplotne karte" +msgstr "Polja po meri niso na voljo v združenih celicah toplotnega zemljevida" msgid "Custom time filter plugin" msgstr "Prilagojeni vtičnik za časovni filter" @@ -4738,25 +4363,21 @@ msgstr "Prilagojeni vtičnik za časovni filter" msgid "Custom width of the screenshot in pixels" msgstr "Poljubna širina zaslonske slike v pikslih" -#, fuzzy msgid "Custom..." -msgstr "Prilagojen" +msgstr "Po meri ..." -#, fuzzy msgid "Customization and styling" -msgstr "Tip vizualizacije" +msgstr "Prilagajanje in oblikovanje" -#, fuzzy msgid "Customization type" -msgstr "Tip vizualizacije" +msgstr "Vrsta prilagajanja" -#, fuzzy msgid "Customization value is required" -msgstr "Vrednost filtra je obvezna" +msgstr "Potrebna je vrednost prilagajanja" -#, fuzzy, python-format +#, python-format msgid "Customizations out of scope (%d)" -msgstr "Filtri izven dosega (%d)" +msgstr "Prilagoditve izven obsega ( %d )" msgid "Customize" msgstr "Prilagodi" @@ -4766,13 +4387,10 @@ msgstr "Prilagodi mere" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "" "Customize cell titles using Handlebars template syntax. Available " "variables: {{rowLabel}}, {{colLabel}}" -msgstr "" -"Prilagodi naslove celic z uporabo sintakse predloge Handlebars. " -"Razpoložljive spremenljivke: {{rowLabel}}, {{colLabel}}" +msgstr "Prilagodite naslove celic s sintakso predloge Handlebars. Razpoložljive spremenljivke: {{rowLabel}}, {{colLabel}}" msgid "Customize columns" msgstr "Prilagodi stolpce" @@ -4782,37 +4400,27 @@ msgstr "Prilagodite podatkovni vir, filtre in izgled." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "" "Customize the label displayed for decreasing values in the chart tooltips" " and legend." -msgstr "" -"Prilagodi oznako, prikazano za padajoče vrednosti v namigih in legendi " -"grafikona." +msgstr "Prilagodite oznako, prikazano za padajoče vrednosti v opisih orodij in legendi grafikona." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "" "Customize the label displayed for increasing values in the chart tooltips" " and legend." -msgstr "" -"Prilagodi oznako, prikazano za naraščajoče vrednosti v namigih in legendi" -" grafikona." +msgstr "Prilagodite oznako, prikazano za naraščajoče vrednosti v opisih orodij in legendi grafikona." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "" "Customize the label displayed for total values in the chart tooltips, " "legend, and chart axis." -msgstr "" -"Prilagodi oznako, prikazano za skupne vrednosti v namigih grafikona, " -"legendi in osi grafikona." +msgstr "Prilagodite oznako, prikazano za skupne vrednosti v opisih orodij grafikona, legendi in osi grafikona." -#, fuzzy msgid "Customize tooltips template" -msgstr "CSS predloga" +msgstr "Prilagodi predlogo opisov orodij" msgid "Cyclic dependency detected" msgstr "Zaznana krožna odvisnost" @@ -4862,9 +4470,8 @@ msgstr "Dnevna sezonskost" msgid "Dark" msgstr "Temno" -#, fuzzy msgid "Dark (Carto)" -msgstr "Radarski grafikon" +msgstr "Temno (Carto)" msgid "Dark Cyan" msgstr "Temno sinja" @@ -4875,17 +4482,15 @@ msgstr "Temni način" msgid "Dashboard" msgstr "Nadzorna plošča" -#, fuzzy, python-format +#, python-format msgid "Dashboard %(dashboard_id)s not found" -msgstr "Grafikon %(id)s ni najden" +msgstr "Nadzorna plošča %(dashboard_id)s ni bila najdena" -#, fuzzy msgid "Dashboard Filter" -msgstr "Ime nadzorne plošče" +msgstr "Filter nadzorne plošče" -#, fuzzy msgid "Dashboard Id" -msgstr "nadzorna plošča" +msgstr "ID nadzorne plošče" #, python-format msgid "Dashboard [%s] just got created and chart [%s] was added to it" @@ -4900,24 +4505,21 @@ msgstr "Nadzorne plošče ni mogoče dodati med priljubljene." msgid "" "Dashboard cannot be restored because its slug is now used by another " "active dashboard. Rename one of the dashboards and retry." -msgstr "" +msgstr "Nadzorne plošče ni mogoče obnoviti, ker njen ključ zdaj uporablja druga aktivna nadzorna plošča. Preimenujte eno od njiju in poskusite znova." msgid "Dashboard cannot be unfavorited." msgstr "Nadzorne plošče ni mogoče odstraniti iz priljubljenih." -#, fuzzy msgid "Dashboard chart customizations could not be updated." -msgstr "Nadzorne plošče ni mogoče posodobiti." +msgstr "Prilagoditev grafikona nadzorne plošče ni bilo mogoče posodobiti." -#, fuzzy msgid "Dashboard color configuration could not be updated." -msgstr "Nadzorne plošče ni mogoče posodobiti." +msgstr "Barvne konfiguracije nadzorne plošče ni bilo mogoče posodobiti." msgid "Dashboard could not be deleted." msgstr "Nadzorne plošče ni mogoče izbrisati." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [no refs] -#, fuzzy msgid "Dashboard could not be restored." msgstr "Nadzorne plošče ni bilo mogoče obnoviti." @@ -4927,30 +4529,25 @@ msgstr "Nadzorne plošče ni mogoče posodobiti." msgid "Dashboard does not exist" msgstr "Nadzorna plošča ne obstaja" -#, fuzzy msgid "Dashboard exported as example successfully" -msgstr "Nadzorna plošča je bila uspešno shranjena." +msgstr "Nadzorna plošča je uspešno izvožena kot primer" -#, fuzzy msgid "Dashboard exported successfully" -msgstr "Nadzorna plošča je bila uspešno shranjena." +msgstr "Nadzorna plošča je bila uspešno izvožena" msgid "Dashboard imported" msgstr "Nadzorna plošča uvožena" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, ja, lv, # ro, ru, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Dashboard name and URL configuration" -msgstr "Konfiguracija imena in URL-ja nadzorne plošče" +msgstr "Ime nadzorne plošče in konfiguracija URL-ja" -#, fuzzy msgid "Dashboard name is required" -msgstr "Zahtevano je ime" +msgstr "Zahtevano je ime nadzorne plošče" -#, fuzzy msgid "Dashboard native filters could not be patched." -msgstr "Nadzorne plošče ni mogoče posodobiti." +msgstr "Izvornih filtrov nadzorne plošče ni bilo mogoče popraviti." msgid "Dashboard parameters are invalid." msgstr "Parametri nadzorne plošče so neveljavni." @@ -4977,9 +4574,9 @@ msgstr "" msgid "Dashboard title" msgstr "Ime nadzorne plošče" -#, fuzzy, python-format +#, python-format msgid "Dashboard updated %s" -msgstr "Zadnja posodobitev %s" +msgstr "Nadzorna plošča posodobljena %s" msgid "Dashboard usage" msgstr "Uporaba nadzorne plošče" @@ -4999,13 +4596,11 @@ msgstr "Črtkano" msgid "Data" msgstr "Podatki" -#, fuzzy msgid "Data Connections" -msgstr "Povezave na podatkovne baze" +msgstr "Podatkovne povezave" -#, fuzzy msgid "Data Export Options" -msgstr "Možnosti grafikona" +msgstr "Možnosti izvoza podatkov" msgid "Data Table" msgstr "Tabela podatkov" @@ -5016,13 +4611,11 @@ msgstr "URI za podatke ni dovoljen." msgid "Data Zoom" msgstr "Zoom funkcija" -#, fuzzy msgid "Data connection" -msgstr "Povezave na podatkovne baze" +msgstr "Podatkovna povezava" -#, fuzzy msgid "Data connections" -msgstr "Povezave na podatkovne baze" +msgstr "Podatkovne povezave" msgid "" "Data could not be deserialized from the results backend. The storage " @@ -5040,15 +4633,13 @@ msgstr "" "Podatkov ni bilo mogoče pridobiti iz zalednega sistema rezultatov. " "Ponovno morate zagnati izvorno poizvedbo." -#, fuzzy msgid "Data error" -msgstr "Napaka podatkovne baze" +msgstr "Podatkovna napaka" #, python-format msgid "Data for %s" msgstr "Podatki za %s" -#, fuzzy msgid "Data imported" msgstr "Podatki uvoženi" @@ -5128,9 +4719,8 @@ msgstr "Gesla podatkovne baze" msgid "Database port" msgstr "Vrata podatkovne baze" -#, fuzzy msgid "Database reference is not allowed on a report" -msgstr "Shema podatkovne baze ne dovoljuje nalaganje csv-datotek." +msgstr "Sklicevanje na bazo podatkov v poročilu ni dovoljeno" msgid "Database schema is not allowed for csv uploads." msgstr "Shema podatkovne baze ne dovoljuje nalaganje csv-datotek." @@ -5142,9 +4732,8 @@ msgid "Database type does not support file uploads." msgstr "Tip podatkovne baze ne podpira nalaganje datotek." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [no refs] -#, fuzzy msgid "Database upload file exceeds the maximum allowed size." -msgstr "Datoteka za nalaganje v bazo podatkov presega največjo dovoljeno velikost." +msgstr "Datoteka za nalaganje zbirke podatkov presega največjo dovoljeno velikost." msgid "Database upload file failed" msgstr "Nalaganje datoteke v podatkovno bazo ni uspelo" @@ -5158,7 +4747,7 @@ msgid "Databases" msgstr "Podatkovne baze" msgid "Dataset" -msgstr "Podatkovni set" +msgstr "Podatkovni niz" #, python-format msgid "Dataset %(table)s already exists" @@ -5168,16 +4757,13 @@ msgid "Dataset Name" msgstr "Ime podatkovnega seta" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ja] -#, fuzzy msgid "" "Dataset cannot be restored because another active dataset already " "references the same physical table (same database, catalog, schema, and " "table name). Delete the duplicate or rename the table before restoring." msgstr "" -"Podatkovne zbirke ni mogoče obnoviti, ker druga aktivna podatkovna zbirka" -" že sklicuje na isto fizično tabelo (ista podatkovna baza, katalog, shema" -" in ime tabele). Izbrišite dvojnik ali preimenujte tabelo pred " -"obnovitvijo." +"Nabora podatkov ni mogoče obnoviti, ker se drug aktivni podatkovni niz že sklicuje na isto fizično tabelo (ista baza podatkov, katalog, shema in ime " +"tabele). Izbrišite dvojnik ali preimenujte tabelo pred obnovitvijo." msgid "Dataset column delete failed." msgstr "Brisanje stolpca podatkovnega seta neuspešno." @@ -5192,9 +4778,8 @@ msgid "Dataset could not be duplicated." msgstr "Podatkovnega niza ni mogoče duplicirati." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ja] -#, fuzzy msgid "Dataset could not be restored." -msgstr "Podatkovne zbirke ni bilo mogoče obnoviti." +msgstr "Podatkovnega niza ni bilo mogoče obnoviti." msgid "Dataset could not be updated." msgstr "Podatkovnega niza ni mogoče posodobiti." @@ -5222,7 +4807,7 @@ msgid "Dataset schema is invalid, caused by: %(error)s" msgstr "Shema podatkovnega seta ni veljavna, zaradi napake: %(error)s" msgid "Datasets" -msgstr "Podatkovni seti" +msgstr "Podatkovni nizi" msgid "" "Datasets can be created from database tables or SQL queries. Select a " @@ -5246,13 +4831,11 @@ msgstr "Tip podatkovnega vira in grafikona" msgid "Datasource does not exist" msgstr "Podatkovni vir ne obstaja" -#, fuzzy msgid "Datasource is required" -msgstr "Zahtevan je podatkovni set" +msgstr "Potreben je vir podatkov" -#, fuzzy msgid "Datasource is required for validation" -msgstr "Podatkovna baza je obvezna za opozorila" +msgstr "Vir podatkov je potreben za preverjanje" msgid "Datasource type is invalid" msgstr "Neveljaven tip podatkovnega vira" @@ -5260,9 +4843,8 @@ msgstr "Neveljaven tip podatkovnega vira" msgid "Datasource type is required when datasource_id is given" msgstr "Ko se podaja datasource_id, je potreben tip podatkovnega vira" -#, fuzzy msgid "Datasources" -msgstr "Podatkovni vir" +msgstr "Viri podatkov" msgid "Date Time Format" msgstr "Oblika zapisa za Datum-Čas" @@ -5305,13 +4887,11 @@ msgstr "Deaktiviraj" msgid "December" msgstr "December" -#, fuzzy msgid "Decides which column or measure to sort the base axis by." -msgstr "Odloči, po kateri meri bo razvrščena osnovna os." +msgstr "Odloči, po katerem stolpcu ali meri naj se razvrsti osnovna os." -#, fuzzy msgid "Decimal character" -msgstr "Decimalno ločilo" +msgstr "Decimalni znak" msgid "Deck.gl - 3D Grid" msgstr "Deck.gl - 3D mreža" @@ -5346,35 +4926,29 @@ msgstr "Deck.gl - raztreseni grafikon" msgid "Deck.gl - Screen Grid" msgstr "Deck.gl - mreža" -#, fuzzy msgid "Deck.gl Layer Visibility" -msgstr "Deck.gl - raztreseni grafikon" +msgstr "Vidnost plasti Deck.gl" -#, fuzzy msgid "Deckgl" -msgstr "deckGL" +msgstr "Deckgl" msgid "Decrease" msgstr "Zmanjšaj" -#, fuzzy msgid "Decrease color" -msgstr "Zmanjšaj" +msgstr "Zmanjšaj barvo" -#, fuzzy msgid "Decrease label" -msgstr "Zmanjšaj" +msgstr "Zmanjšaj oznako" -#, fuzzy msgid "Default" -msgstr "privzeto" +msgstr "Privzeto" msgid "Default Catalog" msgstr "Privzeti katalog" -#, fuzzy msgid "Default Column Settings" -msgstr "Nastavitve poligonov" +msgstr "Privzete nastavitve stolpcev" msgid "Default Schema" msgstr "Privzeta shema" @@ -5384,28 +4958,22 @@ msgstr "Privzeti URL" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, ja, lv, # pt_BR, ro, ru, sr, sr_Latn, tr, uk] -#, fuzzy msgid "" "Default URL to redirect to when accessing from the dataset list page. " "Accepts relative URLs such as" -msgstr "" -"Privzeti URL za preusmeritev pri dostopu s strani seznama naborov " -"podatkov. Sprejema relativne URL-je, kot so" +msgstr "Privzeti URL za preusmeritev pri dostopu s strani s seznamom nabora podatkov. Sprejema relativne URL-je, kot je npr" msgid "Default Value" msgstr "Privzeta vrednost" -#, fuzzy msgid "Default color" -msgstr "Privzeti katalog" +msgstr "Privzeta barva" -#, fuzzy msgid "Default datetime column" -msgstr "Privzet datumčas" +msgstr "Privzeti stolpec datuma in časa" -#, fuzzy msgid "Default folders cannot be nested" -msgstr "Podatkovnega niza ni mogoče ustvariti." +msgstr "Privzetih map ni mogoče ugnezditi" msgid "Default latitude" msgstr "Privzeta širina" @@ -5413,9 +4981,8 @@ msgstr "Privzeta širina" msgid "Default longitude" msgstr "Privzeta dolžina" -#, fuzzy msgid "Default message" -msgstr "Privzeta vrednost" +msgstr "Privzeto sporočilo" msgid "" "Default minimal column width in pixels, actual width may still be larger " @@ -5441,11 +5008,23 @@ msgstr "" "Privzeta vrednost je samodejno izbrana, če je izbrano \"Prvi element je " "izbran kot privzet\"" +msgid "Define a function that receives the input and outputs the content for a tooltip" +msgstr "Določite funkcijo, ki sprejme vhodne podatke in vrne vsebino opisa orodja" + +msgid "Define a function that returns a URL to navigate to when user clicks" +msgstr "Določite funkcijo, ki vrne URL za navigacijo, ko uporabnik klikne" + +msgid "" +"Define a javascript function that receives the data array used in the visualization and is expected to return a modified version of that array. This can be " +"used to alter properties of the data, filter, or enrich the array." +msgstr "" +"Določite Javascript funkcijo, ki sprejme podatkovni niz za vizualizacijo in vrne spremenjeno verzijo tega niza. Lahko se uporabi za spreminjanje lastnosti " +"podatkov, filtra ali obogatitve niza." + # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, pt_BR, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Define color breakpoints for the data" -msgstr "Določi barvne prelomne točke za podatke" +msgstr "Določite barvne prelomne točke za podatke" msgid "" "Define contour layers. Isolines represent a collection of line segments " @@ -5465,9 +5044,8 @@ msgstr "" "Definirajte podatkovno bazo, SQL-poizvedbo in pogoje proženja za " "opozorilo." -#, fuzzy msgid "Defined through system configuration." -msgstr "Neveljavna nastavitev zemljepisne dolžine/širine." +msgstr "Določeno s konfiguracijo sistema." msgid "" "Defines a rolling window function to apply, works along with the " @@ -5508,26 +5086,25 @@ msgstr "" "Določa, če se na začetku, na sredini ali na koncu pojavi stopnica med " "dvema točkama" -#, fuzzy msgid "Definition" -msgstr "deviacija" +msgstr "Opredelitev" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, ja, sr, # sr_Latn] -#, fuzzy, python-format +#, python-format msgid "Delayed (missed %s refresh)" msgid_plural "Delayed (missed %s refreshes)" -msgstr[0] "Zakasnelo (preskočeno %s osveževanje)" -msgstr[1] "Zakasnelo (preskočeni %s osveževanji)" -msgstr[2] "Zakasnelo (preskočena %s osveževanja)" -msgstr[3] "Zakasnelo (preskočenih %s osveževanj)" +msgstr[0] "Zakasnelo (zamujeno %s osveževanje)" +msgstr[1] "Zakasnelo (zamujeni %s osveževanji)" +msgstr[2] "Zakasnelo (zamujena %s osveževanja)" +msgstr[3] "Zakasnelo (zamujenih %s osveževanj)" msgid "Delete" msgstr "Izbriši" -#, fuzzy, python-format +#, python-format msgid "Delete %s" -msgstr "Izbrisano %s" +msgstr "Izbriši %s" #, python-format msgid "Delete %s?" @@ -5536,9 +5113,8 @@ msgstr "Izbrišem %s?" msgid "Delete Annotation?" msgstr "Izbrišem oznako?" -#, fuzzy msgid "Delete Group?" -msgstr "Izbrišem predlogo?" +msgstr "Želite izbrisati skupino?" msgid "Delete Layer?" msgstr "Izbrišem sloj?" @@ -5549,28 +5125,23 @@ msgstr "Izbrišem poizvedbo?" msgid "Delete Report?" msgstr "Izbrišem poročilo?" -#, fuzzy msgid "Delete Role?" -msgstr "Izbrišem predlogo?" +msgstr "Želite izbrisati vlogo?" -#, fuzzy msgid "Delete Semantic Layer?" -msgstr "Izbrišem sloj?" +msgstr "Želite izbrisati semantično plast?" -#, fuzzy msgid "Delete Semantic View?" -msgstr "Izbrišem predlogo?" +msgstr "Želite izbrisati semantični pogled?" msgid "Delete Template?" msgstr "Izbrišem predlogo?" -#, fuzzy msgid "Delete Theme?" -msgstr "Izbrišem predlogo?" +msgstr "Želite izbrisati temo?" -#, fuzzy msgid "Delete User?" -msgstr "Izbrišem poizvedbo?" +msgstr "Želite izbrisati uporabnika?" msgid "Delete all Really?" msgstr "Ali resnično vse izbrišem?" @@ -5584,49 +5155,35 @@ msgstr "Ali izbrišem zavihek nadzorne plošče?" msgid "Delete email report" msgstr "Izbriši e-poštno poročilo" -#, fuzzy msgid "Delete group" -msgstr "Izberite datoteko" +msgstr "Izbriši skupino" -#, fuzzy msgid "Delete item" -msgstr "Izbriši predlogo" - -msgid "Delete permanently" -msgstr "" - -#, python-format -msgid "Delete permanently %(name)s?" -msgstr "" +msgstr "Izbriši predmet" msgid "Delete query" -msgstr "" +msgstr "Izbriši poizvedbo" -#, fuzzy msgid "Delete role" -msgstr "Izberite datoteko" +msgstr "Izbriši vlogo" msgid "Delete template" msgstr "Izbriši predlogo" -#, fuzzy msgid "Delete theme" -msgstr "Izbriši predlogo" +msgstr "Izbriši temo" msgid "Delete this container and save to remove this message." msgstr "Izbrišite ta okvir in shranite za odpravo tega sporočila." -#, fuzzy msgid "Delete user" -msgstr "Izbriši poizvedbo" +msgstr "Izbriši uporabnika" -#, fuzzy msgid "Delete user registration" -msgstr "Izbrisano: %s" +msgstr "Izbriši registracijo uporabnika" -#, fuzzy msgid "Delete user registration?" -msgstr "Izbrišem oznako?" +msgstr "Želite izbrisati registracijo uporabnika?" msgid "Deleted" msgstr "Izbrisano" @@ -5703,57 +5260,57 @@ msgstr[1] "Izbrisani %(num)d shranjeni poizvedbi" msgstr[2] "Izbrisane %(num)d shranjene poizvedbe" msgstr[3] "Izbrisanih %(num)d shranjenih poizvedb" -#, fuzzy, python-format +#, python-format msgid "Deleted %(num)d semantic view" msgid_plural "Deleted %(num)d semantic views" -msgstr[0] "Izbrisana %(num)d css predloga" -msgstr[1] "Izbrisani %(num)d css predlogi" -msgstr[2] "Izbrisane %(num)d css predloge" -msgstr[3] "Izbrisanih %(num)d css predlog" +msgstr[0] "Izbrisan %(num)d semantični pogled" +msgstr[1] "Izbrisana %(num)d semantična pogleda" +msgstr[2] "Izbrisani %(num)d semantični pogledi" +msgstr[3] "Izbrisanih %(num)d semantičnih pogledov" -#, fuzzy, python-format +#, python-format msgid "Deleted %(num)d theme" msgid_plural "Deleted %(num)d themes" -msgstr[0] "Izbrisan %(num)d podatkovni set" -msgstr[1] "Izbrisana %(num)d podatkovna niza" -msgstr[2] "Izbrisani %(num)d podatkovni nizi" -msgstr[3] "Izbrisanih %(num)d podatkovnih nizov" +msgstr[0] "Izbrisana %(num)d tema" +msgstr[1] "Izbrisani %(num)d temi" +msgstr[2] "Izbrisane %(num)d teme" +msgstr[3] "Izbrisanih %(num)d tem" #, python-format msgid "Deleted %s" msgstr "Izbrisano %s" -#, fuzzy, python-format +#, python-format msgid "Deleted %s item(s)" -msgstr "Izbriši predlogo" +msgstr "Izbrisanih elementov: %s" -#, fuzzy, python-format +#, python-format msgid "Deleted group: %s" -msgstr "Izbrisano: %s" +msgstr "Izbrisana skupina: %s" -#, fuzzy, python-format +#, python-format msgid "Deleted groups: %s" -msgstr "Izbrisano: %s" +msgstr "Izbrisane skupine: %s" -#, fuzzy, python-format +#, python-format msgid "Deleted role: %s" -msgstr "Izbrisano: %s" +msgstr "Izbrisana vloga: %s" -#, fuzzy, python-format +#, python-format msgid "Deleted roles: %s" -msgstr "Izbrisano: %s" +msgstr "Izbrisane vloge: %s" -#, fuzzy, python-format +#, python-format msgid "Deleted user registration for user: %s" -msgstr "Izbrisano: %s" +msgstr "Izbrisana uporabniška registracija za uporabnika: %s" -#, fuzzy, python-format +#, python-format msgid "Deleted user: %s" -msgstr "Izbrisano: %s" +msgstr "Izbrisan uporabnik: %s" -#, fuzzy, python-format +#, python-format msgid "Deleted users: %s" -msgstr "Izbrisano: %s" +msgstr "Izbrisani uporabniki: %s" #, python-format msgid "Deleted: %s" @@ -5796,9 +5353,8 @@ msgstr "Besedilo, ki se prikaže pod veliko številko" msgid "Deselect all" msgstr "Počisti izbor" -#, fuzzy msgid "Design with" -msgstr "Min. širina" +msgstr "Oblikovanje z" msgid "Details" msgstr "Podrobnosti" @@ -5808,17 +5364,14 @@ msgstr "Podrobnosti certifikacije" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "" "Determines how the filter matches values. \"Exact match\" uses the IN " "operator (default). ILIKE options enable partial text matching with a " "free-text input. Warning: ILIKE queries may be slow on large datasets as " "they cannot use indexes effectively." msgstr "" -"Določa, kako filter ujema vrednosti. \"Natančno ujemanje\" uporablja " -"operator IN (privzeto). Možnosti ILIKE omogočajo delno ujemanje besedila " -"s prostim vnosom. Opozorilo: poizvedbe ILIKE so lahko počasne na velikih " -"naborih podatkov, ker ne morejo učinkovito uporabiti indeksov." +"Določa, kako se filter ujema z vrednostmi. »Natančno ujemanje« uporablja operator IN (privzeto). Možnosti ILIKE omogočajo delno ujemanje besedila z vnosom " +"poljubnega besedila. Opozorilo: poizvedbe ILIKE so lahko počasne pri velikih naborih podatkov, saj ne morejo učinkovito uporabljati indeksov." msgid "Determines how whiskers and outliers are calculated." msgstr "Določa kako so izračunani kvantili in izstopajoče vrednosti." @@ -5845,28 +5398,22 @@ msgstr "Dimenzija" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "" "Dimension column emitted as a cross-filter when a feature is clicked. " "Other charts on the dashboard match against this column. If unset, falls " "back to the geometry column (legacy behavior, often unmatchable)." msgstr "" -"Stolpec dimenzije, oddan kot navzkrižni filter ob kliku na element. Drugi" -" grafikoni na nadzorni plošči se ujemajo s tem stolpcem. Če ni " -"nastavljeno, se vrne na stolpec geometrije (zastarelo vedenje, ki se " -"pogosto ne ujema)." +"Stolpec razsežnosti, oddan kot navzkrižni filter, ko kliknete funkcijo. Drugi grafikoni na nadzorni plošči se ujemajo s tem stolpcem. Če ni nastavljen, se " +"vrne v stolpec z geometrijo (podedovano vedenje, pogosto ni primerljivo)." -#, fuzzy msgid "Dimension is required" -msgstr "Zahtevano je ime" +msgstr "Dimenzija je obvezna" -#, fuzzy msgid "Dimension members" -msgstr "Dimenzije" +msgstr "Člani dimenzije" -#, fuzzy msgid "Dimension selection" -msgstr "Izbira časovnega pasa" +msgstr "Izbira dimenzij" msgid "Dimension to use on x-axis." msgstr "Dimenzija za x-os." @@ -5874,16 +5421,15 @@ msgstr "Dimenzija za x-os." msgid "Dimension to use on y-axis." msgstr "Dimenzija za y-os." -#, fuzzy msgid "Dimension values" -msgstr "Dimenzije" +msgstr "Vrednosti dimenzij" msgid "Dimensions" msgstr "Dimenzije" -#, fuzzy, python-format +#, python-format msgid "Dimensions (%s)" -msgstr "Dimenzije" +msgstr "Dimenzije (%s)" msgid "" "Dimensions contain qualitative values such as names, dates, or " @@ -5937,11 +5483,10 @@ msgstr "Prikaži vse" msgid "" "Display charts on a map. For using this plugin, users first have to " "create any other chart that can then be placed on the map." -msgstr "" +msgstr "Prikaže grafikone na zemljevidu. Za uporabo tega vtičnika morajo uporabniki najprej ustvariti drug grafikon, ki ga nato lahko postavijo na zemljevid." -#, fuzzy msgid "Display column in the chart" -msgstr "Prikaži vsoto na nivoju stolpca" +msgstr "Prikaz stolpca v grafikonu" msgid "Display column level subtotal" msgstr "Prikaži delno vsoto na nivoju stolpca" @@ -5949,60 +5494,50 @@ msgstr "Prikaži delno vsoto na nivoju stolpca" msgid "Display column level total" msgstr "Prikaži vsoto na nivoju stolpca" -#, fuzzy msgid "Display column name" -msgstr "Prikaži vsoto na nivoju stolpca" +msgstr "Prikaz imena stolpca" msgid "Display configuration" msgstr "Prikaži nastavitve" -#, fuzzy msgid "Display control configuration" -msgstr "Prikaži nastavitve" +msgstr "Konfiguracija nadzora zaslona" -#, fuzzy msgid "Display control has default value" -msgstr "Filter ima privzeto vrednost" +msgstr "Nadzor zaslona ima privzeto vrednost" -#, fuzzy msgid "Display control name" -msgstr "Prikaži vsoto na nivoju stolpca" +msgstr "Prikaz imena kontrolnika" -#, fuzzy msgid "Display control settings" -msgstr "Obdržim nastavitve kontrolnika?" +msgstr "Nastavitve nadzora zaslona" -#, fuzzy msgid "Display control type" -msgstr "Prikaži vsoto na nivoju stolpca" +msgstr "Vrsta nadzora zaslona" -#, fuzzy msgid "Display controls" -msgstr "Prikaži nastavitve" +msgstr "Kontrolniki prikaza" -#, fuzzy, python-format +#, python-format msgid "Display controls (%d)" -msgstr "Prikaži nastavitve" +msgstr "Kontrolniki prikaza (%d)" -#, fuzzy, python-format +#, python-format msgid "Display controls (%s)" -msgstr "Prikaži nastavitve" +msgstr "Kontrolniki prikaza (%s)" -#, fuzzy msgid "Display cumulative total at end" -msgstr "Prikaži vsoto na nivoju stolpca" +msgstr "Prikaži kumulativno vsoto na koncu" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, pt_BR, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Display headers for each column at the top of the matrix" -msgstr "Prikaži glave za vsak stolpec na vrhu matrike" +msgstr "Prikažite glave za vsak stolpec na vrhu matrike" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, pt_BR, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Display labels for each row on the left side of the matrix" -msgstr "Prikaži oznake za vsako vrstico na levi strani matrike" +msgstr "Prikažite oznake za vsako vrstico na levi strani matrike" msgid "" "Display metrics side by side within each column, as opposed to each " @@ -6027,15 +5562,11 @@ msgstr "Prikaži vsoto na nivoju vrstice" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Display the last queried timestamp on charts in the dashboard view" -msgstr "" -"Prikaži časovni žig zadnje poizvedbe na grafikonih v pogledu nadzorne " -"plošče" +msgstr "Prikaži zadnji zahtevani časovni žig na grafikonih v pogledu nadzorne plošče" -#, fuzzy msgid "Display type icon" -msgstr "ikona binarnega tipa" +msgstr "Ikona vrste zaslona" msgid "" "Displays connections between entities in a graph structure. Useful for " @@ -6059,13 +5590,10 @@ msgstr "Ločilnik" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "" "Divides each category into subcategories based on the values in the " "dimension. It can be used to exclude intersections." -msgstr "" -"Razdeli vsako kategorijo na podkategorije glede na vrednosti v dimenziji." -" Lahko se uporabi za izključitev presečišč." +msgstr "Vsako kategorijo razdeli na podkategorije glede na vrednosti v dimenziji. Uporablja se lahko za izključitev križišč." msgid "Do you want a donut or a pie?" msgstr "Želite kolobar ali torto?" @@ -6076,54 +5604,42 @@ msgstr "Dokumentacija" msgid "Domain" msgstr "Domena" -#, fuzzy msgid "Don't refresh" -msgstr "Podatki osveženi" +msgstr "Ne osvežuj" -#, fuzzy msgid "Done" -msgstr "Brez" +msgstr "Končano" msgid "Donut" msgstr "Kolobar" -msgid "Dot size metric" -msgstr "" - msgid "Dotted" msgstr "Pikčasto" msgid "Download" msgstr "Prenesi" -msgid "Download Excel file" -msgstr "" - msgid "Download as Image" msgstr "Izvozi kot sliko" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fr, ja, lv, mi, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Download is on the way" -msgstr "Prenos poteka" +msgstr "Prenos se pripravlja" msgid "Download to CSV" msgstr "Izvozi kot CSV" -#, fuzzy msgid "Download to client" -msgstr "Izvozi kot CSV" +msgstr "Prenos v odjemalca" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fr, ja, lv, mi, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy, python-format +#, python-format msgid "" "Downloading %(rows)s rows based on the LIMIT configuration. If you want " "the entire result set, you need to adjust the LIMIT." -msgstr "" -"Prenaša se %(rows)s vrstic na podlagi konfiguracije LIMIT. Če želite " -"celoten nabor rezultatov, morate prilagoditi LIMIT." +msgstr "Prenos vrstic %(rows)s na podlagi konfiguracije LIMIT. Če želite celoten niz rezultatov, morate prilagoditi LIMIT." msgid "Draft" msgstr "Osnutek" @@ -6136,19 +5652,16 @@ msgstr "Povlecite in spustite elemente na zavihek" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "" "Drag columns and metrics here to customize tooltip content. Order matters" " - items will appear in the same order in tooltips. Click the button to " "manually select columns and metrics." msgstr "" -"Povlecite stolpce in meritve sem, da prilagodite vsebino namiga. Vrstni " -"red je pomemben – elementi se bodo prikazali v enakem vrstnem redu v " -"namigih. Kliknite gumb za ročno izbiro stolpcev in meritev." +"Sem povlecite stolpce in meritve, da prilagodite vsebino opisa orodja. Vrstni red je pomemben – elementi bodo prikazani v istem vrstnem redu v opisih " +"orodij. Kliknite gumb za ročno izbiro stolpcev in meritev." -#, fuzzy msgid "Drag to reorder" -msgstr "Surovi podatki" +msgstr "Povlecite za prerazporeditev" msgid "Draw a marker on data points. Only applicable for line types." msgstr "Nariši markerje na točke grafikona. Samo za črtne grafikone." @@ -6225,9 +5738,8 @@ msgstr "Spustite stolpec sem ali kliknite" msgid "Drop columns/metrics here or click" msgstr "Spustite stolpce/mere sem ali kliknite" -#, fuzzy msgid "Dttm" -msgstr "datum-čas" +msgstr "Dttm" msgid "Duplicate" msgstr "Dupliciraj" @@ -6247,17 +5759,16 @@ msgstr "" msgid "Duplicate dataset" msgstr "Dupliciraj podatkovni set" -#, fuzzy, python-format +#, python-format msgid "Duplicate folder name: %s" -msgstr "Podvojena imena stolpcev: %(columns)s" +msgstr "Podvojeno ime mape: %s" -#, fuzzy msgid "Duplicate role" -msgstr "Dupliciraj" +msgstr "Podvojena vloga" -#, fuzzy, python-format +#, python-format msgid "Duplicate role %(name)s" -msgstr "Podvojena imena stolpcev: %(columns)s" +msgstr "Podvojena vloga %(name)s" msgid "Duplicate tab" msgstr "Podvoji zavihek" @@ -6297,9 +5808,8 @@ msgstr "" "Trajanje (v sekundah) predpomnilnika metapodatkov za tabele v tej " "podatkovni bazi. Če ni nastavljeno, predpomnilnik ne poteče. " -#, fuzzy msgid "Duration Ms" -msgstr "Trajanje" +msgstr "Trajanje v ms" msgid "Duration in ms (1.40008 => 1ms 400µs 80ns)" msgstr "Trajanje v ms (1.40008 => 1ms 400µs 80ns)" @@ -6307,46 +5817,39 @@ msgstr "Trajanje v ms (1.40008 => 1ms 400µs 80ns)" msgid "Duration in ms (100.40008 => 100ms 400µs 80ns)" msgstr "Trajanje v ms (100.40008 => 100ms 400µs 80ns)" -#, fuzzy msgid "Duration in ms (10500 => 0:00:10.5)" -msgstr "Trajanje v ms (66000 => 1m 6s)" +msgstr "Trajanje v ms (10500 => 0:00:10,5)" msgid "Duration in ms (66000 => 1m 6s)" msgstr "Trajanje v ms (66000 => 1m 6s)" -#, fuzzy msgid "Duration in seconds" -msgstr "Vnesite trajanje v sekundah" +msgstr "Trajanje v sekundah" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, pt_BR, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Dynamic" msgstr "Dinamično" msgid "Dynamic Aggregation Function" msgstr "Dinamična agregacijska funkcija" -#, fuzzy msgid "Dynamic Section Label" -msgstr "Usmerjeni" +msgstr "Oznaka dinamičnega odseka" -#, fuzzy msgid "Dynamic group by" -msgstr "NOT GROUPED BY" +msgstr "Dinamična skupina po" -#, fuzzy msgid "Dynamic section description" -msgstr "Dinamična agregacijska funkcija" +msgstr "Dinamični opis razdelka" msgid "Dynamically search all filter values" msgstr "Dinamično poišče vse možnosti filtra" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Dynamically select grouping columns from a dataset" -msgstr "Dinamično izberi stolpce za grupiranje iz nabora podatkov" +msgstr "Dinamično izberite stolpce za združevanje iz nabora podatkov" #. do-not-translate msgid "ECharts" @@ -6354,9 +5857,8 @@ msgstr "ECharts" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "ECharts Options (JS object literals)" -msgstr "Možnosti ECharts (literali objektov JS)" +msgstr "Možnosti ECharts (predmetni literali JS)" #. do-not-translate msgid "EMAIL_REPORTS_CTA" @@ -6367,7 +5869,7 @@ msgstr "NAPAKA" #, python-format msgid "ERROR: %s" -msgstr "" +msgstr "NAPAKA: %s" msgid "Edge length" msgstr "Dolžina povezave" @@ -6382,15 +5884,15 @@ msgid "Edge width" msgstr "Debelina povezave" msgid "Edit" -msgstr "Urejanje" +msgstr "Uredi" -#, fuzzy, python-format +#, python-format msgid "Edit %s" -msgstr "Uredi poizvedbo" +msgstr "Uredi %s" -#, fuzzy, python-format +#, python-format msgid "Edit %s in modal" -msgstr "v modalnem oknu" +msgstr "Uredi %s v modalnem oknu" msgid "Edit CSS template properties" msgstr "Uredi lastnosti CSS predloge" @@ -6401,9 +5903,8 @@ msgstr "Uredi nadzorno ploščo" msgid "Edit Dataset " msgstr "Uredi podatkovni set " -#, fuzzy msgid "Edit Group" -msgstr "Uredi pravilo" +msgstr "Uredi skupino" msgid "Edit Log" msgstr "Uredi dnevnik" @@ -6411,9 +5912,8 @@ msgstr "Uredi dnevnik" msgid "Edit Plugin" msgstr "Uredi vtičnik" -#, fuzzy msgid "Edit Role" -msgstr "načinu urejanja" +msgstr "Uredi vlogo" msgid "Edit Rule" msgstr "Uredi pravilo" @@ -6421,11 +5921,9 @@ msgstr "Uredi pravilo" msgid "Edit Tag" msgstr "Uredi oznako" -#, fuzzy msgid "Edit User" -msgstr "Uredi poizvedbo" +msgstr "Uredi uporabnika" -#, fuzzy msgid "Edit alert" msgstr "Uredi opozorilo" @@ -6456,25 +5954,21 @@ msgstr "Uredi e-poštno poročilo" msgid "Edit formatter" msgstr "Uredi oblikovanje" -#, fuzzy msgid "Edit group" -msgstr "Uredi pravilo" +msgstr "Uredi skupino" msgid "Edit properties" msgstr "Uredi lastnosti" msgid "Edit query" -msgstr "" +msgstr "Uredi poizvedbo" -#, fuzzy msgid "Edit report" msgstr "Uredi poročilo" -#, fuzzy msgid "Edit role" -msgstr "načinu urejanja" +msgstr "Uredi vlogo" -#, fuzzy msgid "Edit tag" msgstr "Uredi oznako" @@ -6487,16 +5981,14 @@ msgstr "Uredi parametre predloge" msgid "Edit the dashboard" msgstr "Uredi nadzorno ploščo" -#, fuzzy msgid "Edit theme properties" -msgstr "Uredi lastnosti" +msgstr "Uredi lastnosti teme" msgid "Edit time range" msgstr "Uredi časovno obdobje" -#, fuzzy msgid "Edit user" -msgstr "Uredi poizvedbo" +msgstr "Uredi uporabnika" msgid "Editable" msgstr "Uredljivo" @@ -6541,27 +6033,23 @@ msgstr "" msgid "Either the username or the password is wrong." msgstr "Uporabniško ime ali/in geslo sta napačna." -#, fuzzy msgid "Elapsed" -msgstr "Ponovno naloži" +msgstr "Preteklo" msgid "Elevation" msgstr "Višina" -#, fuzzy msgid "Email" -msgstr "Podrobnosti" +msgstr "E-pošta" -#, fuzzy msgid "Email is required" -msgstr "Zahtevana je vrednost" +msgstr "E-pošta je obvezna" -#, fuzzy msgid "Email link" -msgstr "Podrobnosti" +msgstr "E-poštna povezava" msgid "Email recipients" -msgstr "" +msgstr "Prejemniki e-pošte" msgid "Email reports active" msgstr "E-poštna poročila aktivna" @@ -6610,7 +6098,6 @@ msgstr "Omogoči 'Dovoli nalaganje podatkov' v nastavitvah vseh podatkovnih baz" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, pt_BR, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Enable Matrixify" msgstr "Omogoči Matrixify" @@ -6632,17 +6119,24 @@ msgstr "Omogoči napovedovanje" msgid "Enable graph roaming" msgstr "Omogoči preoblikovanje grafikona" -#, fuzzy +# Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, +# lv, pt_BR, ru, sk, sr, sr_Latn, tr, uk] +msgid "Enable icon JavaScript mode" +msgstr "Omogoči način JavaScript ikon" + msgid "Enable icons" -msgstr "Stolpci tabele" +msgstr "Omogoči ikone" + +# Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, +# lv, pt_BR, ru, sk, sr, sr_Latn, tr, uk] +msgid "Enable label JavaScript mode" +msgstr "Omogoči način JavaScript oznake" -#, fuzzy msgid "Enable labels" -msgstr "Oznake razponov" +msgstr "Omogoči oznake" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "Enable matrixify" msgstr "Omogoči matrixify" @@ -6662,13 +6156,21 @@ msgstr "" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, pt_BR, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy +msgid "Enables custom icon configuration via JavaScript" +msgstr "Omogoča konfiguracijo ikon po meri prek JavaScripta" + +# Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, +# lv, pt_BR, ru, sk, sr, sr_Latn, tr, uk] +msgid "Enables custom label configuration via JavaScript" +msgstr "Omogoča konfiguracijo oznak po meri prek JavaScripta" + +# Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, +# lv, pt_BR, ru, sk, sr, sr_Latn, tr, uk] msgid "Enables rendering of icons for GeoJSON points" msgstr "Omogoča upodabljanje ikon za točke GeoJSON" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, pt_BR, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Enables rendering of labels for GeoJSON points" msgstr "Omogoča upodabljanje oznak za točke GeoJSON" @@ -6680,9 +6182,8 @@ msgstr "" "Prišlo je do neveljavnega NULL prostorskega vnosa," " poskusite ga izločiti s filtrom" -#, fuzzy msgid "Encrypted extra fields" -msgstr "Polja deljenih poizvedb" +msgstr "Šifrirana dodatna polja" msgid "End" msgstr "Konec" @@ -6690,16 +6191,14 @@ msgstr "Konec" msgid "End (Longitude, Latitude): " msgstr "Konec (zemljepisna dolžina, širina): " -#, fuzzy msgid "End (exclusive)" -msgstr "KONEC (NI VKLJUČEN)" +msgstr "Konec (ekskluzivno)" msgid "End Longitude & Latitude" msgstr "Končna Dolž. in Širina" -#, fuzzy msgid "End Time" -msgstr "Končni datum" +msgstr "Končni čas" msgid "End angle" msgstr "Končni kot" @@ -6713,13 +6212,12 @@ msgstr "Končni datum ni vključen v časovno obdobje" msgid "End date must be after start date" msgstr "Končni datum mora biti za začetnim" -#, fuzzy msgid "Ends With" -msgstr "Debelina povezave" +msgstr "Konča se z" -#, fuzzy, python-format +#, python-format msgid "Ends with (ILIKE %x)" -msgstr "Debelina povezave" +msgstr "Konča se z (ILIKE %x)" #, python-format msgid "Engine \"%(engine)s\" cannot be configured through parameters." @@ -6744,9 +6242,8 @@ msgstr "Vnesite primarne vpisne podatke" msgid "Enter a name for this sheet" msgstr "Vnesite ime te preglednice" -#, fuzzy msgid "Enter a part of the object name" -msgstr "Če želite zapolniti objekte" +msgstr "Vnesite del imena predmeta" msgid "Enter alert name" msgstr "Vnesite naslov opozorila" @@ -6759,24 +6256,20 @@ msgstr "Vklopi celozaslonski način" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, pt_BR, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Enter minimum and maximum values for the range filter" -msgstr "Vnesite minimalne in maksimalne vrednosti za filter obsega" +msgstr "Vnesite najmanjšo in največjo vrednost za filter obsega" msgid "Enter report name" msgstr "Vnesite naslov poročila" -#, fuzzy msgid "Enter the group's description" -msgstr "Skrij opis grafikona" +msgstr "Vnesite opis skupine" -#, fuzzy msgid "Enter the group's label" -msgstr "Vnesite naslov opozorila" +msgstr "Vnesite oznako skupine" -#, fuzzy msgid "Enter the group's name" -msgstr "Vnesite naslov opozorila" +msgstr "Vnesite ime skupine" #, python-format msgid "Enter the required %(dbModelName)s credentials" @@ -6784,49 +6277,41 @@ msgstr "Vnesite potrebne %(dbModelName)s vpisne podatke" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fr, ja, lv, mi, pt_BR, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Enter the unique project id for your database." -msgstr "Vnesite edinstveni ID projekta za vašo bazo podatkov." +msgstr "Vnesite enolični ID projekta za svojo bazo podatkov." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fr, ja, lv, mi, pt_BR, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Enter the user's email" -msgstr "Vnesite e-poštni naslov uporabnika" +msgstr "Vnesite e-pošto uporabnika" -#, fuzzy msgid "Enter the user's first name" -msgstr "Vnesite naslov opozorila" +msgstr "Vnesite ime uporabnika" -#, fuzzy msgid "Enter the user's last name" -msgstr "Vnesite naslov opozorila" +msgstr "Vnesite priimek uporabnika" -#, fuzzy msgid "Enter the user's password" -msgstr "Vnesite naslov opozorila" +msgstr "Vnesite geslo uporabnika" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fr, ja, lv, mi, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Enter the user's username" msgstr "Vnesite uporabniško ime uporabnika" -#, fuzzy msgid "Enter theme name" -msgstr "Vnesite naslov opozorila" +msgstr "Vnesite ime teme" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, pt_BR, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Enter your login and password below:" -msgstr "Vnesite svoje prijavne podatke in geslo spodaj:" +msgstr "Spodaj vnesite svojo prijavo in geslo:" msgid "Entity" msgstr "Entiteta" msgid "Entries per page" -msgstr "" +msgstr "Vnosov na stran" msgid "Equal Date Sizes" msgstr "Enaki datumi" @@ -6834,9 +6319,8 @@ msgstr "Enaki datumi" msgid "Equal to (=)" msgstr "Je enako (=)" -#, fuzzy msgid "Equals" -msgstr "Sekvenčni" +msgstr "Enako" msgid "Error" msgstr "Napaka" @@ -6844,34 +6328,31 @@ msgstr "Napaka" msgid "Error Fetching Tagged Objects" msgstr "Pri pridobivanju označenih elementov je prišlo do napake" -#, fuzzy, python-format +#, python-format msgid "Error deleting %s" -msgstr "Napaka pri pridobivanju podatkov: %s" +msgstr "Napaka pri brisanju %s" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, es, sr, # sr_Latn] -#, fuzzy, python-format +#, python-format msgid "Error disabling fullscreen: %s" msgstr "Napaka pri onemogočanju celozaslonskega načina: %s" -#, fuzzy, python-format +#, python-format msgid "Error enabling fullscreen: %s" -msgstr "Napaka pri pridobivanju podatkov: %s" +msgstr "Napaka pri omogočanju celozaslonskega načina: %s" -#, fuzzy msgid "Error executing query. " -msgstr "Zagnana poizvedba" +msgstr "Napaka pri izvajanju poizvedbe. " msgid "Error faving chart" msgstr "Napaka pri dodajanju grafikona med priljubljene" -#, fuzzy msgid "Error fetching charts" msgstr "Napaka pri pridobivanju grafikonov" -#, fuzzy msgid "Error importing theme." -msgstr "Napaka obdelave" +msgstr "Napaka pri uvozu teme." #, python-format msgid "Error in jinja expression in RLS filters: %(msg)s" @@ -6881,25 +6362,25 @@ msgstr "Napaka v jinja izrazu RLS filtrov: %(msg)s" msgid "Error in jinja expression in WHERE clause: %(msg)s" msgstr "Napaka v jinja izrazu WHERE stavka: %(msg)s" -#, fuzzy, python-format +#, python-format msgid "Error in jinja expression in adhoc column: %(msg)s" -msgstr "Napaka v jinja izrazu WHERE stavka: %(msg)s" +msgstr "Napaka v izrazu jinja v adhoc stolpcu: %(msg)s" -#, fuzzy, python-format +#, python-format msgid "Error in jinja expression in column expression: %(msg)s" -msgstr "Napaka v jinja izrazu WHERE stavka: %(msg)s" +msgstr "Napaka v izrazu jinja v izrazu stolpca: %(msg)s" -#, fuzzy, python-format +#, python-format msgid "Error in jinja expression in datetime column: %(msg)s" -msgstr "Napaka v jinja izrazu WHERE stavka: %(msg)s" +msgstr "Napaka v izrazu jinja v stolpcu datuma in časa: %(msg)s" #, python-format msgid "Error in jinja expression in fetch values predicate: %(msg)s" msgstr "Napaka v jinja izrazu za pridobivanje vrednosti predikatov: %(msg)s" -#, fuzzy, python-format +#, python-format msgid "Error in jinja expression in metric expression: %(msg)s" -msgstr "Napaka v jinja izrazu za pridobivanje vrednosti predikatov: %(msg)s" +msgstr "Napaka v izrazu jinja v metričnem izrazu: %(msg)s" msgid "Error loading chart datasources. Filters may not work correctly." msgstr "" @@ -6934,13 +6415,11 @@ msgstr "Napaka pri pridobivanju grafikonov" msgid "Error while fetching data: %s" msgstr "Napaka pri pridobivanju podatkov: %s" -#, fuzzy msgid "Error while fetching groups" -msgstr "Napaka pri pridobivanju grafikonov" +msgstr "Napaka pri pridobivanju skupin" -#, fuzzy msgid "Error while fetching roles" -msgstr "Napaka pri pridobivanju grafikonov" +msgstr "Napaka pri pridobivanju vlog" #, python-format msgid "Error while rendering virtual dataset query: %(msg)s" @@ -6954,9 +6433,9 @@ msgstr "Napaka: %(error)s" msgid "Error: %(msg)s" msgstr "Napaka: %(msg)s" -#, fuzzy, python-format +#, python-format msgid "Error: %s" -msgstr "Napaka: %(msg)s" +msgstr "Napaka: %s" msgid "Error: permalink state not found" msgstr "Napaka: stanje povezave ni najdeno" @@ -6990,7 +6469,6 @@ msgstr "Natančno" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "Exact match (IN)" msgstr "Natančno ujemanje (IN)" @@ -7000,23 +6478,17 @@ msgstr "Primer" msgid "Examples" msgstr "Vzorci" -#, fuzzy msgid "Excel Export" -msgstr "Tedensko poročilo" +msgstr "Izvoz v Excel" -#, fuzzy msgid "Excel XML Export" -msgstr "Tedensko poročilo" - -msgid "Excel export is not configured on this server." -msgstr "" +msgstr "Izvoz v Excel XML" msgid "Excel file format cannot be determined" msgstr "Ni mogoče določiti formata Excel-ove datoteke" -#, fuzzy msgid "Excel upload" -msgstr "Nalaganje Excel-a" +msgstr "Nalaganje v Excel" msgid "Exclude selected values" msgstr "Izloči izbrane vrednosti" @@ -7039,16 +6511,12 @@ msgstr "Dnevnik izvajanja" msgid "Existing dataset" msgstr "Obstoječ podatkovni set" -msgid "Exit edit mode" -msgstr "" - msgid "Exit fullscreen" msgstr "Izhod iz celozaslonskega načina" msgid "Expand" msgstr "Razširi" -#, fuzzy msgid "Expand All" msgstr "Razširi vse" @@ -7061,9 +6529,8 @@ msgstr "Razširi podatkovni panel" msgid "Expand row" msgstr "Razširi vrstico" -#, fuzzy msgid "Expand row to edit" -msgstr "Razširi vrstico" +msgstr "Razširite vrstico za urejanje" msgid "" "Expects a formula with depending time parameter 'x'\n" @@ -7079,9 +6546,8 @@ msgstr "" msgid "Experimental" msgstr "Eksperimentalno" -#, fuzzy msgid "Expired" -msgstr "Raziskovanje" +msgstr "Poteklo" msgid "Explore" msgstr "Raziskovanje" @@ -7096,65 +6562,51 @@ msgstr "Raziščite rezultate v pogledu za raziskovanje podatkov" msgid "Export" msgstr "Izvoz" -#, fuzzy msgid "Export All Data" -msgstr "Počisti vse podatke" +msgstr "Izvozi vse podatke" -#, fuzzy msgid "Export Current View" -msgstr "Invertiraj trenutno stran" - -msgid "Export Data to Excel" -msgstr "" +msgstr "Izvozi trenutni pogled" -msgid "Export Images to Excel" -msgstr "" - -#, fuzzy msgid "Export YAML" -msgstr "Naslov poročila" +msgstr "Izvozi YAML" -#, fuzzy msgid "Export as Example" -msgstr "Izvozi v Excel" +msgstr "Izvozi kot primer" msgid "Export as PDF" -msgstr "" +msgstr "Izvozi kot PDF" -#, fuzzy msgid "Export cancelled" -msgstr "Poročilo ni uspelo" +msgstr "Izvoz preklican" msgid "Export dashboards?" msgstr "Izvozim nadzorne plošče?" -#, fuzzy msgid "Export failed" -msgstr "Poročilo ni uspelo" +msgstr "Izvoz ni uspel" -#, fuzzy msgid "Export failed - please try again" -msgstr "Prenos slike ni uspel. Osvežite in poskusite ponovno." +msgstr "Izvoz ni uspel - poskusite znova" -#, fuzzy, python-format +#, python-format msgid "Export failed: %s" -msgstr "Poročilo ni uspelo" +msgstr "Izvoz ni uspel: %s" msgid "Export query" -msgstr "" +msgstr "Izvozi poizvedbo" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Export screenshot (jpeg)" msgstr "Izvozi posnetek zaslona (jpeg)" msgid "Export screenshot (png)" -msgstr "" +msgstr "Izvozi posnetek zaslona (PNG)" -#, fuzzy, python-format +#, python-format msgid "Export successful: %s" -msgstr "Izvozi v celoten .CSV" +msgstr "Izvoz je uspel: %s" msgid "Export to .CSV" msgstr "Izvozi v .CSV" @@ -7162,9 +6614,8 @@ msgstr "Izvozi v .CSV" msgid "Export to .JSON" msgstr "Izvozi v .JSON" -#, fuzzy msgid "Export to CSV" -msgstr "Izvozi v .CSV" +msgstr "Izvozi v CSV" msgid "Export to Excel" msgstr "Izvozi v Excel" @@ -7175,9 +6626,8 @@ msgstr "Izvozi v PDF" msgid "Export to Pivoted .CSV" msgstr "Izvozi v vrtilni .CSV" -#, fuzzy msgid "Export to Pivoted Excel" -msgstr "Izvozi v vrtilni .CSV" +msgstr "Izvozi v Pivoted Excel" msgid "Export to full .CSV" msgstr "Izvozi v celoten .CSV" @@ -7195,12 +6645,12 @@ msgstr "Izvozi v vrtilni .CSV" msgid "" "Exporting semantic views is not supported yet — %s semantic-view row(s) " "were skipped." -msgstr "" +msgstr "Izvoz semantičnih pogledov še ni podprt — preskočenih je bilo %s vrstic semantičnih pogledov." msgid "" "Exporting semantic views is not supported yet. Deselect the semantic-view" " rows and try again." -msgstr "" +msgstr "Izvoz semantičnih pogledov še ni podprt. Prekličite izbor vrstic semantičnih pogledov in poskusite znova." msgid "Expose database in SQL Lab" msgstr "Prikaži podatkovno bazo v SQL laboratoriju" @@ -7208,33 +6658,22 @@ msgstr "Prikaži podatkovno bazo v SQL laboratoriju" msgid "Expose in SQL Lab" msgstr "Uporabi v SQL laboratoriju" -#, fuzzy msgid "Expression" -msgstr "SQL-izraz" +msgstr "Izraz" -#, fuzzy msgid "Expression cannot be empty" -msgstr "ne sme biti prazno" - -#, python-format -msgid "" -"Extension '%(extension_id)s' has exceeded its persistent storage quota of" -" %(quota)d bytes." -msgstr "" +msgstr "Izraz ne sme biti prazen" -#, fuzzy msgid "Extensions" -msgstr "Dimenzije" +msgstr "Razširitve" -#, fuzzy msgid "Extent" -msgstr "nedavno" +msgstr "Obseg" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "External link warning" -msgstr "Opozorilo o zunanjem linku" +msgstr "Opozorilo o zunanji povezavi" msgid "Extra" msgstr "Dodatno" @@ -7245,6 +6684,9 @@ msgstr "Dodatni kontrolniki" msgid "Extra Parameters" msgstr "Dodatni parametri" +msgid "Extra data for JS" +msgstr "Dodatni podatki za JS" + #, python-brace-format msgid "" "Extra data to specify table metadata. Currently supports metadata of the " @@ -7287,7 +6729,6 @@ msgstr "Faktor, s katerim množite mero" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fr, ja, lv, mi, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Fail login count" msgstr "Število neuspešnih prijav" @@ -7299,37 +6740,21 @@ msgstr "Napaka pri pridobivanju rezultatov" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Failed to apply theme: Invalid JSON" -msgstr "Teme ni bilo mogoče uporabiti: neveljavna vrednost JSON" +msgstr "Teme ni bilo mogoče uporabiti: neveljaven JSON" -#, fuzzy msgid "Failed to copy API key to clipboard" -msgstr "Kopiraj particijsko poizvedbo na odložišče" +msgstr "Ključa API-ja ni bilo mogoče kopirati v odložišče" -#, fuzzy msgid "Failed to copy stack trace to clipboard" -msgstr "Kopiraj na odložišče" +msgstr "Kopiranje sledi sklada v odložišče ni uspelo" -#, fuzzy msgid "Failed to create API key" -msgstr "Ustvarjanje poročila nesupešno" +msgstr "Ključa API ni bilo mogoče ustvariti" msgid "Failed to create report" msgstr "Ustvarjanje poročila nesupešno" -#, python-format -msgid "Failed to delete %(name)s" -msgstr "" - -#, python-format -msgid "Failed to delete %(name)s: %(errMsg)s" -msgstr "" - -#, python-format -msgid "Failed to establish an SSH tunnel to the database: %(reason)s" -msgstr "" - #, python-format msgid "Failed to execute %(query)s" msgstr "Neuspešno izvajanje %(query)s" @@ -7337,18 +6762,17 @@ msgstr "Neuspešno izvajanje %(query)s" msgid "" "Failed to export chart data. Please try again or contact your " "administrator." -msgstr "" +msgstr "Podatkov grafikona ni bilo mogoče izvoziti. Poskusite znova ali se obrnite na skrbnika." -#, fuzzy msgid "Failed to fetch API keys" -msgstr "Napaka pri označevanju elementov" +msgstr "Ključev API ni bilo mogoče pridobiti" msgid "Failed to generate chart edit URL" msgstr "Neuspešno ustvarjanje URL za urejanje grafikona" -#, fuzzy, python-format +#, python-format msgid "Failed to generate download: %s" -msgstr "Neuspešno ustvarjanje URL za urejanje grafikona" +msgstr "Prenosa ni bilo mogoče ustvariti: %s" msgid "Failed to load chart data" msgstr "Neuspešno nalaganje podatkov grafikona" @@ -7356,100 +6780,83 @@ msgstr "Neuspešno nalaganje podatkov grafikona" msgid "Failed to load chart data." msgstr "Neuspešno nalaganje podatkov grafikona." -#, fuzzy, python-format +#, python-format msgid "Failed to load columns for %s %s" -msgstr "Neuspešno nalaganje podatkov grafikona" +msgstr "Nalaganje stolpcev za %s %s ni uspelo" -#, fuzzy msgid "Failed to load top values" -msgstr "Neuspešno ustavljanje poizvedbe. %s" +msgstr "Najpogostejših vrednosti ni bilo mogoče naložiti" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Failed to open file. Please try again." msgstr "Datoteke ni bilo mogoče odpreti. Poskusite znova." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy, python-format -msgid "Failed to remove system dark theme: %s" -msgstr "Sistemske temne teme ni bilo mogoče odstraniti: %s" - -#, fuzzy, python-format -msgid "Failed to remove system default theme: %s" -msgstr "Preverjanje možnosti izbire ni uspelo: %s" - #, python-format -msgid "Failed to restore %(name)s" -msgstr "" +msgid "Failed to remove system dark theme: %s" +msgstr "Temne teme sistema ni bilo mogoče odstraniti: %s" #, python-format -msgid "Failed to restore %(name)s: %(errMsg)s" -msgstr "" +msgid "Failed to remove system default theme: %s" +msgstr "Privzete sistemske teme ni bilo mogoče odstraniti: %s" msgid "Failed to retrieve advanced type" msgstr "Napaka pri pridobivanju naprednega tipa" -#, fuzzy msgid "Failed to revoke API key" -msgstr "Neuspešno ustavljanje poizvedbe. %s" +msgstr "Ključa API-ja ni bilo mogoče preklicati" -#, fuzzy msgid "Failed to save chart customization" -msgstr "Neuspešno nalaganje podatkov grafikona" +msgstr "Prilagajanja grafikona ni bilo mogoče shraniti" msgid "Failed to save cross-filter scoping" msgstr "Shranjevanje dosega medsebojnega filtra ni uspelo" -#, fuzzy msgid "Failed to save cross-filters setting" -msgstr "Shranjevanje dosega medsebojnega filtra ni uspelo" +msgstr "Nastavitev navzkrižnih filtrov ni bilo mogoče shraniti" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Failed to set local theme: Invalid JSON configuration" msgstr "Lokalne teme ni bilo mogoče nastaviti: neveljavna konfiguracija JSON" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy, python-format +#, python-format msgid "Failed to set system dark theme: %s" -msgstr "Sistemske temne teme ni bilo mogoče nastaviti: %s" +msgstr "Temne teme sistema ni bilo mogoče nastaviti: %s" -#, fuzzy, python-format +#, python-format msgid "Failed to set system default theme: %s" -msgstr "Preverjanje možnosti izbire ni uspelo: %s" +msgstr "Sistemske privzete teme ni bilo mogoče nastaviti: %s" msgid "Failed to start remote query on a worker." msgstr "Na delavcu ni bilo mogoče zagnati oddaljene poizvedbe." -#, fuzzy msgid "Failed to stop query." -msgstr "Neuspešno ustavljanje poizvedbe. %s" +msgstr "Poizvedbe ni bilo mogoče ustaviti." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Failed to store query results. Please try again." -msgstr "Rezultatov poizvedbe ni bilo mogoče shraniti. Poskusite znova." +msgstr "Rezultatov poizvedbe ni bilo mogoče shraniti. Prosim poskusite ponovno." msgid "Failed to tag items" msgstr "Napaka pri označevanju elementov" #, python-format msgid "Failed to trigger %(alertType)s \"%(alertName)s\": %(error)s" -msgstr "" +msgstr "%(alertType)s »%(alertName)s« ni bilo mogoče sprožiti: %(error)s" msgid "Failed to update report" msgstr "Posodabljanje poročila neuspešno" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Failed to validate expression. Please try again." -msgstr "Izraza ni bilo mogoče preveriti. Poskusite znova." +msgstr "Izraza ni bilo mogoče potrditi. Prosim poskusite ponovno." #, python-format msgid "Failed to verify select options: %s" @@ -7457,20 +6864,17 @@ msgstr "Preverjanje možnosti izbire ni uspelo: %s" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Falling back to CSV; Excel export library not available." -msgstr "Preklapljam na CSV; knjižnica za izvoz v Excel ni na voljo." +msgstr "Nazaj na CSV; Izvozna knjižnica Excel ni na voljo." -#, fuzzy msgid "False" -msgstr "Je FALSE" +msgstr "Ne" msgid "Favorite" msgstr "Priljubljeno" -#, fuzzy msgid "Feature Not Enabled" -msgstr "SSH-tunel ni omogočen" +msgstr "Funkcija ni omogočena" msgid "Featured" msgstr "Ustvarjene" @@ -7491,9 +6895,8 @@ msgstr "Pridobljeno %s" msgid "Fetching" msgstr "Pridobivam" -#, fuzzy msgid "Fetching data..." -msgstr "pridobivanje" +msgstr "Pridobivanje podatkov ..." #, python-format msgid "Field cannot be decoded by JSON. %(json_error)s" @@ -7503,9 +6906,8 @@ msgstr "Polja ni mogoče dekodirati z JSON. %(json_error)s" msgid "Field cannot be decoded by JSON. %(msg)s" msgstr "Polja ni mogoče dekodirati z JSON. %(msg)s" -#, fuzzy msgid "Field cannot be empty." -msgstr "ne sme biti prazno" +msgstr "Polje ne sme biti prazno." msgid "Field is required" msgstr "Polje je obvezno" @@ -7515,15 +6917,11 @@ msgstr "Končnica datoteke ni dovoljena." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "" "File handling is not supported in this browser. Please use a modern " "browser like Chrome or Edge." -msgstr "" -"Ravnanje z datotekami ni podprto v tem brskalniku. Prosimo, uporabite " -"sodoben brskalnik, kot je Chrome ali Edge." +msgstr "Upravljanje datotek ni podprto v tem brskalniku. Uporabite sodoben brskalnik, kot sta Chrome ali Edge." -#, fuzzy msgid "File settings" msgstr "Nastavitve datoteke" @@ -7541,9 +6939,8 @@ msgstr "Način polnjenja" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Fill out the registration form" -msgstr "Izpolnite registracijski obrazec" +msgstr "Izpolnite obrazec za registracijo" msgid "Filled" msgstr "Zapolnjeno" @@ -7575,9 +6972,8 @@ msgstr "Ime filtra" msgid "Filter only displays values relevant to selections made in other filters." msgstr "Filter prikazuje samo vrednosti vezane na izbire v drugih filtrih." -#, fuzzy msgid "Filter options" -msgstr "Nastavitve filtra" +msgstr "Možnosti filtra" msgid "Filter results" msgstr "Filtriraj rezultate" @@ -7600,9 +6996,8 @@ msgstr "Filtriraj grafikone" msgid "Filters" msgstr "Filtri" -#, fuzzy msgid "Filters and controls" -msgstr "Dodatni kontrolniki" +msgstr "Filtri in kontrole" msgid "Filters by columns" msgstr "Filtrira po stolpcu" @@ -7615,17 +7010,14 @@ msgstr "Filtri za primerjavo morajo imeti vrednost" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fr, ja, lv, mi, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Filters for values equal to this exact value." -msgstr "Filtrira vrednosti, ki so enake tej točni vrednosti." +msgstr "Filtrira vrednosti, ki so enake tej natančni vrednosti." -#, fuzzy msgid "Filters for values greater than or equal." -msgstr "`row_limit` mora biti večja ali enaka 0" +msgstr "Filtrira vrednosti, ki so večje ali enake." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fr, ja, lv, mi, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Filters for values less than or equal." msgstr "Filtrira vrednosti, ki so manjše ali enake." @@ -7661,24 +7053,19 @@ msgstr "Zaključi" msgid "First" msgstr "Prvi" -#, fuzzy msgid "First Name" -msgstr "Ime grafikona" +msgstr "Ime" -#, fuzzy msgid "First name" -msgstr "Ime grafikona" +msgstr "Ime" -#, fuzzy msgid "First name is required" -msgstr "Zahtevano je ime" +msgstr "Ime je obvezno" -#, fuzzy msgid "Fit columns dynamically" -msgstr "Razvrsti stolpce po abecedi" +msgstr "Dinamično prilagajanje stolpcev" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: lv] -#, fuzzy msgid "Fit data" msgstr "Prilagodi podatkom" @@ -7707,13 +7094,11 @@ msgstr "Fiksni radij točk" msgid "Flow" msgstr "Potek" -#, fuzzy msgid "Folder with content must have a name" -msgstr "Filtri za primerjavo morajo imeti vrednost" +msgstr "Mapa z vsebino mora imeti ime" -#, fuzzy msgid "Folders" -msgstr "Filtri" +msgstr "Mape" msgid "Font size" msgstr "Velikost pisave" @@ -7744,19 +7129,19 @@ msgstr "" msgid "For further instructions, consult the" msgstr "Za nadaljnja navodila se posvetujte z" -#, fuzzy +msgid "For more information about objects are in context in the scope of this function, refer to the" +msgstr "Za dodatne informacije o objektih v kontekstu te funkcije si oglejte" + msgid "" "For regular filters, these are the subjects (users, roles, groups) this " "filter will be applied to. For base filters, these are the subjects that " "the filter DOES NOT apply to, e.g. Admin if admin should see all data." msgstr "" -"Za navadne filtre so te vloge tiste, ki bodo filtrirane. Za osnovne " -"filtre, so te vloge tiste, ki NE bodo filtrirane, npr. Admin, če naj " -"administrator vidi vse podatke." +"Pri običajnih filtrih so to subjekti (uporabniki, vloge, skupine), za katere bo ta filter uporabljen. Pri osnovnih filtrih so to subjekti, za katere filter " +"NE VELJA, npr. Administrator, če mora skrbnik videti vse podatke." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Forbidden" msgstr "Prepovedano" @@ -7765,15 +7150,13 @@ msgstr "Sila" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Force Time Grain as Max Interval" -msgstr "Prisili časovno zrnatost kot največji interval" +msgstr "Vsili časovno zrnatost kot največji interval" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "Force abort (stops task for all subscribers)" -msgstr "Prisili prekinitev (ustavi opravilo za vse naročnike)" +msgstr "Prisilna prekinitev (ustavi opravilo za vse naročnike)" msgid "" "Force all tables and views to be created in this schema when clicking " @@ -7791,9 +7174,8 @@ msgstr "Vsili obliko zapisa datuma" msgid "Force refresh" msgstr "Osveži" -#, fuzzy msgid "Force refresh Slack channels list" -msgstr "Osveži seznam shem" +msgstr "Prisilno osveži seznam kanalov Slack" msgid "Force refresh catalog list" msgstr "Vsili osvežitev seznama katalogov" @@ -7806,15 +7188,14 @@ msgstr "Osveži seznam tabel" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Forces selected Time Grain as the maximum interval for X Axis Labels" -msgstr "Prisili izbrano časovno zrnatost kot največji interval za oznake osi X" +msgstr "Vsili izbrano časovno zrnatost kot največji interval za oznake osi X" msgid "Forecast periods" msgstr "Periode napovedi" msgid "Forecast requires at least 2 data points" -msgstr "" +msgstr "Napoved zahteva vsaj dve podatkovni točki" msgid "Foreign key" msgstr "Tuji ključ" @@ -7832,20 +7213,17 @@ msgstr "" "Podatkov ni mogoče najti v predpomnilniku. Uporabljeni bodo metapodatki " "podatkovnega seta." -#, fuzzy msgid "Format" -msgstr "Oblikovan datum" +msgstr "Oblika" -#, fuzzy msgid "Format JSON configuration" -msgstr "Konfiguracija stolpca" +msgstr "Oblikujte konfiguracijo JSON" msgid "Format SQL" msgstr "Oblikuj SQL" -#, fuzzy msgid "Format SQL query" -msgstr "Oblikuj SQL" +msgstr "Oblikujte poizvedbo SQL" #, python-brace-format msgid "" @@ -7859,24 +7237,20 @@ msgstr "" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "" "Format metrics or columns with currency symbols as prefixes or suffixes. " "Choose a symbol manually or use 'Auto-detect' to apply the correct symbol" " based on the dataset's currency code column. When multiple currencies " "are present, formatting falls back to neutral numbers." msgstr "" -"Oblikujte metrike ali stolpce z valutnimi simboli kot predponami ali " -"priponami. Izberite simbol ročno ali uporabite 'Samodejno zaznavanje', da" -" se na podlagi stolpca z valutno kodo v naboru podatkov uporabi pravilen " -"simbol. Kadar je prisotnih več valut, se oblikovanje vrne na nevtralne " -"številke." +"Oblikujte meritve ali stolpce s simboli valut kot predponami ali priponami. Ročno izberite simbol ali uporabite »Samodejno zaznaj«, da uporabite pravilen " +"simbol na podlagi stolpca kode valute nabora podatkov. Če je prisotnih več valut, se formatiranje vrne na nevtralne številke." msgid "Formatted CSV attached in email" msgstr "Oblikovan CSV pripet e-pošti" msgid "Formatted Excel attached in email" -msgstr "" +msgstr "Oblikovana datoteka Excel je priložena e-pošti" msgid "Formatted value" msgstr "Oblikovana vrednost" @@ -7884,13 +7258,11 @@ msgstr "Oblikovana vrednost" msgid "Formatting" msgstr "Oblikovanje" -#, fuzzy msgid "Formatting column" -msgstr "Oblikovanje" +msgstr "Stolpec za oblikovanje" -#, fuzzy msgid "Formatting object" -msgstr "Oblikovanje" +msgstr "Objekt za oblikovanje" msgid "Formula" msgstr "Formula" @@ -7922,9 +7294,8 @@ msgstr "Začetni datum ne sme biti večji od končnega" msgid "Full name" msgstr "Celotno ime" -#, fuzzy msgid "Fullscreen is not supported in this browser." -msgstr "Vrtanje po še ni podprto za grafikon tega tipa" +msgstr "Celozaslonski način ni podprt v tem brskalniku." msgid "Funnel Chart" msgstr "Lijakasti grafikon" @@ -7939,19 +7310,15 @@ msgstr "Dodatne prilagoditve prikaza posameznih mer" msgid "GROUP BY" msgstr "GROUP BY" -#, fuzzy msgid "Gantt Chart" -msgstr "Graf" +msgstr "Ganttov grafikon" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "" "Gantt chart visualizes important events over a time span. Every data " "point displayed as a separate event along a horizontal line." -msgstr "" -"Ganttov grafikon prikazuje pomembne dogodke v časovnem obdobju. Vsaka " -"podatkovna točka je prikazana kot ločen dogodek vzdolž vodoravne črte." +msgstr "Ganttogram vizualizira pomembne dogodke v določenem časovnem obdobju. Vsaka podatkovna točka je prikazana kot ločen dogodek vzdolž vodoravne črte." msgid "Gauge Chart" msgstr "Števčni grafikon" @@ -7962,9 +7329,8 @@ msgstr "Splošno" msgid "General information" msgstr "Splošne informacije" -#, fuzzy msgid "General settings" -msgstr "GeoJson nastavitve" +msgstr "Splošne nastavitve" msgid "Generating link, please wait.." msgstr "Ustvarjam povezavo, prosim počakajte..." @@ -7984,9 +7350,8 @@ msgstr "GeoJson nastavitve" msgid "Geohash" msgstr "Geohash" -#, fuzzy msgid "Geometry Column" -msgstr "Prazen stolpec" +msgstr "Geometrijski stolpec" msgid "Get the last date by the date unit." msgstr "Pridobi zadnji datum glede na časovno enoto." @@ -8011,9 +7376,8 @@ msgstr "Ime Googlove preglednice in URL" msgid "Grace period" msgstr "Obdobje mirovanja" -#, fuzzy msgid "Grain" -msgstr "Granulacija časa" +msgstr "Zrnatost" msgid "Graph Chart" msgstr "Graf" @@ -8024,13 +7388,11 @@ msgstr "Izgled grafikona" msgid "Gravity" msgstr "Gravitacija" -#, fuzzy msgid "Greater Than" -msgstr "Večje kot (>)" +msgstr "Večji od" -#, fuzzy msgid "Greater Than or Equal" -msgstr "Večje ali enako (>=)" +msgstr "Večje od ali enako" msgid "Greater or equal (>=)" msgstr "Večje ali enako (>=)" @@ -8047,13 +7409,11 @@ msgstr "Mreža" msgid "Grid Size" msgstr "Velikost mreže" -#, fuzzy msgid "Grid view" -msgstr "Velikost mreže" +msgstr "Mrežni pogled" -#, fuzzy msgid "Group" -msgstr "Združevanje po (Group by)" +msgstr "Skupina" msgid "Group By" msgstr "Združevanje po (Group by)" @@ -8069,35 +7429,27 @@ msgstr "Združevanje po (Group by)" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Group remaining as \"Others\"" -msgstr "Preostale razvrsti v skupino \"Ostalo\"" +msgstr "Skupina ostane kot »Drugi«" -#, fuzzy msgid "Grouping" -msgstr "Doseg" +msgstr "Združevanje v skupine" -#, fuzzy msgid "Groups" -msgstr "Združevanje po (Group by)" +msgstr "Skupine" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "" "Groups remaining series into an \"Others\" category when series limit is " "reached. This prevents incomplete time series data from being displayed." -msgstr "" -"Preostale serije razvrsti v kategorijo \"Ostalo\", ko je dosežena " -"omejitev serij. S tem se prepreči prikaz nepopolnih podatkov časovnih " -"vrst." +msgstr "Združi preostale serije v kategorijo »Drugo«, ko je dosežena omejitev serije. To preprečuje prikaz nepopolnih časovnih vrst podatkov." msgid "Guest user cannot modify chart payload" msgstr "Gost ne more spreminjati atributov grafikona" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "HTTP Path" msgstr "Pot HTTP" @@ -8119,9 +7471,8 @@ msgstr "Glava" msgid "Header row" msgstr "Vrstica z glavo" -#, fuzzy msgid "Header row is required" -msgstr "Zahtevana je vrednost" +msgstr "Zahtevana je naslovna vrstica" msgid "Heatmap" msgstr "Toplotna karta" @@ -8129,20 +7480,17 @@ msgstr "Toplotna karta" msgid "Height" msgstr "Višina" -#, fuzzy msgid "Height of each row in pixels" -msgstr "Debelina plastnic v pikslih" +msgstr "Višina vsake vrstice v slikovnih pikah" msgid "Height of the sparkline" msgstr "Višina hitrega grafikona" -#, fuzzy msgid "Hidden" -msgstr "razveljavitev" +msgstr "Skrito" -#, fuzzy msgid "Hide Column" -msgstr "Časovni stolpec" +msgstr "Skrij stolpec" msgid "Hide Line" msgstr "Skrij črto" @@ -8210,7 +7558,6 @@ msgstr "Za koliko period v prihodnosti želite napoved" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "How many top values to select" msgstr "Koliko najvišjih vrednosti izbrati" @@ -8232,17 +7579,17 @@ msgstr "Oznake po ISO 3166-2" msgid "ISO 8601" msgstr "ISO 8601" -#, fuzzy +msgid "Icon JavaScript config generator" +msgstr "Generator konfiguracije JavaScript ikon" + msgid "Icon URL" -msgstr "Nadzor" +msgstr "URL ikone" -#, fuzzy msgid "Icon size" -msgstr "Velikost pisave" +msgstr "Velikost ikone" -#, fuzzy msgid "Icon size unit" -msgstr "Velikost pisave" +msgstr "Enota velikosti ikone" msgid "Id" msgstr "Id" @@ -8251,13 +7598,13 @@ msgid "Id of root node of the tree." msgstr "Id korenskega vozlišča drevesa." msgid "" -"If Presto or Trino, all the queries in SQL Lab are going to be executed " -"as the currently logged on user who must have permission to run them. If " -"Hive and hive.server2.enable.doAs is enabled, will run the queries as " -"service account, but impersonate the currently logged on user via " -"hive.server2.proxy.user property. If Databricks, uses OAuth2 to " -"authenticate as the currently logged on user." +"If Presto or Trino, all the queries in SQL Lab are going to be executed as the currently logged on user who must have permission to run them. If Hive and " +"hive.server2.enable.doAs is enabled, will run the queries as service account, but impersonate the currently logged on user via hive.server2.proxy.user " +"property." msgstr "" +"V primeru Presto ali Trino se vse poizvedbe v SQL laboratoriju zaženejo pod trenutno prijavljenim uporabnikom, ki mora imeti pravice za poganjanje. Če je " +"omogočen Hive in hive.server2.enable.doAs, poizvedbe tečejo pod servisnim računom, vendar je trenutno prijavljen uporabnik predstavljen z lastnostjo " +"hive.server2.proxy.user." msgid "If a metric is specified, sorting will be done based on the metric value" msgstr "Če je določena mera, bo razvrščanje izvedeno na podlagi vrednosti mere" @@ -8269,27 +7616,16 @@ msgstr "Če je omogočeno, so vrednosti razvrščene padajoče, drugače pa nara # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "" "If it stays empty, it won't be saved and will be removed from the list. " "To remove folders, move metrics and columns to other folders." -msgstr "" -"Če ostane prazno, ne bo shranjeno in bo odstranjeno s seznama. Če želite " -"odstraniti mape, premaknite metrike in stolpce v druge mape." +msgstr "Če ostane prazen, ne bo shranjen in bo odstranjen s seznama. Če želite odstraniti mape, premaknite meritve in stolpce v druge mape." -#, fuzzy msgid "If table already exists" -msgstr "Oznaka že obstaja" - -msgid "If you delete this item, you won't be able to recover it." -msgstr "" - -msgid "If you did not request this, you can ignore this email." -msgstr "" +msgstr "Če tabela že obstaja" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "If you don't save, changes will be lost." msgstr "Če ne shranite, bodo spremembe izgubljene." @@ -8308,10 +7644,8 @@ msgstr "Slika (PNG) vključena v e-pošto" msgid "Image download failed, please refresh and try again." msgstr "Prenos slike ni uspel. Osvežite in poskusite ponovno." -msgid "" -"Impersonate logged in user (Presto, Trino, Drill, Hive, Databricks, and " -"Google Sheets)" -msgstr "" +msgid "Impersonate logged in user (Presto, Trino, Drill, Hive, and Google Sheets)" +msgstr "Predstavljanje kot prijavljeni uporabnik (Presto, Trino, Drill, Hive in GSheets)" msgid "Import" msgstr "Uvozi" @@ -8320,9 +7654,8 @@ msgstr "Uvozi" msgid "Import %s" msgstr "Uvozi %s" -#, fuzzy msgid "Import Error" -msgstr "Napaka pretečenega časa" +msgstr "Napaka pri uvozu" msgid "Import chart failed for an unknown reason" msgstr "Uvoz grafikona ni uspel zaradi neznanega razloga" @@ -8351,47 +7684,38 @@ msgstr "Uvozi poizvedbe" msgid "Import saved query failed for an unknown reason." msgstr "Uvoz shranjene poizvedbe ni uspel zaradi neznanega razloga." -#, fuzzy msgid "Import themes" -msgstr "Uvozi poizvedbe" +msgstr "Uvozi teme" msgid "In" msgstr "Vsebuje (IN)" -#, fuzzy msgid "In Progress" -msgstr "Napredek" +msgstr "V teku" -#, fuzzy msgid "In Range" -msgstr "Časovno obdobje" +msgstr "V dosegu" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fr, ja, lv, mi, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "" "In order to connect to non-public sheets you need to either provide a " "service account or configure an OAuth2 client." -msgstr "" -"Za povezavo z nejavnimi preglednicami morate posredovati storitveni račun" -" ali konfigurirati odjemalca OAuth2." +msgstr "Če se želite povezati z nejavnimi preglednicami, morate zagotoviti storitveni račun ali konfigurirati odjemalca OAuth2." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "In this view you can preview the first 25 rows. " msgstr "V tem pogledu si lahko ogledate prvih 25 vrstic. " -#, fuzzy msgid "Inactive" -msgstr "Aktiven" +msgstr "Neaktiven" msgid "Include Series" msgstr "Vključi serijo" -#, fuzzy msgid "Include Template Parameters" -msgstr "Parametri predlog" +msgstr "Vključi parametre predloge" msgid "Include a description that will be sent with your report" msgstr "Vključite opis, ki bo vključen v poročilo" @@ -8409,27 +7733,24 @@ msgstr "Vključi čas" msgid "Increase" msgstr "Povečaj" -#, fuzzy msgid "Increase color" -msgstr "Povečaj" +msgstr "Povečaj barvo" -#, fuzzy msgid "Increase label" -msgstr "Povečaj" +msgstr "Povečaj oznako" msgid "Index" msgstr "Indeks" -#, fuzzy msgid "Index column" -msgstr "Stolpec črt" +msgstr "Indeksni stolpec" msgid "Index label" msgstr "Oznaka indeksa" -#, fuzzy, python-format +#, python-format msgid "Indexes (%s)" -msgstr "Ogled ključev in indeksov (%s)" +msgstr "Indeksi (%s)" msgid "Info" msgstr "Informacije" @@ -8439,7 +7760,6 @@ msgstr "Prevzemi obdobje iz časovnega filtra" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Initial tree depth" msgstr "Začetna globina drevesa" @@ -8455,53 +7775,42 @@ msgstr "Vnesi poljubno širino v pikslih" msgid "Input field supports custom rotation. e.g. 30 for 30°" msgstr "Vnosno polje omogoča poljubno rotacijo (vnesite 30 za 30°)" -#, fuzzy msgid "Insert Layer URL" -msgstr "Skrij sloj" +msgstr "Vstavite URL plasti" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fr, ja, lv, mi, pt_BR, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Insert Layer title" -msgstr "Vnesite naslov sloja" +msgstr "Vstavite naslov plasti" -#, fuzzy msgid "Inside" -msgstr "Indeks" +msgstr "V notranjosti" -#, fuzzy msgid "Inside bottom" -msgstr "spodaj" +msgstr "Notranji spodnji del" -#, fuzzy msgid "Inside bottom left" -msgstr "Spodaj levo" +msgstr "Znotraj spodaj levo" -#, fuzzy msgid "Inside bottom right" -msgstr "Spodaj desno" +msgstr "Znotraj spodaj desno" -#, fuzzy msgid "Inside left" -msgstr "Zgoraj levo" +msgstr "Notranjost levo" -#, fuzzy msgid "Inside right" -msgstr "Zgoraj desno" +msgstr "Znotraj desno" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Inside top" -msgstr "Znotraj zgoraj" +msgstr "Notranji vrh" -#, fuzzy msgid "Inside top left" -msgstr "Zgoraj levo" +msgstr "Zgoraj levo znotraj" -#, fuzzy msgid "Inside top right" -msgstr "Zgoraj desno" +msgstr "Zgoraj desno znotraj" msgid "Intensity" msgstr "Intenzivnost" @@ -8543,17 +7852,15 @@ msgstr "" msgid "Invalid JSON" msgstr "Neveljaven JSON" -#, fuzzy msgid "Invalid JSON configuration" -msgstr "Neveljavna nastavitev zemljepisne dolžine/širine." +msgstr "Neveljavna konfiguracija JSON" -#, fuzzy msgid "Invalid JSON metadata" -msgstr "JSON-metapodatki" +msgstr "Neveljavni metapodatki JSON" -#, fuzzy, python-format +#, python-format msgid "Invalid SQL: %(error)s" -msgstr "Neveljavna numpy funkcija: %(operator)s" +msgstr "Neveljaven SQL: %(error)s" #, python-format msgid "Invalid advanced data type: %(advanced_data_type)s" @@ -8562,9 +7869,8 @@ msgstr "Neveljaven napreden tip rezultata: %(advanced_data_type)s" msgid "Invalid certificate" msgstr "Neveljaven certifikat" -#, fuzzy msgid "Invalid color" -msgstr "Barve intervalov" +msgstr "Neveljavna barva" msgid "" "Invalid connection string, a valid string usually follows: " @@ -8598,21 +7904,18 @@ msgstr "Neveljaven zapis datuma/časa" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fr, ja, lv, mi, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Invalid executor type" -msgstr "Neveljaven tip izvršitelja" +msgstr "Neveljavna vrsta izvajalca" -#, fuzzy msgid "Invalid expression" -msgstr "Neveljaven cron izraz" +msgstr "Neveljaven izraz" #, python-format msgid "Invalid filter operation type: %(op)s" msgstr "Neveljaven tip operacije filtra: %(op)s" -#, fuzzy msgid "Invalid formula expression" -msgstr "Neveljaven cron izraz" +msgstr "Neveljaven izraz formule" msgid "Invalid geodetic string" msgstr "Neveljaven geodetski niz" @@ -8663,13 +7966,12 @@ msgstr "Neveljavna prostorska točka: %(latlong)s" msgid "Invalid state." msgstr "Neveljavno stanje." -#, fuzzy, python-format +#, python-format msgid "Invalid tab ids: %(tab_ids)s" -msgstr "Neveljavni id-ji zavihkov: %s(tab_ids)" +msgstr "Neveljavni ID-ji zavihkov: %(tab_ids)s" -#, fuzzy msgid "Invalid username or password" -msgstr "Uporabniško ime ali/in geslo sta napačna." +msgstr "Neveljavno uporabniško ime ali geslo" msgid "Inverse selection" msgstr "Invertiraj izbiro" @@ -8677,13 +7979,11 @@ msgstr "Invertiraj izbiro" msgid "Invert current page" msgstr "Invertiraj trenutno stran" -#, fuzzy msgid "Is Active?" -msgstr "Opozorilo je aktivno" +msgstr "Je aktiven?" -#, fuzzy msgid "Is active?" -msgstr "Opozorilo je aktivno" +msgstr "Je aktiven?" msgid "Is certified" msgstr "Certificiran" @@ -8732,17 +8032,13 @@ msgstr "Težava 1001 - podatkovni vir je neobičajno obremenjen." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "" "It won't be removed even if empty. It won't be shown in chart editing " "view if empty." -msgstr "" -"Ne bo odstranjeno, tudi če je prazno. V pogledu za urejanje grafikona ne " -"bo prikazano, če je prazno." +msgstr "Ne bo odstranjen, tudi če je prazen. Če je prazen, ne bo prikazan v pogledu za urejanje grafikona." -#, fuzzy msgid "It’s not recommended to truncate Y axis in Bar chart." -msgstr "V stolpčnem grafikonu ni priporočljivo omejiti osi." +msgstr "V paličnem grafikonu ni priporočljivo skrajšati osi Y." msgid "JAN" msgstr "JAN" @@ -8750,9 +8046,8 @@ msgstr "JAN" msgid "JSON" msgstr "JSON" -#, fuzzy msgid "JSON Configuration" -msgstr "Konfiguracija stolpca" +msgstr "Konfiguracija JSON" msgid "JSON Metadata" msgstr "JSON-metapodatki" @@ -8762,7 +8057,6 @@ msgstr "JSON-metapodatki" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "JSON metadata and advanced configuration" msgstr "Metapodatki JSON in napredna konfiguracija" @@ -8789,6 +8083,15 @@ msgstr "JUN" msgid "January" msgstr "Januar" +msgid "JavaScript data interceptor" +msgstr "JavaScript prestreznik podatkov" + +msgid "JavaScript onClick href" +msgstr "JavaScript onClick href" + +msgid "JavaScript tooltip generator" +msgstr "JavaScript generator opisa orodja" + msgid "Jinja templating" msgstr "Jinja" @@ -8810,18 +8113,16 @@ msgstr "Nadaljuj z urejanjem" msgid "Key" msgstr "Ključ" -#, fuzzy msgid "Key Prefix" -msgstr "Predpona" +msgstr "Predpona ključa" msgid "Keyboard shortcuts" msgstr "Bližnjice na tipkovnici" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "Keys are shown only once at creation. Store them securely." -msgstr "Ključi so prikazani samo enkrat ob ustvarjanju. Hranite jih varno." +msgstr "Ključi so prikazani samo enkrat ob ustvarjanju. Shranite jih na varno." msgid "Kilometers" msgstr "Kilometri" @@ -8832,6 +8133,9 @@ msgstr "Naziv" msgid "Label Contents" msgstr "Označi vsebino" +msgid "Label JavaScript config generator" +msgstr "Generator konfiguracije JavaScript oznake" + msgid "Label Line" msgstr "Črta oznake" @@ -8844,17 +8148,14 @@ msgstr "Tip oznake" msgid "Label already exists" msgstr "Oznaka že obstaja" -#, fuzzy msgid "Label ascending" -msgstr "0 - 9" +msgstr "Oznaka naraščajoče" -#, fuzzy msgid "Label color" -msgstr "Barva polnila" +msgstr "Barva oznake" -#, fuzzy msgid "Label descending" -msgstr "9 - 0" +msgstr "Oznaka padajoče" msgid "Label for the index column. Don't use an existing column name." msgstr "Oznaka za indeksni stolpec. Ne smete uporabiti obstoječega imena stolpca." @@ -8863,22 +8164,19 @@ msgid "Label for your query" msgstr "Ime vaše poizvedbe" msgid "Label must not be empty." -msgstr "" +msgstr "Oznaka ne sme biti prazna." msgid "Label position" msgstr "Položaj oznake" -#, fuzzy msgid "Label property name" -msgstr "Naslov opozorila" +msgstr "Ime lastnosti oznake" -#, fuzzy msgid "Label size" -msgstr "Črta oznake" +msgstr "Velikost oznake" -#, fuzzy msgid "Label size unit" -msgstr "Črta oznake" +msgstr "Enota velikosti oznake" msgid "Label threshold" msgstr "Prag oznak" @@ -8898,9 +8196,8 @@ msgstr "Oznake za markerje" msgid "Labels for the ranges" msgstr "Oznake za razpone" -#, fuzzy msgid "Languages" -msgstr "Razponi" +msgstr "Jeziki" msgid "Large" msgstr "Veliko" @@ -8908,18 +8205,8 @@ msgstr "Veliko" msgid "Last" msgstr "Zadnji" -msgid "Last 30 days" -msgstr "" - -msgid "Last 7 days" -msgstr "" - -msgid "Last 90 days" -msgstr "" - -#, fuzzy msgid "Last Name" -msgstr "ime podatkovnega seta" +msgstr "Priimek" #, python-format msgid "Last Updated %s" @@ -8929,9 +8216,8 @@ msgstr "Zadnja posodobitev %s" msgid "Last Updated %s by %s" msgstr "Zadnja posodobitev %s, %s" -#, fuzzy msgid "Last Used" -msgstr "Število razdelitev" +msgstr "Nazadnje uporabljeno" #, python-format msgid "Last available value seen on %s" @@ -8940,9 +8226,8 @@ msgstr "Zadnja razpoložljiva vrednost na %s" msgid "Last day" msgstr "Zadnji dan" -#, fuzzy msgid "Last login" -msgstr "Zadnji mesec" +msgstr "Zadnja prijava" msgid "Last modified" msgstr "Zadnja sprememba" @@ -8950,27 +8235,24 @@ msgstr "Zadnja sprememba" msgid "Last month" msgstr "Zadnji mesec" -#, fuzzy msgid "Last name" -msgstr "ime podatkovnega seta" +msgstr "Priimek" -#, fuzzy msgid "Last name is required" -msgstr "Zahtevano je ime" +msgstr "Priimek je obvezen" msgid "Last quarter" msgstr "Zadnje četrletje" -#, fuzzy msgid "Last queried at" -msgstr "Zadnje četrletje" +msgstr "Zadnja poizvedba ob" msgid "Last run" msgstr "Zadnji zagon" -#, fuzzy, python-format +#, python-format msgid "Last updated %s ago" -msgstr "Zadnja posodobitev %s" +msgstr "Nazadnje posodobljeno pred %s" msgid "Last week" msgstr "Zadnji teden" @@ -8978,9 +8260,8 @@ msgstr "Zadnji teden" msgid "Last year" msgstr "Zadnje leto" -#, fuzzy msgid "Lat" -msgstr "ravno" +msgstr "Zemljepisna širina" msgid "Latitude" msgstr "Širina" @@ -8988,34 +8269,28 @@ msgstr "Širina" msgid "Latitude of default viewport" msgstr "Širina privzetega pogleda" -#, fuzzy msgid "Layer" -msgstr "leto" +msgstr "Plast" -#, fuzzy msgid "Layer Name" -msgstr "Naslov opozorila" +msgstr "Ime plasti" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fr, ja, lv, mi, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Layer URL" -msgstr "URL sloja" +msgstr "URL plasti" msgid "Layer configuration" msgstr "Nastavitve sloja" -#, fuzzy msgid "Layer title" -msgstr "Naslov grafikona" +msgstr "Naslov plasti" -#, fuzzy msgid "Layer type" -msgstr "Tip filtra" +msgstr "Vrsta plasti" -#, fuzzy msgid "Layers" -msgstr "opozorila" +msgstr "Plasti" msgid "Layout" msgstr "Izgled" @@ -9068,22 +8343,11 @@ msgstr "Tip legende" msgid "Legend type" msgstr "Tip legende" -msgid "Length in cm (12345678cm => 123.46km)" -msgstr "" - -msgid "Length in cm (12345cm => 123.45m)" -msgstr "" - -msgid "Length in m (12345m => 12.35km)" -msgstr "" - -#, fuzzy msgid "Less Than" -msgstr "Manjše kot (<)" +msgstr "Manj kot" -#, fuzzy msgid "Less Than or Equal" -msgstr "Manjše ali enako (<=)" +msgstr "Manj kot ali enako" msgid "Less or equal (<=)" msgstr "Manjše ali enako (<=)" @@ -9093,7 +8357,6 @@ msgstr "Manjše kot (<)" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "Liberty (OpenFreeMap)" msgstr "Liberty (OpenFreeMap)" @@ -9103,9 +8366,8 @@ msgstr "Točnost procentualnega dviga" msgid "Light" msgstr "Svetlo" -#, fuzzy msgid "Light (Carto)" -msgstr "Črtni grafikon" +msgstr "Svetla (Carto)" msgid "Light mode" msgstr "Svetli način" @@ -9116,19 +8378,14 @@ msgstr "Like" msgid "Like (case insensitive)" msgstr "Like (ni razlik. velikih/malih črk)" -#, fuzzy msgid "Limit" -msgstr "OMEJITEV" +msgstr "Omejitev" msgid "Limit type" msgstr "Tip omejitve" -msgid "" -"Limits the number of cells that get retrieved. Not applied when non-" -"additive metrics (e.g. ratios, COUNT_DISTINCT, AVG, percentiles) are " -"present, since totals and subtotals are then computed via a database " -"rollup query that must see every row to stay correct." -msgstr "" +msgid "Limits the number of cells that get retrieved." +msgstr "Omeji število pridobljenih celic." msgid "Limits the number of rows that get displayed." msgstr "Omeji število vrstic za prikaz." @@ -9172,7 +8429,6 @@ msgstr "" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fr, ja, lv, mi, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Line charts on a map" msgstr "Črtni grafikoni na zemljevidu" @@ -9194,9 +8450,8 @@ msgstr "Linearna barvna shema" msgid "Linear interpolation" msgstr "Linearna interpolacija" -#, fuzzy msgid "Linear palette" -msgstr "Počisti vse" +msgstr "Linearna paleta" msgid "Lines column" msgstr "Stolpec črt" @@ -9205,25 +8460,27 @@ msgid "Lines encoding" msgstr "Kodiranje črt" msgid "Link Copied!" -msgstr "" +msgstr "Povezava je kopirana!" -#, fuzzy msgid "List" -msgstr "Zadnji" +msgstr "Seznam" -#, fuzzy msgid "List Groups" -msgstr "Število razdelitev" +msgstr "Seznam skupin" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fr, ja, lv, mi, pt_BR, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "List Roles" msgstr "Seznam vlog" -#, fuzzy +msgid "List Unique Values" +msgstr "Seznam unikatnih vrednosti" + msgid "List Users" -msgstr "Število razdelitev" +msgstr "Seznam uporabnikov" + +msgid "List of extra columns made available in JavaScript functions" +msgstr "Seznam dodatnih stolpcev, ki bodo na razpolago v JavaScript funkcijah" msgid "List of n+1 values for bucketing metric into n buckets." msgstr "Seznam n+1 vrednosti za mero razvrščanja v n razdelkov." @@ -9240,16 +8497,14 @@ msgstr "Seznam vrednosti, ki bodo markirane s trikotniki" msgid "List updated" msgstr "Seznam posodobljen" -#, fuzzy msgid "List view" -msgstr "Število razdelitev" +msgstr "Pogled seznama" msgid "Live render" msgstr "Sprotni izris" -#, fuzzy msgid "Load CSS template (optional)" -msgstr "Naloži CSS predlogo" +msgstr "Naloži predlogo CSS (neobvezno)" msgid "Loaded data cached" msgstr "Naloženo v predpomnilnik" @@ -9257,43 +8512,37 @@ msgstr "Naloženo v predpomnilnik" msgid "Loaded from cache" msgstr "Naloženo iz predpomnilnika" -#, fuzzy msgid "Loading" -msgstr "Nalagam ..." +msgstr "Nalaganje" -#, fuzzy msgid "Loading filter values" -msgstr "Razvrsti vrednosti filtra" +msgstr "Nalaganje vrednosti filtra" -#, fuzzy msgid "Loading timezones..." -msgstr "Nalagam ..." +msgstr "Nalaganje časovnih pasov ..." msgid "Loading..." -msgstr "Nalagam ..." +msgstr "Nalaganje ..." -#, fuzzy msgid "Local" -msgstr "Logaritemska skala" +msgstr "Lokalno" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Local theme set for preview" -msgstr "Lokalna tema nastavljena za predogled" +msgstr "Lokalna tema, nastavljena za predogled" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy, python-format +#, python-format msgid "Local theme set to \"%s\"" -msgstr "Lokalna tema nastavljena na \"%s\"" +msgstr "Lokalna tema je nastavljena na »%s«" msgid "Locate the chart" msgstr "Lociraj grafikon" -#, fuzzy msgid "Log" -msgstr "dnevnik" +msgstr "Dnevnik" msgid "Log Scale" msgstr "Logaritemska skala" @@ -9319,9 +8568,8 @@ msgstr "Logaritemska y-os" msgid "Login" msgstr "Prijava" -#, fuzzy msgid "Login count" -msgstr "število" +msgstr "Število prijav" msgid "Login with" msgstr "Prijava z" @@ -9332,9 +8580,8 @@ msgstr "Odjava" msgid "Logs" msgstr "Dnevniki" -#, fuzzy msgid "Lon" -msgstr "v" +msgstr "Lon" msgid "Long dashed" msgstr "Dolgo-črtkano" @@ -9357,11 +8604,6 @@ msgstr "Dolžina privzetega pogleda" msgid "Lower Threshold" msgstr "Spodnji prag" -msgid "" -"Lower bound of the color scale. When both start and end are set, the " -"legend uses this fixed range instead of the automatic data range." -msgstr "" - msgid "Lower threshold must be lower than upper threshold" msgstr "Spodnji prag mora biti manjši od zgornjega" @@ -9377,9 +8619,8 @@ msgstr "PON" msgid "Main" msgstr "Glavni" -#, fuzzy msgid "Main navigation" -msgstr "Animacija" +msgstr "Glavna navigacija" msgid "" "Make sure that the controls are configured properly and the datasource " @@ -9409,13 +8650,10 @@ msgstr "Upravljaj e-poštno poročilo" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "" "Manage filters and customizations to set scoping, descriptions, and " "limitations. Create new elements for better dashboard insights." -msgstr "" -"Upravljajte filtre in prilagoditve za nastavitev obsega, opisov in " -"omejitev. Ustvarite nove elemente za boljši vpogled v nadzorno ploščo." +msgstr "Upravljajte filtre in prilagoditve za nastavitev obsega, opisov in omejitev. Ustvarite nove elemente za boljše vpoglede v nadzorno ploščo." msgid "Manage your databases" msgstr "Upravljajte podatkovne baze" @@ -9429,45 +8667,37 @@ msgstr "Ročno nastavi min./max. vrednosti za y-os." msgid "Map" msgstr "Zemljevid" -#, fuzzy msgid "Map Options" -msgstr "Možnosti toplotne karte" +msgstr "Možnosti zemljevida" -#, fuzzy msgid "Map Renderer" -msgstr "Sprotni izris" +msgstr "Upodabljalnik zemljevidov" msgid "Map Style" msgstr "Slog zemljevida" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "MapLibre (open-source)" -msgstr "MapLibre (odprtokodna)" +msgstr "MapLibre (odprtokodni)" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "" "MapLibre is open-source and requires no API key. Mapbox requires " "MAPBOX_API_KEY to be configured on the server." -msgstr "" -"MapLibre je odprtokoden in ne zahteva ključa API. Mapbox zahteva, da je " -"MAPBOX_API_KEY konfiguriran na strežniku." +msgstr "MapLibre je odprtokoden in ne potrebuje ključa API. Mapbox zahteva, da je MAPBOX_API_KEY konfiguriran na strežniku." msgid "Mapbox" msgstr "Mapbox" -#, fuzzy msgid "Mapbox (API key required)" -msgstr "Zahtevana je vrednost" +msgstr "Mapbox (potreben je ključ API)" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "Mapbox requires a MAPBOX_API_KEY to be configured on the server." -msgstr "Mapbox zahteva, da je MAPBOX_API_KEY konfiguriran na strežniku." +msgstr "Mapbox zahteva, da je na strežniku konfiguriran MAPBOX_API_KEY." msgid "March" msgstr "Marec" @@ -9504,20 +8734,17 @@ msgstr "Tip označevanja" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, pt_BR, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Match system" -msgstr "Ujemi sistem" +msgstr "Sistem ujemanja" msgid "Match time shift color with original series" msgstr "Uskladi barvo časovnega premika z izvorno serijo" -#, fuzzy msgid "Match type" -msgstr "Tip podatka" +msgstr "Vrsta ujemanja" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Matrixify" msgstr "Matrixify" @@ -9527,15 +8754,13 @@ msgstr "Max" msgid "Max Bubble Size" msgstr "Max. velikost mehurčka" -#, fuzzy msgid "Max value" -msgstr "Maksimalna vrednost" +msgstr "Največja vrednost" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fr, ja, lv, mi, pt_BR, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Max. features" -msgstr "Maks. objektov" +msgstr "Največje število elementov" msgid "Maximum" msgstr "Maksimum" @@ -9546,24 +8771,18 @@ msgstr "Max. velikost pisave" msgid "Maximum Radius" msgstr "Max. polmer" -#, fuzzy msgid "Maximum Width" -msgstr "Min. širina" - -msgid "Maximum dot size" -msgstr "" +msgstr "Največja širina" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, pt_BR, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Maximum folder nesting depth reached" -msgstr "Dosežena največja globina gnezdenja map" +msgstr "Dosežena je največja globina ugnezdenja mape" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fr, ja, lv, mi, pt_BR, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Maximum number of features to fetch from service" -msgstr "Največje število objektov za pridobitev iz storitve" +msgstr "Največje število funkcij za pridobivanje iz storitve" msgid "" "Maximum radius size of the circle, in pixels. As the zoom level changes, " @@ -9578,9 +8797,8 @@ msgstr "Maksimalna vrednost" msgid "Maximum value on the gauge axis" msgstr "Največja vrednost na številčnici" -#, fuzzy msgid "Maximum width size of the path, in pixels or meters." -msgstr "Velikost kvadratne celice v pikslih" +msgstr "Največja širina poti v slikovnih pikah ali metrih." msgid "May" msgstr "Maj" @@ -9591,6 +8809,9 @@ msgstr "Povprečna vrednost v dani periodi" msgid "Mean values" msgstr "Srednje vrednosti" +msgid "Median" +msgstr "Mediana" + msgid "" "Median edge width, the thickest edge will be 4 times thicker than the " "thinnest." @@ -9613,27 +8834,23 @@ msgstr "Srednje" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fa, fr, ja, lv, mi, pt_BR, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Memory in bytes - binary (1024B => 1KiB)" -msgstr "Pomnilnik v bajtih - dvojiški (1024B => 1KiB)" +msgstr "Pomnilnik v bajtih - binarni (1024B => 1KiB)" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fa, fr, ja, lv, mi, pt_BR, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Memory in bytes - decimal (1024B => 1.024kB)" -msgstr "Pomnilnik v bajtih - desetiški (1024B => 1.024kB)" +msgstr "Pomnilnik v bajtih - decimalno (1024B => 1,024kB)" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fr, ja, lv, mi, pt_BR, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Memory transfer rate in bytes - binary (1024B => 1KiB/s)" -msgstr "Hitrost prenosa pomnilnika v bajtih - dvojiški (1024B => 1KiB/s)" +msgstr "Hitrost prenosa pomnilnika v bajtih - binarno (1024B => 1KiB/s)" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fr, ja, lv, mi, pt_BR, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Memory transfer rate in bytes - decimal (1024B => 1.024kB/s)" -msgstr "Hitrost prenosa pomnilnika v bajtih - desetiški (1024B => 1.024kB/s)" +msgstr "Hitrost prenosa pomnilnika v bajtih - decimalno (1024B => 1,024kB/s)" msgid "Menu actions trigger" msgstr "Preklapljanje funkcionalnosti menijev" @@ -9650,26 +8867,22 @@ msgstr "Parametri metapodatkov" msgid "Metadata has been synced" msgstr "Metapodatki so sinhronizirani" -#, fuzzy msgid "Meters" -msgstr "metri" +msgstr "Metri" msgid "Method" msgstr "Metoda" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "" "Method to compute the displayed value. \"Overall value\" calculates a " "single metric across the entire filtered time period, ideal for non-" "additive metrics like ratios, averages, or distinct counts. Other methods" " operate over the time series data points." msgstr "" -"Metoda za izračun prikazane vrednosti. \"Skupna vrednost\" izračuna eno " -"metriko za celotno filtrirano časovno obdobje, kar je idealno za " -"neaditivne metrike, kot so razmerja, povprečja ali število različnih " -"vrednosti. Druge metode delujejo na podatkovnih točkah časovne vrste." +"Metoda za izračun prikazane vrednosti. »Skupna vrednost« izračuna eno samo meritev v celotnem filtriranem časovnem obdobju, kar je idealno za neaditivne " +"meritve, kot so razmerja, povprečja ali ločena štetja. Druge metode delujejo na podatkovnih točkah časovne serije." msgid "Metric" msgstr "Mera" @@ -9709,9 +8922,8 @@ msgstr "Sprememba faktorja mere od vrednosti \"OD\" do \"DO\"" msgid "Metric for node values" msgstr "Mera za vrednosti vozlišč" -#, fuzzy msgid "Metric for ordering" -msgstr "Mera za vrednosti vozlišč" +msgstr "Mera za razvrščanje" msgid "Metric name" msgstr "Ime mere" @@ -9729,9 +8941,8 @@ msgstr "Mera, ki določa velikost mehurčka" msgid "Metric to display bottom title" msgstr "Mera za prikaz spodnjega naslova" -#, fuzzy msgid "Metric to use for ordering Top N values" -msgstr "Mera za vrednosti vozlišč" +msgstr "Mera za razvrščanje najvišjih N vrednosti" msgid "Metric used as a weight for the grid's coloring" msgstr "Mera, ki služi kot utež za barvo mreže" @@ -9763,31 +8974,27 @@ msgstr "" msgid "Metrics" msgstr "Mere" -#, fuzzy, python-format +#, python-format msgid "Metrics (%s)" -msgstr "Mere" +msgstr "Mere (%s)" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "Metrics can't be used for both rows and columns at the same time" -msgstr "Metrik ni mogoče hkrati uporabiti za vrstice in stolpce" +msgstr "Meritev ni mogoče uporabiti za vrstice in stolpce hkrati" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Metrics folder can only contain metric items" -msgstr "Mapa z metrikami lahko vsebuje samo elemente metrik" +msgstr "Mapa mer lahko vsebuje samo mere" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "Metrics should be inside folders" -msgstr "Metrike bi morale biti znotraj map" +msgstr "Mere morajo biti v mapah" -#, fuzzy msgid "Metrics to show in the tooltip." -msgstr "Če želite v celicah prikazati numerične vrednosti" +msgstr "Mere, prikazane v opisu orodja." msgid "Middle" msgstr "Sredina" @@ -9810,17 +9017,14 @@ msgstr "Min. širina" msgid "Min periods" msgstr "Min. št. period" -#, fuzzy msgid "Min value" -msgstr "Vrednost minut" +msgstr "Najmanjša vrednost" -#, fuzzy msgid "Min value cannot be greater than max value" -msgstr "Začetni datum ne sme biti večji od končnega" +msgstr "Najmanjša vrednost ne more biti večja od največje vrednosti" -#, fuzzy msgid "Min value should be smaller or equal to max value" -msgstr "Ta vrednost mora biti manjša od desne ciljne vrednosti" +msgstr "Najmanjša vrednost mora biti manjša ali enaka največji vrednosti" msgid "Min/max (no outliers)" msgstr "Min/max (brez osamelcev)" @@ -9837,16 +9041,11 @@ msgstr "Min. velikost pisave" msgid "Minimum Radius" msgstr "Min. polmer" -#, fuzzy msgid "Minimum Width" -msgstr "Min. širina" - -msgid "Minimum dot size" -msgstr "" +msgstr "Najmanjša širina" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fr, ja, lv, mi, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Minimum must be strictly less than maximum" msgstr "Minimum mora biti strogo manjši od maksimuma" @@ -9869,9 +9068,8 @@ msgstr "Najmanjša vrednost, za katero bo na grafikonu prikazana oznaka." msgid "Minimum value on the gauge axis" msgstr "Najmanjša vrednost na številčnici" -#, fuzzy msgid "Minimum width size of the path, in pixels or meters." -msgstr "Velikost kvadratne celice v pikslih" +msgstr "Najmanjša velikost širine poti v slikovnih pikah ali metrih." msgid "Minor Split Line" msgstr "Pomožna ločilna črta" @@ -9886,19 +9084,17 @@ msgstr "Minuta" msgid "Minutes %s" msgstr "Minute %s" -#, fuzzy, python-format +#, python-format msgid "Missing %s" -msgstr "Manjka podatkovni set" +msgstr "Manjka %s" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fr, ja, lv, mi, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Missing OAuth2 token" -msgstr "Manjkajoči žeton OAuth2" +msgstr "Manjka žeton OAuth2" -#, fuzzy msgid "Missing URL parameter" -msgstr "Manjkajo parametri URL-ja" +msgstr "Manjka parameter URL" msgid "Missing URL parameters" msgstr "Manjkajo parametri URL-ja" @@ -9915,13 +9111,13 @@ msgstr "Zadnja sprememba %s" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fr, ja, lv, mi, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy, python-format +#, python-format msgid "Modified 1 column in the virtual dataset" msgid_plural "Modified %s columns in the virtual dataset" -msgstr[0] "Spremenjen 1 stolpec v virtualnem naboru podatkov" -msgstr[1] "Spremenjena %s stolpca v virtualnem naboru podatkov" -msgstr[2] "Spremenjeni %s stolpci v virtualnem naboru podatkov" -msgstr[3] "Spremenjenih %s stolpcev v virtualnem naboru podatkov" +msgstr[0] "V virtualnem podatkovnem nizu je bil spremenjen %s stolpec" +msgstr[1] "V virtualnem podatkovnem nizu sta bila spremenjena %s stolpca" +msgstr[2] "V virtualnem podatkovnem nizu so bili spremenjeni %s stolpci" +msgstr[3] "V virtualnem podatkovnem nizu je bilo spremenjenih %s stolpcev" msgid "Modified by" msgstr "Spremenil" @@ -9930,9 +9126,9 @@ msgstr "Spremenil" msgid "Modified by: %s" msgstr "Spremenil: %s" -#, fuzzy, python-format +#, python-format msgid "Modified from \"%s\" template" -msgstr "Naloži CSS predlogo" +msgstr "Spremenjeno iz predloge »%s«" msgid "Monday" msgstr "Ponedeljek" @@ -9947,9 +9143,8 @@ msgstr "Meseci %s" msgid "More" msgstr "Več" -#, fuzzy msgid "More Options" -msgstr "Možnosti toplotne karte" +msgstr "Več možnosti" msgid "More filters" msgstr "Več filtrov" @@ -9957,9 +9152,8 @@ msgstr "Več filtrov" msgid "MotherDuck token" msgstr "Žeton za MotherDuck" -#, fuzzy msgid "Move icon" -msgstr "Samo premikanje" +msgstr "Premakni ikono" msgid "Move only" msgstr "Samo premikanje" @@ -9994,13 +9188,10 @@ msgstr "Množitelj" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "" "Must be a chart editor to overwrite this chart. Save as a new chart " "instead." -msgstr "" -"Če želite prepisati ta grafikon, morate biti urednik grafikona. Namesto " -"tega ga shranite kot nov grafikon." +msgstr "Če želite prepisati ta grafikon, morate biti urejevalnik grafikonov. Namesto tega shranite kot nov grafikon." msgid "Must be unique" msgstr "Mora biti unikaten" @@ -10057,9 +9248,8 @@ msgstr "Ime stolpca, ki vsebuje id nadrejenega vozlišča" msgid "Name of the id column" msgstr "Ime id-stolpca" -#, fuzzy msgid "Name of the semantic layer" -msgstr "Ime id-stolpca" +msgstr "Ime semantične plasti" msgid "Name of the source nodes" msgstr "Imena izvornih vozlišč" @@ -10075,17 +9265,14 @@ msgstr "Poimenujte podatkovno bazo" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Name your folder and to edit it later, click on the folder name" -msgstr "Poimenujte svojo mapo in za kasnejše urejanje kliknite na ime mape" +msgstr "Poimenujte mapo in jo pozneje uredite s klikom na ime mape" -#, fuzzy msgid "Native filter column is required" -msgstr "Vrednost filtra je obvezna" +msgstr "Potreben je izvorni stolpec filtra" -#, fuzzy msgid "Native filter values has no values" -msgstr "Predfiltriraj razpoložljive vrednosti" +msgstr "Izvorne vrednosti filtra nimajo vrednosti" msgid "Need help? Learn how to connect your database" msgstr "Potrebujete pomoč? Kako povezati vašo podatkovno bazo se naučite" @@ -10093,27 +9280,23 @@ msgstr "Potrebujete pomoč? Kako povezati vašo podatkovno bazo se naučite" msgid "Need help? Learn more about" msgstr "Potrebujete pomoč? Naučite se več o" -#, fuzzy msgid "Network Error" -msgstr "Napaka omrežja" +msgstr "Omrežna napaka" msgid "Network error" msgstr "Napaka omrežja" -#, fuzzy msgid "Network error while attempting to fetch resource" -msgstr "Pri ustvarjanju podatkovnega vira je prišlo do težave" +msgstr "Omrežna napaka med poskusom pridobivanja vira" msgid "Network error." msgstr "Napaka omrežja." -#, fuzzy msgid "New" -msgstr "Zdaj" +msgstr "Novo" -#, fuzzy msgid "New Semantic Layer" -msgstr "Ni slojev z oznakami" +msgstr "Nova semantična plast" msgid "New chart" msgstr "Nov grafikon" @@ -10155,9 +9338,8 @@ msgstr "%s še ne obstajajo" msgid "No Data" msgstr "Ni podatkov" -#, fuzzy msgid "No Logs yet" -msgstr "%s še ne obstajajo" +msgstr "Dnevnikov še ni" msgid "No Results" msgstr "Ni rezultatov" @@ -10165,16 +9347,14 @@ msgstr "Ni rezultatov" msgid "No Rules yet" msgstr "Pravil še ni" -#, fuzzy msgid "No SQL query found" -msgstr "SQL-poizvedba" +msgstr "Ni najdene poizvedbe SQL" msgid "No Tags created" msgstr "Ni ustvarjenih oznak" -#, fuzzy msgid "No actions" -msgstr "Razveljavi dejanje" +msgstr "Brez dejanj" msgid "No annotation layers" msgstr "Ni slojev z oznakami" @@ -10188,18 +9368,15 @@ msgstr "Oznak še ni" msgid "No applied filters" msgstr "Ni uporabljenih filtrov" -msgid "No archived items" -msgstr "" - msgid "No available filters." msgstr "Ni razpoložljivih filtrov." msgid "No columns found" msgstr "Ni najdenih stolpcev" -#, fuzzy, python-format +#, python-format msgid "No compatible %s found" -msgstr "Ni najdenih skladnih shem" +msgstr "Ni bilo najdenih združljivih %s" msgid "No compatible catalog found" msgstr "Ni najdenega kompatibilnega kataloga" @@ -10219,14 +9396,13 @@ msgstr "" "zapis" msgid "No data found" -msgstr "" +msgstr "Ni najdenih podatkov" msgid "No data in file" msgstr "V datoteki ni podatkov" -#, fuzzy msgid "No databases available" -msgstr "Podatkovnih baz ni na voljo" +msgstr "Baze podatkov niso na voljo" msgid "No databases match your search" msgstr "Nobena podatkovna baza ne ustreza iskanju" @@ -10246,18 +9422,16 @@ msgstr "Noben filter ni izbran." msgid "No filters" msgstr "Brez filtrov" -#, fuzzy msgid "No filters applied" -msgstr "Brez filtrov" +msgstr "Uporabljen ni noben filter" msgid "No filters are currently added to this dashboard." msgstr "Trenutno na nadzorno ploščo še ni dodanih filtrov." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "No filters or customizations created yet" -msgstr "Še niso ustvarjeni filtri ali prilagoditve" +msgstr "Ni še ustvarjenih filtrov ali prilagoditev" msgid "No form settings were maintained" msgstr "Nastavitve forme se niso ohranile" @@ -10265,28 +9439,23 @@ msgstr "Nastavitve forme se niso ohranile" msgid "No global filters are currently added" msgstr "Trenutno ni dodanih globalnih filtrov" -#, fuzzy msgid "No groups" -msgstr "NOT GROUPED BY" +msgstr "Brez skupin" -#, fuzzy msgid "No groups yet" -msgstr "Pravil še ni" +msgstr "Ni še nobene skupine" -#, fuzzy msgid "No items" -msgstr "Brez filtrov" +msgstr "Ni elementov" msgid "No matching records found" msgstr "Ni ujemajočih zapisov" -#, fuzzy msgid "No matching results found" -msgstr "Ni ujemajočih zapisov" +msgstr "Ni ustreznih rezultatov" -#, fuzzy msgid "No multilayer deck.gl charts are currently added to this dashboard." -msgstr "Trenutno na nadzorno ploščo še ni dodanih filtrov." +msgstr "Na to nadzorno ploščo trenutno ni dodanih večplastnih grafikonov deck.gl." msgid "No records found" msgstr "Ni zapisov" @@ -10312,21 +9481,19 @@ msgstr "" "da so filtri pravilno nastavljeni in podatkovni vir vsebuje podatke za " "izbrano časovno obdobje." -#, fuzzy msgid "No roles" -msgstr "Pravil še ni" +msgstr "Brez vlog" -#, fuzzy msgid "No roles yet" -msgstr "Pravil še ni" +msgstr "Ni še nobene vloge" -#, fuzzy, python-format +#, python-format msgid "No rows were returned for this %s" -msgstr "Za podatkovni set ni vrnjenih vrstic" +msgstr "Za ta %s ni bila vrnjena nobena vrstica" -#, fuzzy, python-format +#, python-format msgid "No samples were returned for this %s" -msgstr "Za podatkovni set ni vrnjenih vzorcev" +msgstr "Za ta %s ni bil vrnjen noben vzorec" msgid "No saved expressions found" msgstr "Shranjeni izrazi niso najdeni" @@ -10345,9 +9512,8 @@ msgstr "" msgid "No table columns" msgstr "Ni stolpcev tabel" -#, fuzzy msgid "No tasks yet" -msgstr "%s še ne obstajajo" +msgstr "Opravil še ni" msgid "No temporal columns found" msgstr "Ni najdenih časovnih stolpcev" @@ -10355,13 +9521,11 @@ msgstr "Ni najdenih časovnih stolpcev" msgid "No time columns" msgstr "Ni časovnih stolpcev" -#, fuzzy msgid "No user registrations yet" -msgstr "Pravil še ni" +msgstr "Registracij uporabnikov še ni" -#, fuzzy msgid "No users yet" -msgstr "Pravil še ni" +msgstr "Še ni uporabnikov" msgid "No validator found (configured for the engine)" msgstr "Potrjevalnik ni najden (nastavljen za podatkovno bazo)" @@ -10407,13 +9571,11 @@ msgstr "Normiraj imena stolpcev" msgid "Normalized" msgstr "Normiran" -#, fuzzy msgid "Not Contains" -msgstr "Vsebina poročila" +msgstr "Ne vsebuje" -#, fuzzy msgid "Not Equal" -msgstr "Ni enako (≠)" +msgstr "Ni enako" msgid "Not Time Series" msgstr "Ni časovna vrsta" @@ -10436,9 +9598,8 @@ msgstr "Ni definirano" msgid "Not equal to (≠)" msgstr "Ni enako (≠)" -#, fuzzy msgid "Not found" -msgstr "Grafikon ni najden" +msgstr "Ni najden" msgid "Not in" msgstr "Ne vsebuje (NOT IN)" @@ -10446,9 +9607,8 @@ msgstr "Ne vsebuje (NOT IN)" msgid "Not null" msgstr "Ni null (IS NOT NULL)" -#, fuzzy msgid "Not set" -msgstr "%s še ne obstajajo" +msgstr "Ni nastavljeno" msgid "Not triggered" msgstr "Ni sproženo" @@ -10456,9 +9616,8 @@ msgstr "Ni sproženo" msgid "Not up to date" msgstr "Ni posodobljeno" -#, fuzzy msgid "Nothing here yet" -msgstr "Ni ni sproženo" +msgstr "Tukaj še ni ničesar" msgid "Nothing triggered" msgstr "Ni ni sproženo" @@ -10511,15 +9670,13 @@ msgstr "Število razdelkov za združevanje podatkov" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Number of charts per row when not fitting dynamically" -msgstr "Število grafikonov v vrstici, ko se ne prilagajajo dinamično" +msgstr "Število grafikonov na vrstico, če se ne prilega dinamično" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Number of charts to display per row" -msgstr "Število grafikonov za prikaz v vrstici" +msgstr "Število grafikonov za prikaz na vrstico" msgid "Number of decimal digits to round numbers to" msgstr "Število decimalnih mest za zaokroževanje števil" @@ -10557,13 +9714,12 @@ msgstr "Število korakov med oznakami pri prikazu X-osi" msgid "Number of steps to take between ticks when displaying the Y scale" msgstr "Število korakov med oznakami pri prikazu Y-osi" -#, fuzzy msgid "Number of top values" -msgstr "Oblika zapisa števila" +msgstr "Število najvišjih vrednosti" -#, fuzzy, python-format +#, python-format msgid "Numbers must be within %(min)s and %(max)s" -msgstr "Širina zaslonske slike mora biti med %(min)spx and %(max)spx" +msgstr "Številke morajo biti znotraj %(min)s in %(max)s" msgid "Numeric column used to calculate the histogram." msgstr "Numerični stolpec za izračun histograma." @@ -10571,9 +9727,8 @@ msgstr "Numerični stolpec za izračun histograma." msgid "Numerical range" msgstr "Številski obseg" -#, fuzzy msgid "OAuth2 client information" -msgstr "Osnovne informacije" +msgstr "Podatki o odjemalcu OAuth2" msgid "OCT" msgstr "OKT" @@ -10581,9 +9736,8 @@ msgstr "OKT" msgid "OK" msgstr "OK" -#, fuzzy msgid "OR" -msgstr "ali" +msgstr "ALI" #. do-not-translate msgid "OVERWRITE" @@ -10646,7 +9800,7 @@ msgstr "Ena ali več mer ne obstaja" #, python-format msgid "One or more parameters are missing: %(missing)s" -msgstr "" +msgstr "Manjka eden ali več parametrov: %(missing)s" msgid "One or more parameters needed to configure a database are missing." msgstr "En ali več parametrov, potrebnih za nastavitev podatkovne baze, manjka." @@ -10671,15 +9825,13 @@ msgstr "Veljavno samo, ko je izbran \"Tip oznake\" za prikaz vrednosti." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "Only exact match is available for non-string columns." -msgstr "Za stolpce, ki niso tekstovni, je na voljo samo natančno ujemanje." +msgstr "Za stolpce brez nizov je na voljo samo natančno ujemanje." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "Only proceed if you trust the destination or its source." -msgstr "Nadaljujte samo, če zaupate cilju ali njegovemu viru." +msgstr "Nadaljujte le, če zaupate cilju ali njegovemu viru." msgid "" "Only show the total value on the stacked chart, and not show on the " @@ -10691,9 +9843,8 @@ msgstr "" msgid "Only single queries supported" msgstr "Podprte so le enojne poizvedbe" -#, fuzzy msgid "Only the default catalog is supported for this connection" -msgstr "Privzeti katalog, ki bo uporabljen za to povezavo." +msgstr "Za to povezavo je podprt samo privzeti katalog" msgid "Oops! An error occurred!" msgstr "Prišlo je do napake!" @@ -10719,26 +9870,22 @@ msgstr "Prosojnost, vnesite vrednosti med 0 in 100" msgid "Open Datasource tab" msgstr "Odpri zavihek s podatkovnim virom" -#, fuzzy msgid "Open SQL Lab in a new tab" -msgstr "Zaženi poizvedbo v novem zavihku" +msgstr "Odprite SQL Lab v novem zavihku" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ja] -#, fuzzy msgid "Open chart in new tab" msgstr "Odpri grafikon v novem zavihku" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ja] -#, fuzzy msgid "Open dashboard in new tab" msgstr "Odpri nadzorno ploščo v novem zavihku" msgid "Open in SQL Lab" msgstr "Odpri v SQL laboratoriju" -#, fuzzy msgid "Open in SQL lab" -msgstr "Odpri v SQL laboratoriju" +msgstr "Odpri v SQL Labu" msgid "Open query in SQL Lab" msgstr "Odpri poizvedbo v SQL laboratoriju" @@ -10774,11 +9921,6 @@ msgstr "Opcijski niz za d3-oblikovanje datuma" msgid "Optional d3 number format string" msgstr "Opcijski niz za d3-oblikovanje števila" -msgid "" -"Optional metric used to scale the size of each dot. Dot areas are scaled " -"linearly between the minimum and maximum dot size." -msgstr "" - msgid "Optional name of the data column." msgstr "Opcijsko ime podatkovnega stolpca." @@ -10816,11 +9958,6 @@ msgstr "Orientacija stolpčnega grafikona" msgid "Orientation of filter bar" msgstr "Orientacija vrstice s filtri" -msgid "" -"Orientation of the chart. Horizontal places the dimension on the y-axis " -"and the metric on the x-axis." -msgstr "" - msgid "Orientation of tree" msgstr "Orientacija drevesa" @@ -10915,24 +10052,20 @@ msgstr "Besedilo v urejevalniku prepišite s poizvedbo na to tabelo" msgid "Owned Created or Favored" msgstr "Lastnik, Ustvaril ali Priljubljen" -#, fuzzy msgid "PDF download failed, please refresh and try again." -msgstr "Prenos slike ni uspel. Osvežite in poskusite ponovno." +msgstr "Prenos PDF-ja ni uspel, osvežite in poskusite znova." -#, fuzzy msgid "Page" -msgstr "Uporaba" +msgstr "Stran" -#, fuzzy msgid "Page Size:" -msgstr "page_size.all" +msgstr "Velikost strani:" msgid "Page length" msgstr "Dolžina strani" -#, fuzzy msgid "Page navigation" -msgstr "Agregacija" +msgstr "Navigacija po straneh" msgid "Paired t-test Table" msgstr "Tabela t-testa za odvisne vzorce" @@ -10990,26 +10123,22 @@ msgstr "" msgid "Password" msgstr "Geslo" -#, fuzzy msgid "Password is required" -msgstr "Tip je obvezen" +msgstr "Zahtevano je geslo" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ja] -#, fuzzy, python-format +#, python-format msgid "Password must be at least %(min_length)s characters long." msgstr "Geslo mora biti dolgo vsaj %(min_length)s znakov." -#, fuzzy msgid "Password:" -msgstr "Geslo" +msgstr "Geslo:" -#, fuzzy msgid "Passwords do not match!" -msgstr "Nadzorna plošča ne obstaja" +msgstr "Gesli se ne ujemata!" -#, fuzzy msgid "Paste" -msgstr "Posodobi" +msgstr "Prilepi" msgid "Paste Private Key here" msgstr "Prilepite privatni ključ sem" @@ -11023,34 +10152,28 @@ msgstr "Prilepite deljeni URL Googlove preglednice sem" msgid "Paste your access token here" msgstr "Sem prilepite žeton za dostop" -#, fuzzy msgid "Path Color" -msgstr "Barva točke" +msgstr "Barva poti" -#, fuzzy msgid "Path Size" -msgstr "Velikost točke" +msgstr "Velikost poti" msgid "Pattern" msgstr "Vzorec" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "Pause auto refresh if tab is inactive" -msgstr "Začasno ustavi samodejno osvežavanje, če je zavihek neaktiven" +msgstr "Zaustavite samodejno osveževanje, če je zavihek neaktiven" -#, fuzzy msgid "Pause auto-refresh" -msgstr "Nastavi interval samodejnega osveževanja" +msgstr "Zaustavi samodejno osveževanje" -#, fuzzy msgid "Pending" -msgstr "v teku" +msgstr "V čakanju" -#, fuzzy msgid "Per user caching" -msgstr "Procentualna sprememba" +msgstr "Predpomnjenje na uporabnika" msgid "Percent Change" msgstr "Procentualna sprememba" @@ -11070,9 +10193,8 @@ msgstr "Procentualna sprememba" msgid "Percentage difference between the time periods" msgstr "Procentualna razlika med časovnimi obdobji" -#, fuzzy msgid "Percentage metric calculation" -msgstr "Procentualne mere" +msgstr "Izračun mere v odstotkih" msgid "Percentage metrics" msgstr "Procentualne mere" @@ -11095,15 +10217,14 @@ msgstr "Št. period" msgid "Periods must be a whole number" msgstr "Periode morajo biti celo število" -#, fuzzy msgid "Permissions" -msgstr "Verzija" +msgstr "Dovoljenja" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fr, ja, lv, mi, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy, python-format +#, python-format msgid "Permissions successfully synced for %s" -msgstr "Dovoljenja uspešno sinhronizirana za %s" +msgstr "Dovoljenja so bila uspešno sinhronizirana za %s" msgid "Person or group that has certified this chart." msgstr "Oseba ali skupina, ki je certificirala ta grafikon." @@ -11116,7 +10237,6 @@ msgstr "Oseba ali skupina, ki je certificirala to mero" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Personal info" msgstr "Osebni podatki" @@ -11162,7 +10282,6 @@ msgstr "Tortni grafikon" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fr, ja, lv, mi, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Pie charts on a map" msgstr "Tortni grafikoni na zemljevidu" @@ -11175,31 +10294,25 @@ msgstr "Odsekovno" msgid "Pin" msgstr "Žebljiček" -#, fuzzy msgid "Pin Column" -msgstr "Stolpec črt" +msgstr "Pripni stolpec" -#, fuzzy msgid "Pin Left" -msgstr "Zgoraj levo" +msgstr "Pripni levo" -#, fuzzy msgid "Pin Right" -msgstr "Zgoraj desno" +msgstr "Pripni desno" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Pin to the result panel" -msgstr "Pripni na panel rezultatov" +msgstr "Pripni na ploščo z rezultati" -#, fuzzy msgid "Pin to top" -msgstr "Od vrha proti dnu" +msgstr "Pripni na vrh" -#, fuzzy msgid "Pivot Mode" -msgstr "načinu urejanja" +msgstr "Vrtilni način" msgid "Pivot Table" msgstr "Vrtilna tabela" @@ -11213,9 +10326,8 @@ msgstr "Vrtilna operacija zahteva vsaj en indeks" msgid "Pivoted" msgstr "Vrtilni" -#, fuzzy msgid "Pivots" -msgstr "Vrtilni" +msgstr "Vrtilne vrednosti" msgid "Pixel height of each series" msgstr "Višina vsake serije v pikslih" @@ -11260,7 +10372,6 @@ msgstr "" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fr, ja, lv, mi, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Please choose a valid value" msgstr "Izberite veljavno vrednost" @@ -11273,55 +10384,45 @@ msgstr "Prosim, potrdite" msgid "Please confirm the overwrite values." msgstr "Potrdite vrednosti za prepis." -#, fuzzy msgid "Please confirm your password" -msgstr "Prosim, potrdite" +msgstr "Prosim potrdite svoje geslo" msgid "Please enter a SQLAlchemy URI to test" msgstr "Vnesite SQLAlchemy URI za test" -#, fuzzy msgid "Please enter a valid email" -msgstr "Vnesite SQLAlchemy URI za test" +msgstr "Vnesite veljaven e-poštni naslov" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fr, ja, lv, mi, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Please enter a valid email address" -msgstr "Vnesite veljavni e-poštni naslov" +msgstr "Vnesite veljaven e-poštni naslov" msgid "Please enter valid text. Spaces alone are not permitted." msgstr "Vnesite veljaven zapis. Samo presledki niso dovoljeni." -#, fuzzy msgid "Please enter your email" -msgstr "Prosim, potrdite" +msgstr "Prosimo, vnesite svoj e-poštni naslov" -#, fuzzy msgid "Please enter your first name" -msgstr "Vnesite naslov opozorila" +msgstr "Prosimo, vnesite svoje ime" -#, fuzzy msgid "Please enter your last name" -msgstr "Vnesite naslov opozorila" +msgstr "Prosimo vnesite svoj priimek" -#, fuzzy msgid "Please enter your password" -msgstr "Prosim, potrdite" +msgstr "Prosim vnesite svoje geslo" -#, fuzzy msgid "Please enter your username" -msgstr "Ime vaše poizvedbe" +msgstr "Vnesite svoje uporabniško ime" -#, fuzzy msgid "Please fix the following errors" -msgstr "Imamo naslednje ključe: %s" +msgstr "Popravite naslednje napake" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, ja, lv, # ro, ru, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Please provide a valid min or max value" -msgstr "Vnesite veljavno minimalno ali maksimalno vrednost" +msgstr "Navedite veljavno najmanjšo ali največjo vrednost" msgid "Please re-enter the password." msgstr "Ponovno vpišite geslo." @@ -11346,13 +10447,12 @@ msgstr "" "Najprej shranite nadzorno ploščo, potem pa poskusite ustvariti novo " "e-poštno poročilo." -#, fuzzy msgid "Please select at least one role or group" -msgstr "Izberite vsaj en 'Group by'" +msgstr "Izberite vsaj eno vlogo ali skupino" -#, fuzzy, python-format +#, python-format msgid "Please select both a %s and a Chart type to proceed" -msgstr "Za nadaljevanje izberite podatkovni set in tip grafikona" +msgstr "Za nadaljevanje izberite %s in vrsto grafikona" #, python-format msgid "" @@ -11369,6 +10469,8 @@ msgid "" "period (e.g. today so far) against complete prior periods (e.g. all of " "yesterday)." msgstr "" +"Vsako časovno zamaknjeno serijo izriše čez njen celotni časovni obseg, namesto da bi jo skrajšal na glavno serijo. Uporabno za primerjavo delnega trenutnega " +"obdobja (npr. današnjega dne do zdaj) s celotnimi preteklimi obdobji (npr. celotnim včerajšnjim dnem)." msgid "Plot the distance (like flight paths) between origin and destination." msgstr "Izriši razdalje (kot letalske koridorje) med izhodiščem in ciljem." @@ -11385,9 +10487,8 @@ msgstr "" msgid "Plugins" msgstr "Vtičniki" -#, fuzzy msgid "Point Cluster Map" -msgstr "Barva točke" +msgstr "Zemljevid grozdov točk" msgid "Point Color" msgstr "Barva točke" @@ -11402,9 +10503,8 @@ msgid "Point Radius Unit" msgstr "Enota radija točk" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ja] -#, fuzzy msgid "Point Radius Units" -msgstr "Enote polmera točke" +msgstr "Enote radija točke" msgid "Point Size" msgstr "Velikost točke" @@ -11515,9 +10615,8 @@ msgstr "Meje primarne y-osi" msgid "Primary y-axis format" msgstr "Oblika primarne y-osi" -#, fuzzy msgid "Private" -msgstr "Privatni ključ" +msgstr "Zasebno" msgid "Private Key" msgstr "Privatni ključ" @@ -11533,15 +10632,14 @@ msgstr "Nadaljuj" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy, python-format +#, python-format msgid "Processing export for %s" msgstr "Obdelava izvoza za %s" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Processing export..." -msgstr "Obdelava izvoza..." +msgstr "Obdelava izvoza ..." msgid "Progress" msgstr "Napredek" @@ -11549,22 +10647,19 @@ msgstr "Napredek" msgid "Progressive" msgstr "Progresivno" -#, fuzzy msgid "Project Id" -msgstr "Zastarelo" +msgstr "ID projekta" msgid "Proportional" msgstr "Proporcionalno" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "Public and privately shared sheets" -msgstr "Javno in zasebno deljeni listi" +msgstr "Javni in zasebni listi v skupni rabi" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "Publicly shared sheets only" msgstr "Samo javno deljeni listi" @@ -11612,17 +10707,14 @@ msgstr "Poizvedba B" msgid "Query History" msgstr "Zgodovina poizvedb" -#, fuzzy msgid "Query State" -msgstr "Poizvedba A" +msgstr "Stanje poizvedbe" -#, fuzzy msgid "Query cannot be loaded." -msgstr "Poizvedbe ni mogoče naložiti" +msgstr "Poizvedbe ni mogoče naložiti." -#, fuzzy msgid "Query data in SQL Lab" -msgstr "POIZVEDBA V SQL LABORATORIJU" +msgstr "Poizveduj po podatkih v SQL Labu" msgid "Query does not exist" msgstr "Poizvedba ne obstaja" @@ -11654,9 +10746,8 @@ msgstr "Poizvedba je bila ustavljena" msgid "Query was stopped." msgstr "Poizvedba je bila ustavljena." -#, fuzzy msgid "Queued" -msgstr "poizvedbe" +msgstr "V čakalni vrsti" msgid "RGB Color" msgstr "RGB barva" @@ -11694,9 +10785,8 @@ msgstr "Polmer v miljah" msgid "Range" msgstr "Doseg" -#, fuzzy msgid "Range Inputs" -msgstr "Razponi" +msgstr "Vhodi obsega" msgid "Range Type" msgstr "Tip obdobja" @@ -11728,12 +10818,6 @@ msgstr "Razmerje" msgid "Raw records" msgstr "Surovi podatki" -msgid "Recently Archived" -msgstr "" - -msgid "Recently archived" -msgstr "" - msgid "Recently modified" msgstr "Nedavno spremenjeno" @@ -11743,18 +10827,8 @@ msgstr "Nedavno" msgid "Recipients are separated by \",\" or \";\"" msgstr "Prejemniki so ločeni z \",\" ali \";\"" -#, fuzzy msgid "Records" -msgstr "Surovi podatki" - -msgid "Recover" -msgstr "" - -msgid "Recover this item" -msgstr "" - -msgid "Recover this item to open it" -msgstr "" +msgstr "Zapisi" msgid "Rectangle" msgstr "Pravokotnik" @@ -11787,9 +10861,8 @@ msgstr "Obrnite se na" msgid "Referenced columns not available in DataFrame." msgstr "Referencirani stolpci niso razpoložljivi v Dataframe-u." -#, fuzzy msgid "Referrer" -msgstr "Osveži" +msgstr "Napotitelj" msgid "Refetch results" msgstr "Ponovno pridobi rezultate" @@ -11797,16 +10870,15 @@ msgstr "Ponovno pridobi rezultate" msgid "Refresh dashboard" msgstr "Osveži nadzorno ploščo" -#, fuzzy msgid "Refresh delayed" -msgstr "Osveži nadzorno ploščo" +msgstr "Osvežitev je zakasnjena" msgid "Refresh frequency" msgstr "Frekvenca osveževanja" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy, python-format +#, python-format msgid "Refresh frequency must be at least %s seconds" msgstr "Pogostost osveževanja mora biti vsaj %s sekund" @@ -11816,13 +10888,11 @@ msgstr "Interval osveževanja" msgid "Refresh interval saved" msgstr "Interval osveževanja shranjen" -#, fuzzy msgid "Refresh interval set for this session" -msgstr "Shranite za to sejo" +msgstr "Za to sejo je nastavljen interval osveževanja" -#, fuzzy msgid "Refresh settings" -msgstr "Nastavitve datoteke" +msgstr "Nastavitve osveževanja" msgid "Refresh table schema" msgstr "Osveži shemo tabele" @@ -11836,17 +10906,14 @@ msgstr "Osveževanje grafikonov" msgid "Refreshing columns" msgstr "Osveževanje stolpcev" -#, fuzzy msgid "Register" -msgstr "Predfilter" +msgstr "Registriraj se" -#, fuzzy msgid "Registration date" -msgstr "Začetni datum" +msgstr "Datum registracije" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Registration successful" msgstr "Registracija uspešna" @@ -11859,6 +10926,8 @@ msgid "" "except the subjects defined in the filter, and can be used to define what" " users can see if no RLS filters within a filter group apply to them." msgstr "" +"Običajni filtri poizvedbam dodajo pogoje WHERE, če se uporabnik ujema s subjektom, navedenim v filtru. Osnovni filtri veljajo za vse poizvedbe razen za " +"subjekte, določene v filtru, in določajo, kaj lahko uporabniki vidijo, če zanje ne velja noben filter RLS v skupini filtrov." msgid "Relational" msgstr "Relacijsko" @@ -11879,58 +10948,53 @@ msgid "Reload" msgstr "Ponovno naloži" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ja] -#, fuzzy msgid "Reload SQL Lab" -msgstr "Znova naloži SQL Lab" +msgstr "Ponovno naloži SQL Lab" msgid "Remove" msgstr "Odstrani" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Remove System Dark Theme" -msgstr "Odstrani sistemsko temno temo" +msgstr "Odstranite sistemsko temno temo" -#, fuzzy msgid "Remove System Default Theme" -msgstr "Osveži privzete vrednosti" +msgstr "Odstranite sistemsko privzeto temo" msgid "Remove cross-filter" msgstr "Odstrani medsebojne filtre" -#, fuzzy msgid "Remove customization" -msgstr "Tip vizualizacije" +msgstr "Odstrani prilagajanje" msgid "Remove dependency" -msgstr "" +msgstr "Odstrani odvisnost" -#, fuzzy msgid "Remove filter" -msgstr "Odstrani element" +msgstr "Odstranite filter" msgid "Remove item" msgstr "Odstrani element" msgid "Remove notification method" -msgstr "" +msgstr "Odstrani način obveščanja" msgid "Remove query from log" msgstr "Odstrani poizvedbo iz dnevnika" msgid "Remove sheet" -msgstr "" +msgstr "Odstrani list" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fr, ja, lv, mi, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy, python-format +#, python-format msgid "Removed 1 column from the virtual dataset" msgid_plural "Removed %s columns from the virtual dataset" -msgstr[0] "Odstranjen 1 stolpec iz virtualnega nabora podatkov" -msgstr[1] "Odstranjena %s stolpca iz virtualnega nabora podatkov" -msgstr[2] "Odstranjeni %s stolpci iz virtualnega nabora podatkov" -msgstr[3] "Odstranjenih %s stolpcev iz virtualnega nabora podatkov" +msgstr[0] "Iz virtualnega podatkovnega niza je bil odstranjen %s stolpec" +msgstr[1] "Iz virtualnega podatkovnega niza sta bila odstranjena %s stolpca" +msgstr[2] "Iz virtualnega podatkovnega niza so bili odstranjeni %s stolpci" +msgstr[3] "Iz virtualnega podatkovnega niza je bilo odstranjenih %s stolpcev" msgid "Rename tab" msgstr "Preimenuj zavihek" @@ -11943,13 +11007,10 @@ msgstr "Izvede HTML v stolpcih" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fr, ja, lv, mi, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "" "Renders table cells as HTML when applicable. For example, HTML tags " "will be rendered as hyperlinks." -msgstr "" -"Prikazuje celice tabele kot HTML, kadar je to primerno. Na primer, oznake" -" HTML bodo prikazane kot hiperpovezave." +msgstr "Upodobi celice tabele kot HTML, kadar je to primerno. Na primer, oznake HTML bodo upodobljene kot hiperpovezave." msgid "Replace" msgstr "Zamenjaj" @@ -11970,7 +11031,7 @@ msgid "Report Schedule delete failed." msgstr "Izbris urnika poročanja ni uspel." msgid "Report Schedule execute now failed." -msgstr "" +msgstr "Takojšnja izvedba razporeda poročila ni uspela." msgid "Report Schedule execution failed when generating a csv." msgstr "Izvajanje urnika poročanja je bilo neuspešno pri ustvarjanju csv." @@ -11989,7 +11050,7 @@ msgstr "" "slike." msgid "Report Schedule execution failed when generating an Excel file." -msgstr "" +msgstr "Izvedba razporeda poročila pri ustvarjanju datoteke Excel ni uspela." msgid "Report Schedule execution got an unexpected error." msgstr "Pri izvajanju urnika poročanja je prišlo do nepričakovane napake." @@ -11998,11 +11059,11 @@ msgid "" "Report Schedule execution requires a Celery backend to be configured. " "Please configure a Celery broker (Redis or RabbitMQ) and worker " "processes." -msgstr "" +msgstr "Izvedba razporeda poročila zahteva nastavljen zaledni sistem Celery. Nastavite posrednika Celery (Redis ali RabbitMQ) in delovne procese." #, python-format msgid "Report Schedule executor user %(username)s was not found." -msgstr "" +msgstr "Uporabnik izvajalca razporeda poročila %(username)s ni bil najden." msgid "Report Schedule is still working, refusing to re-compute." msgstr "Urnik poročanja se še vedno izvaja, ponovni izračun je zavrnjen." @@ -12038,9 +11099,8 @@ msgid "Report name" msgstr "Naslov poročila" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ja] -#, fuzzy msgid "Report not yet run" -msgstr "Poročilo še ni bilo izvedeno" +msgstr "Poročilo še ni zagnano" msgid "Report schedule client error" msgstr "Napaka klienta urnika poročanja" @@ -12071,7 +11131,6 @@ msgstr "Odbojna sila med vozlišči" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fr, ja, lv, mi, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Request Access" msgstr "Zahtevaj dostop" @@ -12088,13 +11147,6 @@ msgstr "Zahtevaj manjkajoča podatkovna polja." msgid "Request timed out" msgstr "Zahtevek pretečen" -#, python-format -msgid "" -"Requested page would return %(requested_size)d bytes, exceeding the " -"maximum allowed list payload size of %(max_size)d bytes. Reduce page_size" -" and try again." -msgstr "" - msgid "Required" msgstr "Obvezno" @@ -12105,9 +11157,9 @@ msgid "Resample" msgstr "Prevzorči" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ja] -#, fuzzy, python-format +#, python-format msgid "Resample method '%(method)s' is not supported." -msgstr "Metoda vzorčenja '%(method)s' ni podprta." +msgstr "Metoda ponovnega vzorčenja ' %(method)s ' ni podprta." msgid "Resample method should be in " msgstr "Metoda za prevzorčenje v mora biti v " @@ -12118,38 +11170,31 @@ msgstr "Prevzorčevalna operacija zahteva indeks tipa datumčas" msgid "Reset" msgstr "Ponastavi" -#, fuzzy msgid "Reset Columns" -msgstr "Izberite stolpec" +msgstr "Ponastavi stolpce" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Reset all folders to default" -msgstr "Ponastavi vse mape na privzeto" +msgstr "Ponastavite vse mape na privzete" -#, fuzzy msgid "Reset columns" -msgstr "Izberite stolpec" +msgstr "Ponastavi stolpce" -#, fuzzy msgid "Reset my password" -msgstr "%s GESLO" +msgstr "Ponastavi moje geslo" -#, fuzzy msgid "Reset password" -msgstr "%s GESLO" +msgstr "Ponastavi geslo" msgid "Reset state" msgstr "Ponastavi stanje" -#, fuzzy msgid "Reset to default folders?" -msgstr "Osveži privzete vrednosti" +msgstr "Ponastaviti na privzete mape?" -#, fuzzy msgid "Resize" -msgstr "Ponastavi" +msgstr "Spremeni velikost" msgid "Resource already has an attached report." msgstr "Vir že ima povezano poročilo." @@ -12180,20 +11225,17 @@ msgstr "" "Zaledni sistem za rezultate, potreben za asinhrone poizvedbe, ni " "konfiguriran." -#, fuzzy msgid "Resume auto-refresh" -msgstr "Nastavi interval samodejnega osveževanja" +msgstr "Nadaljuj samodejno osveževanje" -#, fuzzy msgid "Retry" -msgstr "Avtor" +msgstr "Poskusi znova" msgid "Retry fetching results" msgstr "Ponovno pridobi rezultate" -#, fuzzy msgid "Return to Superset" -msgstr "Vrne datum-čas." +msgstr "Vrni se v Superset" msgid "Return to specific datetime." msgstr "Vrne datum-čas." @@ -12204,23 +11246,19 @@ msgstr "Zamenjaj širino in dolžino" msgid "Reverse lat/long " msgstr "Zamenjaj zemljepisno dolžino/širino " -#, fuzzy msgid "Revoke" -msgstr "Odstrani" +msgstr "Prekliči" -#, fuzzy msgid "Revoke API Key" -msgstr "Ključ za združevanje" +msgstr "Prekliči ključ API" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, ja, sr, # sr_Latn] -#, fuzzy msgid "Revoke this API key" -msgstr "Prekliči ta API ključ" +msgstr "Prekliči ta ključ API" -#, fuzzy msgid "Revoked" -msgstr "Obrobljeno" +msgstr "Preklicano" msgid "Rich Tooltip" msgstr "Podroben opis orodja" @@ -12237,9 +11275,8 @@ msgstr "Oblika desne osi" msgid "Right Axis Metric" msgstr "Mera desne osi" -#, fuzzy msgid "Right Panel" -msgstr "Desna vrednost" +msgstr "Desna plošča" msgid "Right axis metric" msgstr "Mera desne osi" @@ -12256,13 +11293,11 @@ msgstr "Z desnim klikom na dimenzijo vrtajte v podrobnosti po tej vrednosti." msgid "Role" msgstr "Vloga" -#, fuzzy msgid "Role Name" -msgstr "Naslov opozorila" +msgstr "Ime vloge" -#, fuzzy msgid "Role name is required" -msgstr "Zahtevano je ime" +msgstr "Zahtevano je ime vloge" msgid "Roles" msgstr "Vloge" @@ -12308,16 +11343,13 @@ msgstr "Varnost na nivoju vrstic" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "" "Row Limit: percentages are calculated based on the subset of data " "retrieved, respecting the row limit. All Records: Percentages are " "calculated based on the total dataset, ignoring the row limit." msgstr "" -"Omejitev vrstic: odstotki so izračunani na podlagi podmnožice " -"pridobljenih podatkov, ob upoštevanju omejitve vrstic. Vsi zapisi: " -"odstotki so izračunani na podlagi celotnega nabora podatkov, brez " -"upoštevanja omejitve vrstic." +"Omejitev vrstic: odstotki se izračunajo na podlagi podnabora pridobljenih podatkov ob upoštevanju omejitve vrstic. Vsi zapisi: odstotki se izračunajo na " +"podlagi skupnega nabora podatkov, pri čemer se ne upošteva omejitev vrstic." msgid "" "Row containing the headers to use as column names (0 is first line of " @@ -12326,26 +11358,17 @@ msgstr "" "Vrstica z glavo, ki se uporabi za imena stolpcev (0 je prva vrstica " "podatkov)." -#, fuzzy msgid "Row height" -msgstr "Utež" +msgstr "Višina vrstice" msgid "Row limit" msgstr "Omejitev števila vrstic" -msgid "Row-Level Security" -msgstr "" - -#, python-format -msgid "Row-Level Security: %d filter(s) may restrict data based on your role." -msgstr "" - msgid "Rows" msgstr "Vrstice" -#, fuzzy msgid "Rows (vertical layout)" -msgstr "Navpično (levo)" +msgstr "Vrstice (navpična postavitev)" msgid "Rows per page, 0 means no pagination" msgstr "Vrstic na stran (0 pomeni brez številčenja strani)" @@ -12368,9 +11391,6 @@ msgstr "Pravilo dodano" msgid "Run" msgstr "Zaženi" -msgid "Run a new query using the \"Update chart\" button or" -msgstr "" - msgid "Run a query to display query history" msgstr "Za prikaz zgodovine poizvedb zaženite poizvedbo" @@ -12398,9 +11418,9 @@ msgstr "Zaženi izbrano" msgid "Running" msgstr "V teku" -#, fuzzy, python-format +#, python-format msgid "Running block %(block_num)s out of %(block_count)s" -msgstr "Poganjanje izraza %(block_num)s od %(block_count)s" +msgstr "Teče blok %(block_num)s iz %(block_count)s" msgid "SAT" msgstr "SOB" @@ -12416,20 +11436,16 @@ msgstr "SQL laboratorij" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "" "SQL Lab cannot authorise a statement that could not be fully parsed. " "Qualify tables explicitly and avoid dynamic SQL inside stored-procedure " "or vendor-specific calls." msgstr "" -"SQL Lab ne more odobriti stavka, ki ga ni bilo mogoče v celoti " -"razčleniti. Eksplicitno kvalificirajte tabele in se izogibajte " -"dinamičnemu SQL-u znotraj shranjenih procedur ali klicev, specifičnih za " -"dobavitelja." +"SQL Lab ne more odobriti izjave, ki je ni bilo mogoče v celoti razčleniti. Eksplicitno kvalificirajte tabele in se izogibajte dinamičnemu SQL znotraj " +"shranjenih procedur ali klicev, specifičnih za prodajalca." -#, fuzzy msgid "SQL Lab queries" -msgstr "shranjene poizvedbe" +msgstr "Poizvedbe SQL Lab" #, python-format msgid "" @@ -12459,9 +11475,8 @@ msgstr "SQL-izraz" msgid "SQL query" msgstr "SQL-poizvedba" -#, fuzzy msgid "SQL was formatted" -msgstr "Oblika Y-osi" +msgstr "SQL je bil oblikovan" msgid "SQLAlchemy URI" msgstr "SQLAlchemy URI" @@ -12496,9 +11511,8 @@ msgstr "Parametri SSH-tunela so neveljavni." msgid "SSH Tunneling is not enabled" msgstr "SSH-tunel ni omogočen" -#, fuzzy msgid "SSL" -msgstr "sql" +msgstr "SSL" msgid "SSL Mode \"require\" will be used." msgstr "Uporabljen bo SSL-način \"REQUIRED\"." @@ -12513,6 +11527,12 @@ msgstr "STRING" msgid "SUN" msgstr "NED" +msgid "Sample Standard Deviation" +msgstr "Standardna deviacija vzorca" + +msgid "Sample Variance" +msgstr "Varianca vzorca" + msgid "Samples" msgstr "Vzorci" @@ -12549,9 +11569,9 @@ msgstr "Shrani (prepiši)" msgid "Save as" msgstr "Shrani kot" -#, fuzzy, python-format +#, python-format msgid "Save as %s" -msgstr "Shrani kot" +msgstr "Shrani kot %s" msgid "Save as Dataset" msgstr "Shrani kot podatkovni set" @@ -12568,22 +11588,19 @@ msgstr "Shrani kot:" msgid "Save changes" msgstr "Shrani spremembe" -#, fuzzy msgid "Save changes to your chart?" -msgstr "Shrani spremembe" +msgstr "Želite shraniti spremembe v grafikon?" -#, fuzzy msgid "Save changes to your dashboard?" -msgstr "Shrani in pojdi na nadzorno ploščo" +msgstr "Želite shraniti spremembe na nadzorno ploščo?" msgid "Save chart" msgstr "Shrani grafikon" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Save color breakpoint values" -msgstr "Shrani vrednosti prelomnih točk barv" +msgstr "Shranite vrednosti prelomnih točk barv" msgid "Save dashboard" msgstr "Shrani nadzorno ploščo" @@ -12602,9 +11619,8 @@ msgstr "Shrani poizvedbo" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "Save this API key securely" -msgstr "Varno shrani ta API ključ" +msgstr "Varno shranite ta ključ API-ja" msgid "Save this query as a virtual dataset to continue exploring" msgstr "Shranite poizvedbo kot virtualni podatkovni set" @@ -12633,18 +11649,16 @@ msgstr "Shranjena poizvedba ni najdena." msgid "Saved query parameters are invalid." msgstr "Parametri shranjene poizvedbe so neveljavni." -#, fuzzy msgid "Saving..." -msgstr "Nalagam ..." +msgstr "Shranjevanje ..." msgid "Scale and Move" msgstr "Povečava in premikanje" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "Scale factor applied to metric-driven line widths" -msgstr "Faktor skaliranja, ki se uporablja za širine linij, določenih z metrikami" +msgstr "Faktor lestvice, uporabljen za širine črt, ki jih določa mera" msgid "Scale only" msgstr "Samo povečava" @@ -12717,7 +11731,7 @@ msgid "Scroll down to the bottom to enable overwriting changes. " msgstr "Pomaknite se do dna, da omogočite prepis sprememb. " msgid "Search" -msgstr "Iskanje" +msgstr "Išči" msgid "Search / Filter" msgstr "Iskanje / Filter" @@ -12726,28 +11740,25 @@ msgid "Search Metrics & Columns" msgstr "Iskanje mer in stolpcev" msgid "Search a channel by name, or paste a channel ID" -msgstr "" +msgstr "Poiščite kanal po imenu ali prilepite ID kanala" msgid "Search all charts" msgstr "Išči vse grafikone" -#, fuzzy msgid "Search all metrics & columns" -msgstr "Iskanje mer in stolpcev" +msgstr "Išči po vseh merah in stolpcih" msgid "Search box" msgstr "Iskalno polje" -#, fuzzy msgid "Search by" -msgstr "Iskalno polje" +msgstr "Iskanje po" msgid "Search by query text" msgstr "Išči po vsebini poizvedbe" -#, fuzzy msgid "Search calculated columns by name" -msgstr "Izračunani stolpci" +msgstr "Poiščite izračunane stolpce po imenu" msgid "Search charts by name, editor, or dashboard" msgstr "Iskanje grafikonov po imenu, uredniku ali nadzorni plošči" @@ -12755,13 +11766,11 @@ msgstr "Iskanje grafikonov po imenu, uredniku ali nadzorni plošči" msgid "Search columns" msgstr "Iskanje stolpcev" -#, fuzzy msgid "Search columns by name" -msgstr "Iskanje stolpcev" +msgstr "Išči stolpce po imenu" -#, fuzzy msgid "Search columns..." -msgstr "Iskanje stolpcev" +msgstr "Išči stolpce ..." msgid "Search editors" msgstr "Iskanje urednikov" @@ -12769,16 +11778,14 @@ msgstr "Iskanje urednikov" msgid "Search in filters" msgstr "Iskanje v filtrih" -#, fuzzy msgid "Search metrics by key or label" -msgstr "Iskanje mer in stolpcev" +msgstr "Išči mere po ključu ali oznaki" msgid "Search records" -msgstr "" +msgstr "Išči zapise" -#, fuzzy msgid "Search tags" -msgstr "Izberite oznake" +msgstr "Išči oznake" msgid "Search viewers" msgstr "Iskanje gledalcev" @@ -12787,7 +11794,7 @@ msgid "Search..." msgstr "Iskanje ..." msgid "Searches all text fields: Name, Description, Database & Schema" -msgstr "" +msgstr "Išče po vseh besedilnih poljih: ime, opis, podatkovna baza in shema" msgid "Second" msgstr "Sekunda" @@ -12820,16 +11827,15 @@ msgstr "Dodatna varnost" msgid "Security" msgstr "Varnost" -#, fuzzy msgid "See " -msgstr "serije" +msgstr "Glej " #, python-format msgid "See all %(tableName)s" msgstr "Poglej vse %(tableName)s" msgid "See all dashboards" -msgstr "" +msgstr "Prikaži vse nadzorne plošče" msgid "See less" msgstr "Oglejte si manj" @@ -12843,42 +11849,37 @@ msgstr "Podrobnosti poizvedbe" msgid "Select" msgstr "Izberi" -#, fuzzy, python-format +#, python-format msgid "Select %s or type to search %s" -msgstr "Izberite ali vnesite ime sheme" +msgstr "Izberite %s ali vnesite za iskanje %s" msgid "Select ..." msgstr "Izberite ..." -#, fuzzy msgid "Select All" -msgstr "Počisti izbor" +msgstr "Izberi vse" -#, fuzzy msgid "Select Database and Schema" -msgstr "Izberite podatkovno bazo" +msgstr "Izberi podatkovno bazo in shemo" msgid "Select Delivery Method" msgstr "Izberite način dostave" -#, fuzzy msgid "Select Filter" -msgstr "Izbirni filter" +msgstr "Izberi filter" msgid "Select Tags" msgstr "Izberite oznake" -#, fuzzy msgid "Select Value" -msgstr "Leva vrednost" +msgstr "Izberite vrednost" -#, fuzzy, python-format +#, python-format msgid "Select a %s" -msgstr "Izberite oznake" +msgstr "Izberite %s" -#, fuzzy msgid "Select a CSS template" -msgstr "Naloži CSS predlogo" +msgstr "Izberite predlogo CSS" msgid "Select a column" msgstr "Izberite stolpec" @@ -12910,9 +11911,8 @@ msgstr "Vnesite ločilnik za te podatke" msgid "Select a dimension" msgstr "Izberite dimenzijo" -#, fuzzy msgid "Select a linear color scheme" -msgstr "Izberite barvno shemo" +msgstr "Izberite linearno barvno shemo" msgid "Select a metric to display on the right axis" msgstr "Izberite mero za prikaz na desni osi" @@ -12926,11 +11926,8 @@ msgstr "" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Select a predefined CSS template to apply to your dashboard" -msgstr "" -"Izberite vnaprej določeno predlogo CSS za uporabo na svojem nadzornem " -"panelu" +msgstr "Izberite vnaprej določeno predlogo CSS, ki jo želite uporabiti na nadzorni plošči" msgid "Select a schema" msgstr "Izberite shemo" @@ -12938,13 +11935,11 @@ msgstr "Izberite shemo" msgid "Select a schema if the database supports this" msgstr "Izberite shemo (če vrsta podatkovne baze to podpira)" -#, fuzzy msgid "Select a semantic layer" -msgstr "Izberite shemo" +msgstr "Izberite semantično plast" -#, fuzzy msgid "Select a semantic layer type" -msgstr "Izberite tip vizualizacije" +msgstr "Izberite vrsto semantične plasti" msgid "Select a sheet name from the uploaded file" msgstr "Izberite ime zvezka iz naložene datoteke" @@ -12952,9 +11947,8 @@ msgstr "Izberite ime zvezka iz naložene datoteke" msgid "Select a tab" msgstr "Izberite zavihek" -#, fuzzy msgid "Select a theme" -msgstr "Izberite shemo" +msgstr "Izberite temo" msgid "" "Select a time grain for the visualization. The grain is the time interval" @@ -12969,9 +11963,8 @@ msgstr "Izberite tip vizualizacije" msgid "Select aggregate options" msgstr "Izberite agregacijske možnosti" -#, fuzzy msgid "Select all" -msgstr "Počisti izbor" +msgstr "Izberite vse" msgid "Select all data" msgstr "Izberite vse podatke" @@ -13003,9 +11996,8 @@ msgstr "Izberite barvno shemo" msgid "Select column" msgstr "Izberite stolpec" -#, fuzzy msgid "Select column name" -msgstr "Izberite stolpec" +msgstr "Izberite ime stolpca" msgid "" "Select columns that will be displayed in the table. You can multiselect " @@ -13017,9 +12009,8 @@ msgstr "" msgid "Select content type" msgstr "Izberite vrsto vsebine" -#, fuzzy msgid "Select currency code column" -msgstr "Izberite stolpec" +msgstr "Izberite stolpec kode valute" msgid "Select current page" msgstr "Izberite trenutno stran" @@ -13048,25 +12039,20 @@ msgstr "" msgid "Select dataset source" msgstr "Izberite podatkovni vir" -#, fuzzy msgid "Select datetime column" -msgstr "Izberite stolpec" +msgstr "Izberite stolpec datuma in časa" -#, fuzzy msgid "Select dimension" msgstr "Izberite dimenzijo" -#, fuzzy msgid "Select dimension and values" -msgstr "Izberite dimenzijo" +msgstr "Izberite dimenzijo in vrednosti" -#, fuzzy msgid "Select dimension for Top N" -msgstr "Izberite dimenzijo" +msgstr "Izberite dimenzijo za Top N" -#, fuzzy msgid "Select dimension values" -msgstr "Izberite dimenzijo" +msgstr "Izberite vrednosti dimenzij" msgid "Select editors" msgstr "Izberi urednike" @@ -13086,13 +12072,11 @@ msgstr "Izberi prvo vrednost kot privzeto" msgid "Select format" msgstr "Izberite obliko" -#, fuzzy msgid "Select groups" -msgstr "Izberite lastnike" +msgstr "Izberite skupine" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "" "Select layers in the order you want them stacked. First selected appears " "at the bottom.Layers let you combine multiple visualizations on one map. " @@ -13100,20 +12084,15 @@ msgid "" "arcs) that displays different data or insights. Stack them to reveal " "patterns and relationships across your data." msgstr "" -"Izberite plasti v vrstnem redu, v katerem jih želite zložiti. Prva " -"izbrana se prikaže na dnu. Plasti vam omogočajo kombiniranje več " -"vizualizacij na eni karti. Vsaka plast je shranjen grafikon deck.gl (kot " -"so razpršeni grafikoni, poligoni ali loki), ki prikazuje različne podatke" -" ali vpoglede. Zložite jih, da razkrijete vzorce in odnose v svojih " -"podatkih." +"Izberite plasti v vrstnem redu, v katerem želite, da so zložene. Prvo izbrano se prikaže na dnu. Sloji vam omogočajo kombiniranje več vizualizacij na enem " +"zemljevidu. Vsak sloj je shranjen grafikon deck.gl (kot so razpršeni grafikoni, poligoni ali loki), ki prikazuje različne podatke ali vpoglede. Zložite jih " +"na kup, da razkrijete vzorce in razmerja v svojih podatkih." -#, fuzzy msgid "Select layers to hide" -msgstr "Izberite grafikon za uporabo" +msgstr "Izberite plasti, ki jih želite skriti" -#, fuzzy msgid "Select object name" -msgstr "Izberite zadevo" +msgstr "Izberite ime predmeta" msgid "" "Select one or many metrics to display, that will be displayed in the " @@ -13137,10 +12116,10 @@ msgid "Select operator" msgstr "Izberite operator" msgid "Select or type BCC recipients" -msgstr "" +msgstr "Izberite ali vnesite prejemnike Skp" msgid "Select or type CC recipients" -msgstr "" +msgstr "Izberite ali vnesite prejemnike Kp" msgid "Select or type a custom value..." msgstr "Izberite ali vnesite poljubno vrednost..." @@ -13152,19 +12131,16 @@ msgid "Select or type dataset name" msgstr "Izberite ali vnesite ime podatkovnega seta" msgid "Select or type email recipients" -msgstr "" +msgstr "Izberite ali vnesite prejemnike e-pošte" -#, fuzzy msgid "Select page size" -msgstr "Izberite oznake" +msgstr "Izberite velikost strani" -#, fuzzy msgid "Select permissions" -msgstr "Verzija" +msgstr "Izberite dovoljenja" -#, fuzzy msgid "Select roles" -msgstr "Izberite lastnike" +msgstr "Izberite vloge" msgid "Select saved metrics" msgstr "Izberite shranjene mere" @@ -13172,29 +12148,24 @@ msgstr "Izberite shranjene mere" msgid "Select saved queries" msgstr "Izberite shranjene poizvedbe" -#, fuzzy msgid "Select schema" msgstr "Izberite shemo" msgid "Select scheme" msgstr "Izberite shemo" -#, fuzzy msgid "Select semantic views" -msgstr "Izberite shemo" +msgstr "Izberite semantične poglede" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fr, ja, lv, mi, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "" "Select shape for computing values. \"FIXED\" sets all zoom levels to the " "same size. \"LINEAR\" increases sizes linearly based on specified slope. " "\"EXP\" increases sizes exponentially based on specified exponent" msgstr "" -"Izberite obliko za izračun vrednosti. \"FIXED\" nastavi vse ravni " -"povečave na isto velikost. \"LINEAR\" linearno povečuje velikosti glede " -"na določen naklon. \"EXP\" eksponentno povečuje velikosti glede na " -"določen eksponent" +"Izberite obliko za izračun vrednosti. \"FIKSNO\" nastavi vse stopnje povečave na enako velikost. \"LINEAR\" linearno poveča velikosti na podlagi določenega " +"naklona. »EXP« eksponentno poveča velikosti glede na podani eksponent" msgid "Select subject" msgstr "Izberite zadevo" @@ -13234,82 +12205,59 @@ msgstr "" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, ja, lv, # ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Select the color used for values that indicate an increase in the chart" -msgstr "" -"Izberite barvo, ki se uporablja za vrednosti, ki kažejo povečanje na " -"grafikonu" +msgstr "Izberite barvo za vrednosti, ki označujejo povečanje v grafikonu" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, ja, lv, # ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Select the color used for values that represent total bars in the chart" -msgstr "" -"Izberite barvo, ki se uporablja za vrednosti, ki predstavljajo skupne " -"stolpce na grafikonu" +msgstr "Izberite barvo, uporabljeno za vrednosti, ki predstavljajo skupne stolpce v grafikonu" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, ja, lv, # ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Select the color used for values ​​that indicate a decrease in the chart." -msgstr "" -"Izberite barvo, ki se uporablja za vrednosti, ki kažejo zmanjšanje na " -"grafikonu." +msgstr "Izberite barvo, uporabljeno za vrednosti, ki označujejo zmanjšanje v grafikonu." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, ja, lv, # ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "" "Select the column containing currency codes such as USD, EUR, GBP, etc. " "Used when building charts when 'Auto-detect' currency formatting is " "enabled. If this column is not set or if a chart metric contains multiple" " currencies, charts will fall back to neutral numeric formatting." msgstr "" -"Izberite stolpec, ki vsebuje kode valut, kot so USD, EUR, GBP itd. " -"Uporablja se pri gradnji grafikonov, ko je omogočeno samodejno zaznavanje" -" oblikovanja valut. Če ta stolpec ni nastavljen ali če meritev grafikona " -"vsebuje več valut, bodo grafikoni prešli na nevtralno številčno " -"oblikovanje." +"Izberite stolpec, ki vsebuje kode valut, kot so USD, EUR, GBP itd. Uporablja se pri gradnji grafikonov, ko je omogočeno oblikovanje valute »Samodejno " +"zaznaj«. Če ta stolpec ni nastavljen ali če mera grafikona vsebuje več valut, se bodo grafikoni vrnili v nevtralno številsko oblikovanje." -#, fuzzy msgid "Select the fixed color" -msgstr "Izberite geojson stolpec" +msgstr "Izberite fiksno barvo" msgid "Select the geojson column" msgstr "Izberite geojson stolpec" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "" "Select the map tile provider. MapLibre is open-source and requires no API" " key. Mapbox requires MAPBOX_API_KEY to be configured in Superset." msgstr "" -"Izberite ponudnika kartografskih ploščic. MapLibre je odprtokodna rešitev" -" in ne zahteva API ključa. Mapbox zahteva, da je MAPBOX_API_KEY " -"konfiguriran v Superset-u." +"Izberite ponudnika ploščic zemljevida. MapLibre je odprtokoden in ne potrebuje ključa API. Mapbox zahteva, da je MAPBOX_API_KEY konfiguriran v Supersetu." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "" "Select the metric used to determine which color breakpoint range each " "path falls into." -msgstr "" -"Izberite metriko, ki se uporablja za določanje, v kateri razpon prelomnih" -" točk barve spada vsaka pot." +msgstr "Izberite mero, ki se uporablja za določitev, v kateri obseg barvnih prelomnih točk spada posamezna pot." -#, fuzzy msgid "Select the type of color scheme to use." -msgstr "Izberite barvno shemo" +msgstr "Izberite vrsto barvne sheme, ki jo želite uporabiti." -#, fuzzy msgid "Select users" -msgstr "Izberite lastnike" +msgstr "Izberite uporabnike" -#, fuzzy msgid "Select values" -msgstr "Izberite lastnike" +msgstr "Izberite vrednosti" #, python-format msgid "" @@ -13321,112 +12269,88 @@ msgstr "" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "" "Select which time grains are available in the filter control. This is a " "UI allow list only and does not add extra conditions to the underlying " "queries." msgstr "" -"Izberite, katera časovna zrna so na voljo v kontrolniku filtra. To je " -"samo seznam dovoljenih možnosti za vmesnik in ne dodaja dodatnih pogojev " -"osnovnim poizvedbam." +"Izberite, katera časovna zrna so na voljo v kontrolniku filtra. To je samo dovoljeni seznam uporabniškega vmesnika in osnovnim poizvedbam ne dodaja dodatnih " +"pogojev." -#, fuzzy msgid "Selected" -msgstr "0 izbranih" +msgstr "Izbrano" msgid "Selecting a database is required" msgstr "Izbira podatkovne baze je obvezna" -#, fuzzy msgid "Selection method" -msgstr "Izberite način dostave" +msgstr "Metoda izbire" -#, fuzzy msgid "Semantic" -msgstr "Podrobnosti" +msgstr "Semantična" -#, fuzzy msgid "Semantic Layer" -msgstr "Sloj z oznakami" +msgstr "Semantična plast" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "Semantic View" msgstr "Semantični pogled" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "Semantic Views" msgstr "Semantični pogledi" -#, fuzzy msgid "Semantic layer" -msgstr "Sloj z oznakami" +msgstr "Semantična plast" -#, fuzzy msgid "Semantic layer could not be created." -msgstr "Sloja z oznakami ni mogoče ustvariti." +msgstr "Semantične plasti ni bilo mogoče ustvariti." -#, fuzzy msgid "Semantic layer could not be deleted." -msgstr "Slojev z oznakami ni mogoče izbrisati." +msgstr "Semantične plasti ni bilo mogoče izbrisati." -#, fuzzy msgid "Semantic layer could not be updated." -msgstr "Sloja z oznakami ni mogoče posodobiti." +msgstr "Semantične plasti ni bilo mogoče posodobiti." -#, fuzzy msgid "Semantic layer created" -msgstr "Predloga oznake ustvarjena" +msgstr "Semantična plast je ustvarjena" -#, fuzzy msgid "Semantic layer does not exist" -msgstr "Grafikon ne obstaja" +msgstr "Semantična plast ne obstaja" -#, fuzzy msgid "Semantic layer parameters are invalid." -msgstr "Parametri sloja z oznakami so neveljavni." +msgstr "Parametri semantične plasti so neveljavni." -#, fuzzy msgid "Semantic layer type" -msgstr "Tip sloja z oznakami" +msgstr "Vrsta semantične plasti" -#, fuzzy msgid "Semantic layer updated" -msgstr "Predloga oznake posodobljena" +msgstr "Semantična plast je posodobljena" -#, fuzzy msgid "Semantic view could not be created." -msgstr "Podatkovnega niza ni mogoče ustvariti." +msgstr "Semantičnega pogleda ni bilo mogoče ustvariti." -#, fuzzy msgid "Semantic view could not be deleted." -msgstr "CSS predlog ni mogoče izbrisati." +msgstr "Semantičnega pogleda ni bilo mogoče izbrisati." -#, fuzzy msgid "Semantic view could not be updated." -msgstr "Podatkovnega niza ni mogoče posodobiti." +msgstr "Semantičnega pogleda ni bilo mogoče posodobiti." -#, fuzzy msgid "Semantic view does not exist" -msgstr "Podatkovni set ne obstaja" +msgstr "Semantični pogled ne obstaja" -#, fuzzy msgid "Semantic view parameters are invalid." -msgstr "Parametri podatkovnega seta so neveljavni." +msgstr "Parametri semantičnega pogleda so neveljavni." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "Semantic view updated" msgstr "Semantični pogled posodobljen" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "Semantic views" msgstr "Semantični pogledi" @@ -13434,7 +12358,7 @@ msgid "Send as CSV" msgstr "Pošlji kot CSV" msgid "Send as Excel" -msgstr "" +msgstr "Pošlji kot Excel" msgid "Send as PDF" msgstr "Pošlji kot PDF" @@ -13468,26 +12392,22 @@ msgstr "Tip grafikona za posamezno podatkovno serijo (črtni, stolpčni, ...)" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Series decrease setting" msgstr "Nastavitev zmanjšanja serije" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Series increase setting" msgstr "Nastavitev povečanja serije" msgid "Series limit" msgstr "Omejitev števila serij" -#, fuzzy msgid "Series settings" -msgstr "Nastavitve datoteke" +msgstr "Nastavitve serije" -#, fuzzy msgid "Series total setting" -msgstr "Obdržim nastavitve kontrolnika?" +msgstr "Skupna nastavitev serije" msgid "Series type" msgstr "Tip serije" @@ -13500,73 +12420,60 @@ msgstr "Paginacija na strani strežnika" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy, python-format +#, python-format msgid "Server pagination needs to be enabled for values over %s" -msgstr "Strežniška paginacija mora biti omogočena za vrednosti nad %s" +msgstr "Straniranje strežnika mora biti omogočeno za vrednosti nad %s" msgid "Service Account" msgstr "Servisni račun" -#, fuzzy msgid "Service version" -msgstr "Servisni račun" +msgstr "Različica storitve" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Set System Dark Theme" -msgstr "Nastavi sistemsko temno temo" +msgstr "Nastavite temno temo sistema" -#, fuzzy msgid "Set System Default Theme" -msgstr "Privzet datumčas" +msgstr "Nastavite sistemsko privzeto temo" -#, fuzzy msgid "Set as default dark theme" -msgstr "Privzet datumčas" +msgstr "Nastavi kot privzeto temno temo" -#, fuzzy msgid "Set as default light theme" -msgstr "Filter ima privzeto vrednost" +msgstr "Nastavi kot privzeto svetlobno temo" -#, fuzzy msgid "Set auto-refresh" -msgstr "Nastavi interval samodejnega osveževanja" +msgstr "Nastavite samodejno osveževanje" msgid "Set filter mapping" msgstr "Nastavi shemo filtrov" -#, fuzzy msgid "Set local theme for testing" -msgstr "Omogoči napovedovanje" +msgstr "Nastavite lokalno temo za testiranje" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, pt_BR, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Set local theme for testing (preview only)" -msgstr "Nastavi lokalno temo za testiranje (samo predogled)" +msgstr "Nastavite lokalno temo za testiranje (samo predogled)" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, pt_BR, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Set refresh frequency for current session only." -msgstr "Nastavi frekvenco osveževanja samo za trenutno sejo." +msgstr "Nastavite frekvenco osveževanja samo za trenutno sejo." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, pt_BR, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Set the automatic refresh frequency for this dashboard." -msgstr "Nastavi samodejno frekvenco osveževanja za ta nadzorni panel." +msgstr "Nastavite frekvenco samodejnega osveževanja za to nadzorno ploščo." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, pt_BR, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "" "Set the automatic refresh frequency for this dashboard. The dashboard " "will reload its data at the specified interval." -msgstr "" -"Nastavi samodejno frekvenco osveževanja za ta nadzorni panel. Nadzorni " -"panel bo znova naložil svoje podatke v določenem intervalu." +msgstr "Nastavite frekvenco samodejnega osveževanja za to nadzorno ploščo. Nadzorna plošča bo znova naložila podatke v določenem intervalu." msgid "Set up an email report" msgstr "Nastavite e-poštno poročilo" @@ -13576,15 +12483,13 @@ msgstr "Nastavite bistvene atribute, kot sta ime in opis." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, pt_BR, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "" "Sets the default temporal column for this dataset. Automatically selected" " as the time column when building charts that require a time dimension " "and used in dashboard level time filters." msgstr "" -"Nastavi privzeti časovni stolpec za ta nabor podatkov. Samodejno se " -"izbere kot časovni stolpec pri gradnji grafikonov, ki zahtevajo časovno " -"dimenzijo, in se uporablja v časovnih filtrih na ravni nadzornega panela." +"Nastavi privzeti časovni stolpec za ta niz podatkov. Samodejno izbran kot časovni stolpec pri gradnji grafikonov, ki zahtevajo časovno dimenzijo, in se " +"uporablja v časovnih filtrih na ravni nadzorne plošče." msgid "" "Sets the hierarchy levels of the chart. Each level is\n" @@ -13600,9 +12505,8 @@ msgstr "Nastavitve" msgid "Settings for time series" msgstr "Nastavitve časovne vrste" -#, fuzzy msgid "Shape" -msgstr "Oblika torte" +msgstr "Oblika" msgid "Share" msgstr "Deljenje" @@ -13613,9 +12517,8 @@ msgstr "Deli grafikon po e-pošti" msgid "Share permalink by email" msgstr "Deli povezavo po e-pošti" -#, fuzzy msgid "Shared" -msgstr "Deljenje" +msgstr "V skupni rabi" msgid "Shared query" msgstr "Deljene poizvedbe" @@ -13681,22 +12584,20 @@ msgstr "Prikaži dnevnik" msgid "Show Markers" msgstr "Prikaži markerje" -#, fuzzy msgid "Show Metric Name" -msgstr "Prikaži imena mer" +msgstr "Prikaži ime mere" msgid "Show Metric Names" msgstr "Prikaži imena mer" msgid "Show Null Values" -msgstr "" +msgstr "Prikaži ničelne vrednosti" msgid "Show Range Filter" msgstr "Prikaži filter obdobja" -#, fuzzy msgid "Show SQL" -msgstr "Prikaži dnevnik" +msgstr "Prikaži SQL" msgid "Show Timestamp" msgstr "Prikaži časovno značko" @@ -13716,9 +12617,8 @@ msgstr "Prikaži zgornje oznake" msgid "Show Values" msgstr "Prikaži vrednosti" -#, fuzzy msgid "Show X-axis" -msgstr "Prikaži Y-os" +msgstr "Pokaži X-os" msgid "Show Y-axis" msgstr "Prikaži Y-os" @@ -13731,13 +12631,15 @@ msgstr "" "pokaže to, drugače pa glede na podatke." msgid "Show a draggable slider to control the visible range of the Y-axis." -msgstr "" +msgstr "Prikaže drsnik za nastavitev vidnega obsega osi Y." msgid "" "Show a summary row of total aggregations: the selected metrics in " "aggregate mode, or the sum of numeric columns in raw records mode. Note " "that row limit does not apply to the result." msgstr "" +"Prikaže vrstico povzetka skupnih agregacij: izbrane mere v agregatnem načinu ali vsoto številskih stolpcev v načinu neobdelanih zapisov. Omejitev vrstic za " +"rezultat ne velja." msgid "Show all columns" msgstr "Prikaži vse stolpce" @@ -13748,20 +12650,17 @@ msgstr "Prikaži oznake na X-osi" msgid "Show cell bars" msgstr "Prikaži grafe v celicah" -#, fuzzy msgid "Show cell bars for all columns" -msgstr "Prikaži vse stolpce" +msgstr "Pokaži vrstice celic za vse stolpce" msgid "Show chart description" msgstr "Prikaži opis grafikona" -#, fuzzy msgid "Show chart query timestamps" -msgstr "Prikaži časovno značko" +msgstr "Prikaži časovne žige poizvedbe grafikona" -#, fuzzy msgid "Show column headers" -msgstr "Naslov stolpca" +msgstr "Prikaži naslove stolpcev" msgid "Show columns subtotal" msgstr "Prikaži delne vsote stolpcev" @@ -13775,12 +12674,11 @@ msgstr "Prikaži točke kot krožne markerje na krivuljah" msgid "Show empty columns" msgstr "Prikaži prazne stolpce" -#, fuzzy msgid "Show entries per page" -msgstr "Prikaži %s vnosov" +msgstr "Prikaži vnose na stran" msgid "Show full range for time shift" -msgstr "" +msgstr "Prikaži celoten obseg za časovni zamik" msgid "" "Show hierarchical relationships of data, with the value represented by " @@ -13804,9 +12702,8 @@ msgstr "Prikaži legendo" msgid "Show less columns" msgstr "Prikaži manj stolpcev" -#, fuzzy msgid "Show min/max axis labels" -msgstr "Naslov X-osi" +msgstr "Prikaži oznake najmanjše/največje osi" msgid "Show minor ticks on axes." msgstr "Na oseh prikaži pomožne oznake." @@ -13826,13 +12723,11 @@ msgstr "Prikaži kazalec" msgid "Show progress" msgstr "Prikaži območje" -#, fuzzy msgid "Show query identifiers" -msgstr "Podrobnosti poizvedbe" +msgstr "Prikaži identifikatorje poizvedbe" -#, fuzzy msgid "Show row labels" -msgstr "Prikaži oznake" +msgstr "Pokaži oznake vrstic" msgid "Show rows subtotal" msgstr "Prikaži delne vsote vrstic" @@ -13852,9 +12747,8 @@ msgstr "Prikaži povzetek" msgid "Show the value on top of the bar" msgstr "Prikaži vrednosti na vrhu stolpcev" -#, fuzzy msgid "Show total" -msgstr "Prikaži vsoto" +msgstr "Pokaži skupno" msgid "" "Show total aggregations of selected metrics. Note that row limit does not" @@ -13863,14 +12757,13 @@ msgstr "" "Prikaži skupno agregacijo izbrane mere. Omejitev števila vrstic ne vpliva" " na rezultat." -#, fuzzy msgid "Show value" msgstr "Prikaži vrednost" msgid "" "Showcases a metric along with a comparison of value, change, and percent " "change for a selected time period." -msgstr "" +msgstr "Prikaže mero skupaj s primerjavo vrednosti, spremembe in odstotne spremembe za izbrano časovno obdobje." msgid "" "Showcases a single metric front-and-center. Big number is best used to " @@ -13910,9 +12803,9 @@ msgstr "" "Prikaže napredovanje posamezne mere glede na cilj. Večja napolnjenost, " "pomeni, da je mera bližje cilju." -#, fuzzy, python-format +#, python-format msgid "Showing %s of %s items" -msgstr "Prikazanih %s od %s" +msgstr "Prikazanih je %s od %s elementov" msgid "Shows a list of all series available at that point in time" msgstr "Prikaže vrednosti vseh serij za posamezno časovno točko" @@ -13920,13 +12813,11 @@ msgstr "Prikaže vrednosti vseh serij za posamezno časovno točko" msgid "Shows or hides markers for the time series" msgstr "Prikaže ali skrije markerje časovne serije" -#, fuzzy msgid "Sign in" -msgstr "Ne vsebuje (NOT IN)" +msgstr "Prijavi se" -#, fuzzy msgid "Sign in with" -msgstr "Prijava z" +msgstr "Prijavi se z" msgid "Significance Level" msgstr "Stopnja značilnosti" @@ -13952,9 +12843,8 @@ msgstr "Ena vrednost" msgid "Single value type" msgstr "Tip z eno vrednostjo" -#, fuzzy msgid "Size in pixels" -msgstr "Določa velikost mreže v pikslih" +msgstr "Velikost v slikovnih pikah" msgid "Size of edge symbols" msgstr "Velikost simbola povezave" @@ -13962,44 +12852,34 @@ msgstr "Velikost simbola povezave" msgid "Size of marker. Also applies to forecast observations." msgstr "Velikost markerja. Upošteva se tudi za napovedi." -msgid "Size of the dot representing the largest value of the dot size metric." -msgstr "" - -msgid "Size of the dot representing the smallest value of the dot size metric." -msgstr "" - msgid "Skip blank lines rather than interpreting them as Not A Number values" msgstr "Raje izpusti prazne vrstice, kot pa da so prepoznane kot NaN vrednosti" msgid "Skip rows" msgstr "Izpusti vrstice" -#, fuzzy msgid "Skip rows is required" -msgstr "Zahtevana je vrednost" +msgstr "Potreben je preskok vrstic" msgid "Skip spaces after delimiter" msgstr "Izpusti presledke za ločilnikom" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy, python-format +#, python-format msgid "Skipped %d system themes that cannot be deleted" -msgstr "Preskočeno %d sistemskih tem, ki jih ni mogoče izbrisati" +msgstr "Preskočene sistemske teme %d, ki jih ni mogoče izbrisati" -#, fuzzy msgid "Slice Id" -msgstr "Debelina črte" +msgstr "ID rezine" -#, fuzzy msgid "Slider" -msgstr "Zapolnjen" +msgstr "Drsnik" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Slider and range input" -msgstr "Drsnik in vnos obsega" +msgstr "Vnos drsnika in obsega" msgid "Slug" msgstr "Slug" @@ -14024,44 +12904,33 @@ msgid "Solid" msgstr "Zapolnjen" msgid "Solid background" -msgstr "" - -msgid "" -"Some filters are inherited from physical tables referenced in this " -"virtual dataset." -msgstr "" +msgstr "Enobarvno ozadje" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "Some groups could not be resolved and are shown as IDs." msgstr "Nekaterih skupin ni bilo mogoče razrešiti in so prikazane kot ID-ji." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "Some permissions could not be resolved and are shown as IDs." msgstr "Nekaterih dovoljenj ni bilo mogoče razrešiti in so prikazana kot ID-ji." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "Some required filters on other tabs have values and will not be cleared" -msgstr "" -"Nekateri zahtevani filtri na drugih zavihkih imajo vrednosti in ne bodo " -"počiščeni" +msgstr "Nekateri obvezni filtri na drugih zavihkih imajo vrednosti in ne bodo počiščeni" msgid "Some tables are not shown. Refine your search." -msgstr "" +msgstr "Nekatere tabele niso prikazane. Izboljšajte iskalni pogoj." msgid "" "Something went wrong loading the dashboard. Check the dev console for " "details." -msgstr "" +msgstr "Pri nalaganju nadzorne plošče je prišlo do napake. Podrobnosti preverite v razvijalski konzoli." -#, fuzzy msgid "Something went wrong while saving the user info" -msgstr "Nekaj je šlo narobe. Poskusite ponovno." +msgstr "Pri shranjevanju podatkov o uporabniku je šlo nekaj narobe" msgid "" "Something went wrong with embedded authentication. Check the dev console " @@ -14118,7 +12987,6 @@ msgstr "Vaš brskalnik ne podpira kopiranja. Uporabite Ctrl / Cmd + C!" msgid "Sort" msgstr "Razvrsti" -#, fuzzy msgid "Sort Ascending" msgstr "Razvrsti naraščajoče" @@ -14150,20 +13018,17 @@ msgstr "Razvrščanje po" msgid "Sort by %s" msgstr "Razvrščanje po %s" -#, fuzzy msgid "Sort by data" -msgstr "Razvrščanje po" +msgstr "Razvrsti po podatkih" msgid "Sort by metric" msgstr "Mera za razvrščanje" -#, fuzzy msgid "Sort by original table order" -msgstr "Vrstni red stolpcev izvorne tabele" +msgstr "Razvrsti po izvirnem vrstnem redu tabele" -#, fuzzy msgid "Sort by series" -msgstr "Razvrsti serije po" +msgstr "Razvrsti po seriji" msgid "Sort columns alphabetically" msgstr "Razvrsti stolpce po abecedi" @@ -14174,16 +13039,14 @@ msgstr "Razvrsti stolpce" msgid "Sort descending" msgstr "Razvrsti padajoče" -#, fuzzy msgid "Sort display control values" -msgstr "Razvrsti vrednosti filtra" +msgstr "Razvrsti vrednosti nadzora prikaza" msgid "Sort filter values" msgstr "Razvrsti vrednosti filtra" -#, fuzzy msgid "Sort legend" -msgstr "Prikaži legendo" +msgstr "Razvrsti legendo" msgid "Sort metric" msgstr "Mera za razvrščanje" @@ -14193,16 +13056,13 @@ msgstr "Razvrščanje poizvedbe po" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "" "Sort results by series name in ascending order. When combined with \"Sort" " by metric\", this acts as a tiebreaker for equal metric values. Adding " "this sort may reduce query performance on some databases." msgstr "" -"Razvrsti rezultate po imenu serije v naraščajočem vrstnem redu. V " -"kombinaciji z »Razvrsti po metriki« to deluje kot odločilec pri enakih " -"vrednostih metrike. Dodajanje tega razvrščanja lahko zmanjša zmogljivost " -"poizvedb na nekaterih zbirkah podatkov." +"Razvrsti rezultate po imenu serije v naraščajočem vrstnem redu. V kombinaciji z možnostjo »Razvrsti po meri« to deluje kot izenačenje za enake vrednosti " +"mere. Dodajanje tega razvrščanja lahko zmanjša zmogljivost poizvedb v nekaterih zbirkah podatkov." msgid "Sort rows by" msgstr "Razvrsti vrstice" @@ -14216,9 +13076,8 @@ msgstr "Način razvrščanja" msgid "Source" msgstr "Izvor" -#, fuzzy msgid "Source Color" -msgstr "Barva obrobe" +msgstr "Izvorna barva" msgid "Source SQL" msgstr "Izvorni SQL" @@ -14226,9 +13085,8 @@ msgstr "Izvorni SQL" msgid "Source category" msgstr "Kategorija izvora" -#, fuzzy msgid "Source location" -msgstr "Kategorija izvora" +msgstr "Lokacija vira" msgid "Sparkline" msgstr "Hitri grafikon" @@ -14257,7 +13115,6 @@ msgstr "Število razdelitev" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Split stack by" msgstr "Razdeli sklad po" @@ -14275,9 +13132,8 @@ msgstr "Naloži" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Stack in groups, where each group corresponds to a dimension" -msgstr "Zloži v skupine, kjer vsaka skupina ustreza dimenziji" +msgstr "Zložite v skupine, kjer vsaka skupina ustreza dimenziji" msgid "Stack series" msgstr "Nalagaj serije" @@ -14303,16 +13159,14 @@ msgstr "Začetek" msgid "Start (Longitude, Latitude): " msgstr "Začetek (Zemlj. dolžina, širina): " -#, fuzzy msgid "Start (inclusive)" -msgstr "ZAČETEK (VKLJUČEN)" +msgstr "Začetek (vključno)" msgid "Start Longitude & Latitude" msgstr "Začetna Dolž. in Širina" -#, fuzzy msgid "Start Time" -msgstr "Začetni datum" +msgstr "Začetni čas" msgid "Start angle" msgstr "Začetni kot" @@ -14339,13 +13193,11 @@ msgstr "" msgid "Started" msgstr "Začetek" -#, fuzzy msgid "Starts With" -msgstr "Širina grafikona" +msgstr "Začne se z" -#, fuzzy msgid "Starts with (ILIKE x%)" -msgstr "Širina grafikona" +msgstr "Začne se z (ILIKE x%)" msgid "State" msgstr "Status" @@ -14396,24 +13248,16 @@ msgstr "Ustavi (Ctrl + x)" msgid "Stopped an unsafe database connection" msgstr "Nevarna povezava s podatkovno bazo je bila ustavljena" -#, python-format -msgid "" -"Storage key exceeds the maximum allowed length of %(max_length)d " -"characters." -msgstr "" - msgid "Stream" msgstr "Tok" msgid "Streets" msgstr "Ulice" -#, fuzzy msgid "Streets (Carto)" -msgstr "Drevesni grafikon" +msgstr "Ulice (Carto)" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ja] -#, fuzzy msgid "Streets (OSM)" msgstr "Ulice (OSM)" @@ -14434,11 +13278,8 @@ msgstr "Strukturni" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "Structure is managed by the upstream semantic layer and is read-only." -msgstr "" -"Struktura je upravljana s strani nadrejenega semantičnega sloja in je " -"samo za branje." +msgstr "Strukturo upravlja zgornji semantični sloj in je samo za branje." msgid "Style" msgstr "Slog" @@ -14446,13 +13287,11 @@ msgstr "Slog" msgid "Style the ends of the progress bar with a round cap" msgstr "Zaobljena oblika koncev območja" -#, fuzzy msgid "Styling" -msgstr "STRING" +msgstr "Oblikovanje" -#, fuzzy msgid "Subcategories" -msgstr "Kategorija" +msgstr "Podkategorije" msgid "Subdomain" msgstr "Poddomena" @@ -14460,9 +13299,6 @@ msgstr "Poddomena" msgid "Subject" msgstr "Subjekt" -msgid "Subject list" -msgstr "" - msgid "Subject type" msgstr "Vrsta subjekta" @@ -14475,26 +13311,24 @@ msgstr "Subjekti niso veljavni" msgid "Submit" msgstr "Pošlji" -#, fuzzy msgid "Subscribers" -msgstr "Kategorija" +msgstr "Naročniki" -#, fuzzy msgid "Subtitle" -msgstr "Naslov zavihka" +msgstr "Podnaslov" msgid "Subtotal" msgstr "Delna vsota" msgid "Success" -msgstr "Uspelo" +msgstr "Uspeh" msgid "Success message" -msgstr "" +msgstr "Sporočilo o uspehu" -#, fuzzy, python-format +#, python-format msgid "Successfully changed %s!" -msgstr "Podatkovni set uspešno spremenjen!" +msgstr "Uspešno spremenjen %s!" msgid "Suffix" msgstr "Pripona" @@ -14505,6 +13339,15 @@ msgstr "Pripona za prikaz procenta" msgid "Sum" msgstr "Vsota" +msgid "Sum as Fraction of Columns" +msgstr "Vsota kot delež stolpcev" + +msgid "Sum as Fraction of Rows" +msgstr "Vsota kot delež vrstic" + +msgid "Sum as Fraction of Total" +msgstr "Vsota kot delež celote" + msgid "Sum of values over specified period" msgstr "Vsota vrednosti v dani periodi" @@ -14529,9 +13372,8 @@ msgstr "Dokumentacija SDK za vgrajevanje." msgid "Superset chart" msgstr "Superset grafikon" -#, fuzzy msgid "Superset docs link" -msgstr "Superset grafikon" +msgstr "Povezava do dokumentacije Superset" msgid "Superset encountered an error while running a command." msgstr "Superset je naletel na napako pri izvajanju ukaza." @@ -14542,15 +13384,15 @@ msgstr "Superset je naletel na nepričakovano napako." msgid "Supported databases" msgstr "Podprte podatkovne baze" -#, fuzzy, python-format +#, python-format msgid "Swap %s" -msgstr "Zamenjaj podatkovni set" +msgstr "Zamenjaj %s" msgid "Swap rows and columns" msgstr "Zamenjaj vrstice in stolpce" msgid "Sweep angle" -msgstr "" +msgstr "Kot loka" msgid "" "Swiss army knife for visualizing data. Choose between step, line, " @@ -14578,7 +13420,6 @@ msgstr "Velikost simbola" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fr, ja, lv, mi, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Sync Permissions" msgstr "Sinhroniziraj dovoljenja" @@ -14587,13 +13428,13 @@ msgstr "Sinhroniziraj stolpce z virom" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fr, ja, lv, mi, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy, python-format +#, python-format msgid "Syncing permissions for %s" msgstr "Sinhronizacija dovoljenj za %s" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fr, ja, lv, mi, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy, python-format +#, python-format msgid "Syncing permissions for %s in the background" msgstr "Sinhronizacija dovoljenj za %s v ozadju" @@ -14606,27 +13447,23 @@ msgstr "" "Napaka v sintaksi: %(qualifier)s input \"%(input)s\" expecting " "\"%(expected)s" -#, fuzzy msgid "System" -msgstr "tok" +msgstr "Sistem" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, pt_BR, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "System Theme - Read Only" -msgstr "Sistemska tema - samo za branje" +msgstr "Sistemska tema – samo za branje" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, pt_BR, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "System dark theme removed" -msgstr "Sistemska temna tema je bila odstranjena" +msgstr "Sistemska temna tema je odstranjena" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, pt_BR, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "System default theme removed" -msgstr "Sistemska privzeta tema je bila odstranjena" +msgstr "Sistemska privzeta tema je odstranjena" msgid "TABLES" msgstr "TABELE" @@ -14638,13 +13475,6 @@ msgstr "ČASOVNI_OBSEG" msgid "THU" msgstr "ČET" -msgid "TTL must be a positive integer." -msgstr "" - -#, python-format -msgid "TTL must not exceed %(max_ttl)d seconds." -msgstr "" - msgid "TUE" msgstr "TOR" @@ -14668,9 +13498,8 @@ msgstr "Tabela %(table)s ni bila najdena v podatkovni bazi %(db)s" msgid "Table Name" msgstr "Ime tabele" -#, fuzzy msgid "Table V2" -msgstr "Tabela" +msgstr "Tabela V2" #, python-format msgid "" @@ -14693,13 +13522,11 @@ msgstr "Trajanje predpomnilnika tabele" msgid "Table columns" msgstr "Stolpci tabele" -#, fuzzy msgid "Table name" msgstr "Ime tabele" -#, fuzzy msgid "Table name is required" -msgstr "Zahtevano je ime" +msgstr "Ime tabele je obvezno" msgid "Table name undefined" msgstr "Ime tabele ni definirano" @@ -14743,7 +13570,7 @@ msgid "Tag created" msgstr "Oznaka ustvarjena" msgid "Tag description" -msgstr "" +msgstr "Opis oznake" msgid "Tag name" msgstr "Ime oznake" @@ -14779,76 +13606,63 @@ msgstr "Kategorija cilja" msgid "Target value" msgstr "Ciljna vrednost" -#, fuzzy msgid "Task" -msgstr "oznake" +msgstr "Naloga" -#, fuzzy, python-format +#, python-format msgid "Task cancelled: %s" -msgstr "Poročilo ni uspelo" +msgstr "Opravilo je preklicano: %s" -#, fuzzy msgid "Task could not be aborted." -msgstr "Oznake ni mogoče posodobiti." +msgstr "Naloge ni bilo mogoče prekiniti." -#, fuzzy msgid "Task could not be created." -msgstr "Oznake ni mogoče ustvariti." +msgstr "Naloge ni bilo mogoče ustvariti." -#, fuzzy msgid "Task could not be updated." -msgstr "Oznake ni mogoče posodobiti." +msgstr "Naloge ni bilo mogoče posodobiti." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "" "Task is not abortable. The task is in progress but has not registered an " "abort handler." -msgstr "" -"Naloge ni mogoče prekiniti. Naloga je v teku, vendar ni registrirala " -"obravnavalnika za prekinitev." +msgstr "Opravila ni mogoče prekiniti. Naloga je v teku, vendar ni registrirala obdelovalca prekinitve." -#, fuzzy msgid "Task parameters are invalid." -msgstr "Parametri oznak so neveljavni." +msgstr "Parametri opravila so neveljavni." -#, fuzzy msgid "Tasks" -msgstr "oznake" +msgstr "Naloge" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "Tasks will appear here as background operations are executed." -msgstr "Naloge se bodo prikazale tukaj, ko se bodo izvajale operacije v ozadju." +msgstr "Naloge se bodo pojavile tukaj, ko se bodo izvajale operacije v ozadju." msgid "Template" msgstr "Predloga" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "" "Template for cell titles. Use Handlebars templating syntax (a popular " "templating library that uses double curly brackets for variable " "substitution): {{row}}, {{column}}, {{rowLabel}}, {{columnLabel}}" msgstr "" -"Predloga za naslove celic. Uporabite sintakso predlog Handlebars " -"(priljubljena knjižnica predlog, ki za nadomeščanje spremenljivk " -"uporablja dvojne zavite oklepaje): {{row}}, {{column}}, {{rowLabel}}, " -"{{columnLabel}}" +"Predloga za naslove celic. Uporabite sintakso predlog Handlebars (priljubljena knjižnica predlog, ki uporablja dvojne zavite oklepaje za zamenjavo " +"spremenljivk): {{row}}, {{column}}, {{rowLabel}}, {{columnLabel}}" msgid "Template parameters" msgstr "Parametri predlog" -#, fuzzy, python-format +#, python-format msgid "Template processing error: %(error)s" -msgstr "Napaka obdelave: %(error)s" +msgstr "Napaka pri obdelavi predloge: %(error)s" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy, python-format +#, python-format msgid "Template processing failed: %(ex)s" msgstr "Obdelava predloge ni uspela: %(ex)s" @@ -14888,15 +13702,15 @@ msgstr "Besedilo vključeno v e-pošto" #, python-format msgid "The %(key)s in metadata_cache_timeout must be a non-negative integer." -msgstr "" +msgstr "The %(key)s in metadata_cache_timeout must be a non-negative integer." -#, fuzzy, python-format +#, python-format msgid "The %s" -msgstr "Pridobljeno %s" +msgstr "%s" -#, fuzzy, python-format +#, python-format msgid "The %s linked to this chart may have been deleted." -msgstr "Podatkovni set, povezan s tem grafikonom, je bil izbrisan." +msgstr "%s, povezan s tem grafikonom, je morda izbrisan." #, python-format msgid "The API response from %s does not match the IDatabaseTable interface." @@ -14917,13 +13731,6 @@ msgstr "" "CTAS (create table as select) na koncu nima SELECT stavka. Poskrbite, da " "bo v poizvedbi SELECT zadnji stavek. Potem ponovno poženite poizvedbo." -#, python-format -msgid "" -"The Custom SQL metric \"%(metric)s\" is not an aggregate and can't be " -"combined with a GROUP BY. Wrap it in an aggregate function, e.g. " -"%(example)s." -msgstr "" - msgid "" "The GeoJsonLayer takes in GeoJSON formatted data and renders it as " "interactive polygons, lines and points (circles, icons and/or texts)." @@ -14933,37 +13740,25 @@ msgstr "" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "" "The Global Task Framework is not enabled. Please contact your " "administrator to enable the GLOBAL_TASK_FRAMEWORK feature flag." -msgstr "" -"Global Task Framework ni omogočen. Prosimo, stopite v stik z vašim " -"skrbnikom, da omogoči zastavico funkcije GLOBAL_TASK_FRAMEWORK." +msgstr "Globalni okvir opravil ni omogočen. Obrnite se na skrbnika, da omogoči zastavico funkcije GLOBAL_TASK_FRAMEWORK." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "" "The Global Task Framework is not enabled. Set GLOBAL_TASK_FRAMEWORK=True " "in your feature flags to use @task. See " "https://superset.apache.org/docs/configuration/async-queries-celery for " "configuration details." msgstr "" -"Global Task Framework ni omogočen. Nastavite GLOBAL_TASK_FRAMEWORK=True v" -" svojih zastavicah funkcij za uporabo @task. Za podrobnosti o " -"konfiguraciji glejte https://superset.apache.org/docs/configuration" -"/async-queries-celery." - -msgid "The SQL query mutator removed all executable statements from this query." -msgstr "" +"Globalni okvir opravil ni omogočen. Nastavite GLOBAL_TASK_FRAMEWORK=True v zastavicah funkcij za uporabo @task. Za podrobnosti konfiguracije glejte https://" +"superset.apache.org/docs/configuration/async-queries-celery." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ja] -#, fuzzy msgid "The SSH server host key could not be verified against the expected key." -msgstr "" -"Ključa gostitelja SSH strežnika ni bilo mogoče preveriti glede na " -"pričakovani ključ." +msgstr "Ključa gostitelja strežnika SSH ni bilo mogoče preveriti glede na pričakovani ključ." msgid "" "The Sankey chart visually tracks the movement and transformation of " @@ -14988,15 +13783,11 @@ msgstr "V URL-ju manjkata parametra dataset_id ali slice_id." msgid "The X-axis is not on the filters list" msgstr "X-osi ni na seznamu filtrov" -#, fuzzy msgid "" "The X-axis is not on the filters list which will prevent it from being " "used in time range filters in dashboards. Would you like to add it to the" " filters list?" -msgstr "" -"X-osi ni na seznamu filtrov, kar preprečuje njeno uporabo v filtrih " -"časovnega obdobja v nadzorni plošči. Jo želite najprej dodati na seznam " -"filtrov?" +msgstr "Os X ni na seznamu filtrov, kar preprečuje njeno uporabo v filtrih časovnega obsega na nadzornih ploščah. Ali ga želite dodati na seznam filtrov?" msgid "The annotation has been saved" msgstr "Označba je bila shranjena" @@ -15004,9 +13795,8 @@ msgstr "Označba je bila shranjena" msgid "The annotation has been updated" msgstr "Označba je bila posodobljena" -#, fuzzy msgid "The background color of the charts." -msgstr "Dodajte naslov grafikona" +msgstr "Barva ozadja grafikonov." msgid "" "The category of source nodes used to assign colors. If a node is " @@ -15018,18 +13808,14 @@ msgstr "" msgid "" "The chart data is too large to download. Please try reducing the date " "range, limiting rows, or using fewer columns." -msgstr "" +msgstr "Podatki grafikona so preveliki za prenos. Skrajšajte datumski obseg, omejite število vrstic ali uporabite manj stolpcev." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "The chart is still loading. Please wait a moment and try again." -msgstr "" -"Grafikon se še vedno nalaga. Prosimo, počakajte trenutek in poskusite " -"znova." +msgstr "Grafikon se še nalaga. Počakajte trenutek in poskusite znova." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ja] -#, fuzzy msgid "" "The chart this report targets was deleted. Restore the chart, or update " "the report to point at an active chart." @@ -15038,7 +13824,7 @@ msgstr "" "grafikon ali posodobite poročilo, da kaže na aktivni grafikon." msgid "The chat failed to load." -msgstr "" +msgstr "Klepeta ni bilo mogoče naložiti." msgid "" "The classic. Great for showing how much of a company each investor gets, " @@ -15055,9 +13841,8 @@ msgstr "" msgid "The color for points and clusters in RGB" msgstr "Barva točk in gruč v RGB zapisu" -#, fuzzy msgid "The color of the elements border" -msgstr "Barva plastnice" +msgstr "Barva obrobe elementov" msgid "The color of the isoband" msgstr "Barva površinske plastnice" @@ -15065,9 +13850,8 @@ msgstr "Barva površinske plastnice" msgid "The color of the isoline" msgstr "Barva plastnice" -#, fuzzy msgid "The color of the point labels" -msgstr "Barva plastnice" +msgstr "Barva oznak točk" msgid "The color scheme for rendering chart" msgstr "Barvna shema za izris grafikona" @@ -15081,20 +13865,16 @@ msgstr "" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "The color used when a value doesn't match any defined breakpoints." -msgstr "" -"Barva, ki se uporabi, ko vrednost ne ustreza nobeni definirani mejni " -"točki." +msgstr "Barva, uporabljena, ko se vrednost ne ujema z nobeno definirano mejno točko." -#, fuzzy msgid "" "The colors of this chart might be overridden by custom label colors of " "the related dashboard.\n" " Check the JSON metadata in the Advanced settings." msgstr "" -"Barvna shema je bila preglasovana z barvami oznak po meri.\n" -" Preverite JSON-metapodatke v naprednih nastavitvah" +"Barve tega grafikona morda preglasijo barve oznak po meri povezane nadzorne plošče.\n" +" Preverite metapodatke JSON v naprednih nastavitvah." msgid "The column header label" msgstr "Naslov stolpca" @@ -15110,15 +13890,13 @@ msgstr "Stolpec je bil izbrisan ali preimenovan v podatkovni bazi." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fr, ja, lv, mi, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "The configuration for the map layers" msgstr "Konfiguracija za plasti zemljevida" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fr, ja, lv, mi, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "The corner radius of the chart background" -msgstr "Polmer kotov ozadja grafikona" +msgstr "Polmer kota ozadja grafikona" msgid "" "The country code standard that Superset should expect to find in the " @@ -15129,7 +13907,6 @@ msgid "The dashboard has been saved" msgstr "Nadzorna plošča je bila shranjena" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ja] -#, fuzzy msgid "" "The dashboard this report targets was deleted. Restore the dashboard, or " "update the report to point at an active dashboard." @@ -15139,7 +13916,7 @@ msgstr "" "ploščo." msgid "The dashboard you are looking for may have been deleted or moved." -msgstr "" +msgstr "Nadzorna plošča, ki jo iščete, je bila morda izbrisana ali premaknjena." msgid "The data source seems to have been deleted" msgstr "Zdi se, da je bil podatkovni vir izbrisan" @@ -15188,7 +13965,6 @@ msgstr "Stolpec/mera podatkovnega seta, ki vrne vrednosti za y-os grafikona." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "" "The dataset columns will be automatically synced\n" " based on the changes in your SQL query. If your changes " @@ -15197,10 +13973,8 @@ msgid "" "step." msgstr "" "Stolpci nabora podatkov bodo samodejno sinhronizirani\n" -" na osnovi sprememb v vaši SQL poizvedbi. Če vaše spremembe " -"ne\n" -" vplivajo na definicije stolpcev, boste morda želeli " -"preskočiti ta korak." +" na podlagi sprememb v vaši poizvedbi SQL. Če vaše spremembe ne\n" +" vplivajo na definicije stolpcev, boste morda želeli preskočiti ta korak." msgid "" "The dataset configuration exposed here\n" @@ -15237,9 +14011,8 @@ msgstr "" "Opis je lahko prikazan kot glava gradnika v pogledu nadzorne plošče. " "Podpira markdown." -#, fuzzy msgid "The display name of your dashboard" -msgstr "Dodajte ime nadzorne plošče" +msgstr "Prikazno ime vaše nadzorne plošče" msgid "The distance between cells, in pixels" msgstr "Razdalja med celicami v pikslih" @@ -15261,44 +14034,27 @@ msgstr "Objekt engine_params se razširi v klic sqlalchemy.create_engine." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fr, ja, lv, mi, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "The exponent to compute all sizes from. \"EXP\" only" -msgstr "Eksponent za izračun vseh velikosti. Samo za \"EXP\"" +msgstr "Eksponent za izračun vseh velikosti. Samo \"EXP" -#, fuzzy, python-format +#, python-format msgid "The extension %(id)s could not be loaded." -msgstr "Končnica datoteke ni dovoljena." +msgstr "Razširitve %(id)s ni bilo mogoče naložiti." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fr, ja, lv, mi, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "" "The extent of the map on application start. FIT DATA automatically sets " "the extent so that all data points are included in the viewport. CUSTOM " "allows users to define the extent manually." msgstr "" -"Obseg zemljevida ob zagonu aplikacije. FIT DATA samodejno nastavi obseg " -"tako, da so vse podatkovne točke vključene v pogled. CUSTOM omogoča " -"uporabnikom, da obseg določijo ročno." +"Obseg zemljevida ob zagonu aplikacije. FIT DATA samodejno nastavi obseg, tako da so vse podatkovne točke vključene v vidno polje. CUSTOM omogoča " +"uporabnikom, da ročno določijo obseg." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "The feature property to use for point labels" -msgstr "Lastnost elementa, ki se uporablja za oznake točk" - -msgid "The following charts could not be exported:" -msgstr "" - -msgid "" -"The following charts were omitted because an error occurred while " -"exporting them:" -msgstr "" - -msgid "" -"The following charts were omitted because they have no saved query " -"context. To include them, open each chart in Explore and re-save." -msgstr "" +msgstr "Lastnost elementa za oznake točk" #, python-format msgid "" @@ -15308,13 +14064,10 @@ msgstr "V 'columns' manjkajo naslednji vnosi iz 'series_columns': %(columns)s. " # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "" "The following fields contain sensitive information that was masked during" " export. Please provide the values to import this database." -msgstr "" -"Naslednja polja vsebujejo občutljive informacije, ki so bile maskirane " -"med izvozom. Prosimo, vnesite vrednosti za uvoz te baze podatkov." +msgstr "Naslednja polja vsebujejo občutljive podatke, ki so bili prikriti med izvozom. Navedite vrednosti za uvoz te zbirke podatkov." #, python-format msgid "" @@ -15328,26 +14081,22 @@ msgstr "" " in jih ni mogoče naložiti, kar preprečuje izris " "nadzorne plošče: %s" -#, fuzzy msgid "The font size of the point labels" -msgstr "Če želite prikazati kazalec" +msgstr "Velikost pisave oznak točk" msgid "The function to use when aggregating points into groups" msgstr "Funkcija za agregacijo točk v skupine" -#, fuzzy msgid "The group has been created successfully." -msgstr "Poročilo je bilo ustvarjeno" +msgstr "Skupina je bila uspešno ustvarjena." -#, fuzzy msgid "The group has been updated successfully." -msgstr "Označba je bila posodobljena" +msgstr "Skupina je bila uspešno posodobljena." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fr, ja, lv, mi, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "The height of the current zoom level to compute all heights from" -msgstr "Višina trenutne ravni povečave za izračun vseh višin" +msgstr "Višina trenutne stopnje povečave za izračun vseh višin" msgid "" "The histogram chart displays the distribution of a dataset by\n" @@ -15389,19 +14138,14 @@ msgstr "Identifikator aktivnega grafikona" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "" "The image URL of the icon to display for GeoJSON points. Note that the " "image URL must conform to the content security policy (CSP) in order to " "load correctly." -msgstr "" -"URL slike ikone za prikaz pri točkah GeoJSON. Upoštevajte, da mora URL " -"slike biti skladen s pravilnikom o varnosti vsebine (CSP) za pravilno " -"nalaganje." +msgstr "URL slike ikone za prikaz točk GeoJSON. Upoštevajte, da mora biti URL slike skladen s politiko varnosti vsebine (CSP), da se lahko pravilno naloži." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "" "The initial level (depth) of the tree. If set as -1 all nodes are " "expanded." @@ -15409,9 +14153,8 @@ msgstr "" "Začetna raven (globina) drevesa. Če je nastavljeno na -1, so vsa vozlišča" " razširjena." -#, fuzzy msgid "The layer attribution" -msgstr "S časom povezani atributi prikaza" +msgstr "Pripisovanje plasti" msgid "The lower limit of the threshold range of the Isoband" msgstr "Spodnji prag za površinske plastnice" @@ -15429,7 +14172,7 @@ msgstr "Največja vrednost mere. To je opcijska nastavitev" msgid "" "The metadata_cache_timeout must be a mapping from string keys to non-" "negative integer values." -msgstr "" +msgstr "The metadata_cache_timeout must be a mapping from string keys to non-negative integer values." #, python-format msgid "" @@ -15471,15 +14214,13 @@ msgstr "" "Najmanjša vrednost mer. To je opcijska nastavitev. Če ni nastavljeno, bo " "uporabljena najmanjša vrednost med podatki" -#, fuzzy msgid "The name of the geometry column" -msgstr "Ime id-stolpca" +msgstr "Ime stolpca geometrije" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fr, ja, lv, mi, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "The name of the layer as described in GetCapabilities" -msgstr "Ime plasti, kot je opisano v GetCapabilities" +msgstr "Ime sloja, kot je opisano v GetCapabilities" msgid "The name of the rule must be unique" msgstr "Ime pravila mora biti unikatno" @@ -15497,9 +14238,9 @@ msgstr "" "Število ur, negativno ali pozitivno, za zamik časovnega stolpca. Na ta " "način je mogoče UTC čas prestaviti na lokalni čas." -#, fuzzy, python-format +#, python-format msgid "The number of results displayed is limited to %(rows)d." -msgstr "Število prikazanih vrstic je omejeno na %(rows)d s poizvedbo" +msgstr "Število prikazanih rezultatov je omejeno na %(rows)d." #, python-format msgid "The number of rows displayed is limited to %(rows)d by the dropdown." @@ -15544,9 +14285,8 @@ msgstr "Geslo za uporabniško ime \"%(username)s\" je napačno." msgid "The password provided when connecting to a database is not valid." msgstr "Geslo za povezavo s podatkovno bazo je neveljavno." -#, fuzzy msgid "The password reset was successful" -msgstr "Nadzorna plošča je bila uspešno shranjena." +msgstr "Ponastavitev gesla je bila uspešna" msgid "" "The passwords for the databases below are needed in order to import them " @@ -15598,9 +14338,8 @@ msgstr "" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "The passwords for the databases below are needed in order to import them." -msgstr "Za uvoz spodnjih baz podatkov so potrebna gesla." +msgstr "Gesla za spodnje zbirke podatkov so potrebna za njihov uvoz." msgid "The pattern of timestamp format. For strings use " msgstr "Format zapisa časovne značke. Za znakovne nize uporabite " @@ -15653,7 +14392,7 @@ msgid "The query contains one or more malformed template parameters." msgstr "Poizvedba vsebuje enega ali več parametrov predlog z napačno obliko." msgid "The query context datasource does not match the chart datasource" -msgstr "" +msgstr "Vir podatkov v kontekstu poizvedbe se ne ujema z virom podatkov grafikona" msgid "The query couldn't be loaded" msgstr "Poizvedbe ni mogoče naložiti" @@ -15697,17 +14436,10 @@ msgstr "" "`Auto` (skalira točke na osnovi največje gruče)" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ja] -#, fuzzy msgid "" "The radius of point features, in the units specified below. The final " "rendered size is this value multiplied by Point Radius Scale." -msgstr "" -"Polmer točkovnih elementov v spodaj določenih enotah. Končna upodobljena " -"velikost je ta vrednost, pomnožena z merilom polmera točke." - -#, python-format -msgid "The remaining %s will be moved to Recently Archived." -msgstr "" +msgstr "Polmer točkovnih elementov v spodaj navedenih enotah. Končna upodobljena velikost je ta vrednost, pomnožena z lestvico polmera točke." msgid "The report has been created" msgstr "Poročilo je bilo ustvarjeno" @@ -15723,9 +14455,8 @@ msgstr "" "Rezultat te poizvedbe mora biti številska vrednost, kot je 1, 1.0 ali " "\"1\" (kompatibilno s Pythonovo float() funkcijo)." -#, fuzzy msgid "The result size exceeds the allowed limit." -msgstr "Velikost datoteke presega največjo dovoljeno." +msgstr "Velikost rezultata presega dovoljeno mejo." msgid "The results backend no longer has the data from the query." msgstr "Zaledni sistem rezultatov nima več podatkov iz poizvedbe." @@ -15742,17 +14473,14 @@ msgstr "" "Podroben opis orodja prikaže seznam vseh podatkovnih serij za posamezno " "časovno točko" -#, fuzzy msgid "The role has been created successfully." -msgstr "Poročilo je bilo ustvarjeno" +msgstr "Vloga je bila uspešno ustvarjena." -#, fuzzy msgid "The role has been duplicated successfully." -msgstr "Poročilo je bilo ustvarjeno" +msgstr "Vloga je bila uspešno podvojena." -#, fuzzy msgid "The role has been updated successfully." -msgstr "Označba je bila posodobljena" +msgstr "Vloga je bila uspešno posodobljena." msgid "" "The row limit set for the chart was reached. The chart may show partial " @@ -15786,32 +14514,28 @@ msgstr "Shema je bila izbrisana ali preimenovana v podatkovni bazi." msgid "The screenshot could not be downloaded. Please, try again later." msgstr "Zaslonske slike ni mogoče prenesti. Poskusite ponovno kasneje." -#, fuzzy msgid "The screenshot has been downloaded." -msgstr "Zaslonska slika se prenaša." +msgstr "Posnetek zaslona je bil prenesen." msgid "The screenshot is being generated. Please, do not leave the page." msgstr "Ustvarja se zaslonska slika. Ne zapuščajte strani." -#, fuzzy msgid "The service url of the layer" -msgstr "Na grafikonu prikaži vrednosti serij" +msgstr "URL storitve sloja" msgid "The size of each cell in meters" msgstr "Velikost vsake celice v metrih" -#, fuzzy msgid "The size of the point icons" -msgstr "Debelina plastnic v pikslih" +msgstr "Velikost ikon točk" msgid "The size of the square cell, in pixels" msgstr "Velikost kvadratne celice v pikslih" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fr, ja, lv, mi, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "The slope to compute all sizes from. \"LINEAR\" only" -msgstr "Naklon za izračun vseh velikosti. Samo za \"LINEAR\"" +msgstr "Naklon za izračun vseh velikosti. Samo \"LINEARNO\"" msgid "The submitted payload failed validation." msgstr "Neuspešna validacija podanih podatkov." @@ -15901,35 +14625,28 @@ msgstr "" msgid "The time unit used for the grouping of blocks" msgstr "Časovna enota za združevanje blokov" -#, fuzzy msgid "The two passwords that you entered do not match!" -msgstr "Nadzorna plošča ne obstaja" +msgstr "Gesli, ki ste ju vnesli, se ne ujemata!" -#, fuzzy msgid "The type of the layer" -msgstr "Dodajte naslov grafikona" +msgstr "Vrsta plasti" msgid "The type of visualization to display" msgstr "Tip vizualizacije za prikaz" -#, fuzzy msgid "The unit for icon size" -msgstr "Velikost mehurčka" +msgstr "Enota za velikost ikone" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "The unit for label size" -msgstr "Enota za velikost oznake" +msgstr "Enota velikosti oznake" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ja] -#, fuzzy msgid "" "The unit for point radius. Use \"pixels\" for consistent screen-space " "sizing regardless of zoom level." -msgstr "" -"Enota za polmer točke. Uporabite \"piksele\" za dosledno velikost v " -"prostoru zaslona ne glede na raven povečave." +msgstr "Enota za polmer točke. Uporabite \"piksle\" za dosledno velikost zaslona ne glede na stopnjo povečave." msgid "The unit of measure for the specified point radius" msgstr "Enota merila za definiran radij točk" @@ -15937,20 +14654,17 @@ msgstr "Enota merila za definiran radij točk" msgid "The upper limit of the threshold range of the Isoband" msgstr "Zgornji prag za površinske plastnice" -#, fuzzy msgid "The user has been created successfully." -msgstr "Nadzorna plošča je bila uspešno shranjena." +msgstr "Uporabnik je bil uspešno ustvarjen." -#, fuzzy msgid "The user has been updated successfully." -msgstr "Nadzorna plošča je bila uspešno shranjena." +msgstr "Uporabnik je bil uspešno posodobljen." msgid "The user seems to have been deleted" msgstr "Zdi se, da je bil uporabnik izbrisan" -#, fuzzy msgid "The user was updated successfully" -msgstr "Nadzorna plošča je bila uspešno shranjena." +msgstr "Uporabnik je bil uspešno posodobljen" msgid "The user/password combination is not valid (Incorrect password for user)." msgstr "Kombinacija uporabnik/geslo ni veljavna (napačno geslo)." @@ -15964,17 +14678,14 @@ msgstr "Uporabniško ime za povezavo s podatkovno bazo je neveljavno." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "The values overlap other breakpoint values" -msgstr "Vrednosti se prekrivajo z vrednostmi drugih mejnih točk" +msgstr "Vrednosti se prekrivajo z drugimi vrednostmi prelomnih točk" -#, fuzzy msgid "The version of the service" -msgstr "Izberite položaj legende" +msgstr "Različica storitve" -#, fuzzy msgid "The visible title of the layer" -msgstr "Prikaži vrednosti na vrhu stolpcev" +msgstr "Vidni naslov sloja" msgid "The way the ticks are laid out on the X-axis" msgstr "Način razporeditve oznak na X-osi" @@ -15984,46 +14695,38 @@ msgstr "Debelina plastnic v pikslih" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fr, ja, lv, mi, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "The width of the current zoom level to compute all widths from" -msgstr "Širina trenutne ravni povečave za izračun vseh širin" +msgstr "Širina trenutne stopnje povečave za izračun vseh širin" -#, fuzzy msgid "The width of the elements border" -msgstr "Debelina črt" +msgstr "Širina obrobe elementov" msgid "The width of the lines" msgstr "Debelina črt" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "" "The width of the lines as either a fixed value or variable width based on" " a metric." -msgstr "Širina črt kot fiksna vrednost ali spremenljiva širina na osnovi metrike." +msgstr "Širina črt kot stalna vrednost ali spremenljiva širina na podlagi mere." # SUPERSET UI -#, fuzzy msgid "Theme" -msgstr "Čas" +msgstr "Tema" -#, fuzzy msgid "Theme imported" -msgstr "Podatki uvoženi" +msgstr "Tema uvožena" -#, fuzzy msgid "Theme not found." -msgstr "CSS predloga ni najdena." +msgstr "Tema ni bila najdena." # SUPERSET UI -#, fuzzy msgid "Themes" -msgstr "Čas" +msgstr "Teme" -#, fuzzy msgid "Themes could not be deleted." -msgstr "Oznake ni mogoče izbrisati." +msgstr "Tem ni bilo mogoče izbrisati." msgid "There are associated alerts or reports" msgstr "Prisotna so povezana opozorila in poročila" @@ -16049,9 +14752,8 @@ msgid "" " or a typo." msgstr "V SQL-poizvedbi je sintaktična napaka. Mogoče ste se zatipkali." -#, fuzzy msgid "There is currently no information to display." -msgstr "Tip vizualizacije za prikaz" +msgstr "Trenutno ni informacij za prikaz." msgid "" "There is no chart definition associated with this component, could it " @@ -16069,29 +14771,23 @@ msgstr "" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy, python-format +#, python-format msgid "" "There was a problem refreshing your dashboard. We'll try again in %s, as " "scheduled." -msgstr "" -"Pri osveževanju vaše nadzorne plošče je prišlo do težave. Poskusili bomo " -"znova čez %s, kot je načrtovano." +msgstr "Pri osveževanju nadzorne plošče je prišlo do težave. Znova bomo poskusili v %s, kot je načrtovano." -#, fuzzy msgid "There was an error creating the group. Please, try again." -msgstr "Napaka pri nalaganju shem" +msgstr "Pri ustvarjanju skupine je prišlo do napake. Prosim poskusite znova." -#, fuzzy msgid "There was an error creating the role. Please, try again." -msgstr "Napaka pri nalaganju shem" +msgstr "Pri ustvarjanju vloge je prišlo do napake. Prosim poskusite znova." -#, fuzzy msgid "There was an error creating the user. Please, try again." -msgstr "Napaka pri nalaganju shem" +msgstr "Pri ustvarjanju uporabnika je prišlo do napake. Prosim poskusite znova." -#, fuzzy msgid "There was an error duplicating the role. Please, try again." -msgstr "Pri dupliciranju podatkovnega seta je prišlo do težave." +msgstr "Pri podvajanju vloge je prišlo do napake. Prosim poskusite znova." msgid "There was an error fetching dataset" msgstr "Pri pridobivanju podatkovnega seta je prišlo do napake" @@ -16107,15 +14803,13 @@ msgid "There was an error fetching the filtered charts and dashboards:" msgstr "Napaka pri pridobivanju filtriranih grafikonov in nadzornih plošč:" msgid "There was an error generating the permalink." -msgstr "" +msgstr "Pri ustvarjanju trajne povezave je prišlo do napake." -#, fuzzy msgid "There was an error loading groups." -msgstr "Napaka pri nalaganju tabel" +msgstr "Pri nalaganju skupin je prišlo do napake." -#, fuzzy msgid "There was an error loading permissions." -msgstr "Napaka pri nalaganju tabel" +msgstr "Pri nalaganju dovoljenj je prišlo do napake." msgid "There was an error loading the catalogs" msgstr "Napaka pri nalaganju katalogov" @@ -16129,9 +14823,8 @@ msgstr "Napaka pri nalaganju shem" msgid "There was an error loading the tables" msgstr "Napaka pri nalaganju tabel" -#, fuzzy msgid "There was an error loading users." -msgstr "Napaka pri nalaganju tabel" +msgstr "Pri nalaganju uporabnikov je prišlo do napake." msgid "There was an error retrieving dashboard tabs." msgstr "Prišlo je do napake pri pridobivanju zavihkov nadzornih plošč." @@ -16140,76 +14833,50 @@ msgstr "Prišlo je do napake pri pridobivanju zavihkov nadzornih plošč." msgid "There was an error saving the favorite status: %s" msgstr "Napaka pri shranjevanju statusa \"Priljubljeno\": %s" -#, fuzzy msgid "There was an error updating the group. Please, try again." -msgstr "Napaka pri nalaganju shem" +msgstr "Pri posodabljanju skupine je prišlo do napake. Prosim poskusite znova." -#, fuzzy msgid "There was an error updating the role. Please, try again." -msgstr "Napaka pri nalaganju shem" +msgstr "Pri posodabljanju vloge je prišlo do napake. Prosim poskusite znova." -#, fuzzy msgid "There was an error updating the user. Please, try again." -msgstr "Napaka pri nalaganju shem" +msgstr "Pri posodobitvi uporabnika je prišlo do napake. Prosim poskusite znova." -#, fuzzy msgid "There was an error while fetching groups" -msgstr "Pri pridobivanju podatkovnega seta je prišlo do napake" +msgstr "Pri pridobivanju skupin je prišlo do napake" -#, fuzzy msgid "There was an error while fetching permissions" -msgstr "Pri pridobivanju podatkovnega seta je prišlo do napake" +msgstr "Pri pridobivanju dovoljenj je prišlo do napake" -#, fuzzy msgid "There was an error while fetching users" -msgstr "Pri pridobivanju podatkovnega seta je prišlo do napake" +msgstr "Pri pridobivanju uporabnikov je prišlo do napake" msgid "There was an error with your request" msgstr "Pri zahtevi je prišlo do napake" #, python-format -msgid "There was an issue archiving %s: %s" -msgstr "" - -#, python-format -msgid "There was an issue archiving the selected %s" -msgstr "" - -#, python-format -msgid "There was an issue archiving the selected charts: %s" -msgstr "" - -#, python-format -msgid "There was an issue archiving the selected dashboards: %s" -msgstr "" - -#, python-format -msgid "There was an issue archiving: %s" -msgstr "" - -#, fuzzy, python-format msgid "There was an issue cancelling the task: %s" -msgstr "Težava pri brisanju %s: %s" +msgstr "Pri preklicu opravila je prišlo do težave: %s" -#, fuzzy, python-format +#, python-format msgid "There was an issue deleting %s" -msgstr "Težava pri brisanju: %s" +msgstr "Pri brisanju %s je prišlo do težave" #, python-format msgid "There was an issue deleting %s: %s" msgstr "Težava pri brisanju %s: %s" -#, fuzzy, python-format +#, python-format msgid "There was an issue deleting registration for user: %s" -msgstr "Težava pri brisanju pravil: %s" +msgstr "Pri brisanju registracije za uporabnika: %s je prišlo do težave" #, python-format msgid "There was an issue deleting rules: %s" msgstr "Težava pri brisanju pravil: %s" -#, fuzzy, python-format +#, python-format msgid "There was an issue deleting the selected %s" -msgstr "Težava pri brisanju izbranih %s: %s" +msgstr "Pri brisanju izbranega %s je prišlo do težave" #, python-format msgid "There was an issue deleting the selected %s: %s" @@ -16223,9 +14890,8 @@ msgstr "Pri brisanju izbranih oznak je prišlo do težave: %s" msgid "There was an issue deleting the selected charts: %s" msgstr "Pri brisanju izbranih grafikonov je prišlo do težave: %s" -#, python-format -msgid "There was an issue deleting the selected dashboards: %s" -msgstr "" +msgid "There was an issue deleting the selected dashboards: " +msgstr "Pri brisanju izbranih nadzornih plošč je prišlo do težave: " #, python-format msgid "There was an issue deleting the selected layers: %s" @@ -16233,57 +14899,53 @@ msgstr "Pri brisanju izbranih slojev je prišlo do težave: %s" #, python-format msgid "There was an issue deleting the selected queries: %s" -msgstr "" +msgstr "Pri brisanju izbranih poizvedb je prišlo do težave: %s" #, python-format msgid "There was an issue deleting the selected templates: %s" msgstr "Pri brisanju izbranih predlog je prišlo do težave: %s" -#, fuzzy, python-format +#, python-format msgid "There was an issue deleting the selected themes: %s" -msgstr "Pri brisanju izbranih predlog je prišlo do težave: %s" +msgstr "Pri brisanju izbranih tem je prišlo do težave: %s" #, python-format msgid "There was an issue deleting: %s" msgstr "Težava pri brisanju: %s" -#, fuzzy, python-format +#, python-format msgid "There was an issue duplicating the %s." -msgstr "Pri dupliciranju podatkovnega seta je prišlo do težave." +msgstr "Pri podvajanju %s je prišlo do težave." -#, fuzzy, python-format +#, python-format msgid "There was an issue duplicating the selected %s: %s" -msgstr "Težava pri brisanju izbranih %s: %s" +msgstr "Pri podvajanju izbranega %s : %s je prišlo do težave" -#, fuzzy, python-format +#, python-format msgid "There was an issue exporting the %s" -msgstr "Pri dupliciranju podatkovnega seta je prišlo do težave." +msgstr "Pri izvozu %s je prišlo do težave" -#, fuzzy, python-format +#, python-format msgid "There was an issue exporting the selected %s" -msgstr "Pri brisanju izbranih predlog je prišlo do težave: %s" +msgstr "Pri izvozu izbranega %s je prišlo do težave" -#, fuzzy msgid "There was an issue exporting the selected charts" -msgstr "Pri brisanju izbranih grafikonov je prišlo do težave: %s" +msgstr "Pri izvozu izbranih grafikonov je prišlo do težave" -#, fuzzy msgid "There was an issue exporting the selected dashboards" -msgstr "Pri brisanju izbranih nadzornih plošč je prišlo do težave: " +msgstr "Pri izvozu izbranih nadzornih plošč je prišlo do težave" msgid "There was an issue exporting the selected queries" -msgstr "" +msgstr "Pri izvozu izbranih poizvedb je prišlo do težave" -#, fuzzy msgid "There was an issue exporting the selected themes" -msgstr "Pri brisanju izbranih predlog je prišlo do težave: %s" +msgstr "Pri izvozu izbranih tem je prišlo do težave" msgid "There was an issue favoriting this dashboard." msgstr "Pri uvrščanju nadzorne plošče med priljubljene je prišlo do težave." -#, fuzzy msgid "There was an issue fetching reports." -msgstr "Prišlo je do napake pri pridobivanju grafikona: %s" +msgstr "Pri pridobivanju poročil je prišlo do težave." msgid "There was an issue fetching the favorite status of this dashboard." msgstr "" @@ -16314,33 +14976,9 @@ msgstr "Do težave je prišlo pri predogledu izbrane poizvedbe %s" msgid "There was an issue previewing the selected query. %s" msgstr "Pri predogledu izbrane poizvedbe je prišlo do težave. %s" -#, python-format -msgid "" -"These %(type)s will be moved to Recently Archived. You can recover them " -"there within %(days)s days." -msgstr "" - -#, python-format -msgid "" -"These %(type)s will be moved to Recently Archived. You can recover them " -"there." -msgstr "" - msgid "These are the datasets this filter will be applied to." msgstr "To so podatkovni seti, na katere se nanaša ta filter." -#, python-format -msgid "" -"This %(type)s will be moved to Recently Archived. You can recover it " -"there within %(days)s days." -msgstr "" - -#, python-format -msgid "" -"This %(type)s will be moved to Recently Archived. You can recover it " -"there." -msgstr "" - msgid "" "This JSON object is generated dynamically when clicking the save or " "overwrite button in the dashboard view. It is exposed here for reference " @@ -16354,16 +14992,14 @@ msgstr "" msgid "This action will permanently delete %s." msgstr "S tem dejanjem boste trajno izbrisali %s." -#, fuzzy msgid "This action will permanently delete the group." -msgstr "S tem dejanjem boste trajno izbrisali sloj." +msgstr "To dejanje bo trajno izbrisalo skupino." msgid "This action will permanently delete the layer." msgstr "S tem dejanjem boste trajno izbrisali sloj." -#, fuzzy msgid "This action will permanently delete the role." -msgstr "S tem dejanjem boste trajno izbrisali sloj." +msgstr "To dejanje bo trajno izbrisalo vlogo." msgid "This action will permanently delete the saved query." msgstr "S tem dejanjem boste trajno izbrisali shranjeno poizvedbo." @@ -16371,17 +15007,14 @@ msgstr "S tem dejanjem boste trajno izbrisali shranjeno poizvedbo." msgid "This action will permanently delete the template." msgstr "S tem dejanjem boste trajno izbrisali predlogo." -#, fuzzy msgid "This action will permanently delete the theme." -msgstr "S tem dejanjem boste trajno izbrisali predlogo." +msgstr "To dejanje bo trajno izbrisalo temo." -#, fuzzy msgid "This action will permanently delete the user registration." -msgstr "S tem dejanjem boste trajno izbrisali sloj." +msgstr "To dejanje bo trajno izbrisalo registracijo uporabnika." -#, fuzzy msgid "This action will permanently delete the user." -msgstr "S tem dejanjem boste trajno izbrisali sloj." +msgstr "To dejanje bo trajno izbrisalo uporabnika." msgid "" "This can be either an IP address (e.g. 127.0.0.1) or a domain name (e.g. " @@ -16400,9 +15033,8 @@ msgstr "" msgid "This chart has been moved to a different filter scope." msgstr "Ta grafikon je bil prestavljen v drug doseg filtrov." -#, fuzzy msgid "This chart is managed externally and can't be overwritten in Superset." -msgstr "Ta grafikon se ne ureja znotraj Superseta" +msgstr "Ta grafikon se upravlja zunaj in ga ni mogoče prepisati v Supersetu." msgid "This chart is managed externally, and can't be edited in Superset" msgstr "Ta grafikon se ne ureja znotraj Superseta" @@ -16417,9 +15049,9 @@ msgid "" "source. " msgstr "Tip grafikona ne podpira uporabe neshranjene poizvedbe za podatkovni vir. " -#, fuzzy, python-format +#, python-format msgid "This column might be incompatible with current %s" -msgstr "Ta grafikon je lahko nekompatibilen s trenutnim podatkovnim setom" +msgstr "Ta stolpec morda ni združljiv s trenutnim %s" msgid "This column might be incompatible with current dataset" msgstr "Ta grafikon je lahko nekompatibilen s trenutnim podatkovnim setom" @@ -16460,7 +15092,7 @@ msgstr "" " posredovano grafikonu, ki vsebuje podatke oznak slojev." msgid "This dashboard does not exist" -msgstr "" +msgstr "Ta nadzorna plošča ne obstaja" msgid "This dashboard is managed externally, and can't be edited in Superset" msgstr "" @@ -16502,14 +15134,10 @@ msgstr "" msgid "This dashboard was saved successfully." msgstr "Nadzorna plošča je bila uspešno shranjena." -#, fuzzy msgid "" "This database does not allow for DDL/DML, but the query mutates data. " "Please contact your administrator for more assistance." -msgstr "" -"Podatkovna baza ne dovoljuje DDL/DML in poizvedbe ni mogoče prebrati, da " -"bi potrdili, da je poizvedba samo za branje. Kontaktirajte " -"administratorja za nadaljnjo podporo." +msgstr "Ta zbirka podatkov ne omogoča DDL/DML, vendar poizvedba spreminja podatke. Za dodatno pomoč se obrnite na skrbnika." msgid "This database is managed externally, and can't be edited in Superset" msgstr "" @@ -16523,17 +15151,14 @@ msgstr "Tabela podatkovne baze ne vsebuje podatkov. Izberite drugo tabelo." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "" "This database uses OAuth2 for authentication. Please click the link above" " to grant Apache Superset permission to access the data. Your personal " "access token will be stored encrypted and used only for queries run by " "you." msgstr "" -"Ta baza podatkov za avtentikacijo uporablja OAuth2. Prosimo, kliknite " -"zgornjo povezavo, da Apache Supersetu podelite dovoljenje za dostop do " -"podatkov. Vaš osebni žeton za dostop bo shranjen šifrirano in bo " -"uporabljen samo za poizvedbe, ki jih zaženete sami." +"Ta zbirka podatkov uporablja OAuth2 za preverjanje pristnosti. Kliknite zgornjo povezavo, da Apache Superset odobrite dovoljenje za dostop do podatkov. Vaš " +"osebni dostopni žeton bo shranjen šifriran in uporabljen samo za poizvedbe, ki jih izvajate vi." msgid "This dataset is managed externally, and can't be edited in Superset" msgstr "" @@ -16545,19 +15170,13 @@ msgstr "Določa element, ki bo izrisan na grafikonu" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, fr, ja, # lv, ro, ru, sr, sr_Latn, tr, uk] -#, fuzzy msgid "" "This email is already associated with an account. Please choose another " "one." -msgstr "Ta e-poštni naslov je že povezan z računom. Prosimo, izberite drugega." - -#, python-format -msgid "This export was requested on %(when)s UTC." -msgstr "" +msgstr "Ta e-poštni naslov je že povezan z računom. Prosim izberite drugega." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "This feature is experimental and may change or have limitations" msgstr "Ta funkcija je eksperimentalna in se lahko spremeni ali ima omejitve" @@ -16575,63 +15194,54 @@ msgstr "" "To polje se uporablja kot unikaten ID za vključitev mere v grafikon. " "Uporablja se tudi kot alias v SQL-poizvedbi." -#, fuzzy msgid "This filter already exist on the report" -msgstr "Seznam vrednosti filtra ne sme biti prazen" +msgstr "Ta filter že obstaja v poročilu" -#, fuzzy, python-format +#, python-format msgid "This filter might be incompatible with current %s" -msgstr "Ta filter je lahko nekompatibilen s trenutnim podatkovnim setom" +msgstr "Ta filter morda ni združljiv s trenutnim %s" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "This folder is currently empty" msgstr "Ta mapa je trenutno prazna" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "This folder only supports columns" msgstr "Ta mapa podpira samo stolpce" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "This folder only supports metrics" -msgstr "Ta mapa podpira samo metrike" +msgstr "Ta mapa podpira samo mere" + +msgid "This functionality is disabled in your environment for security reasons." +msgstr "Ta funkcionalnost je v vašem okolju onemogočena zaradi varnosti." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "" "This is a default columns folder. Its name cannot be changed or removed. " "It can stay empty but will only accept column items." -msgstr "" -"To je privzeta mapa za stolpce. Njenega imena ni mogoče spremeniti ali " -"odstraniti. Lahko ostane prazna, a bo sprejemala samo elemente stolpcev." +msgstr "To je privzeta mapa stolpcev. Njegovega imena ni mogoče spremeniti ali odstraniti. Lahko ostane prazen, vendar bo sprejel samo elemente stolpcev." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "" "This is a default metrics folder. Its name cannot be changed or removed. " "It can stay empty but will only accept metric items." -msgstr "" -"To je privzeta mapa za metrike. Njenega imena ni mogoče spremeniti ali " -"odstraniti. Lahko ostane prazna, a bo sprejemala samo elemente metrik." +msgstr "To je privzeta mapa z meritvami. Njegovega imena ni mogoče spremeniti ali odstraniti. Lahko ostane prazen, vendar bo sprejel le metrične postavke." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "This is custom error message for a" -msgstr "To je sporočilo o napaki po meri za a" +msgstr "To je prilagojeno sporočilo o napaki za a" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "This is custom error message for b" -msgstr "To je sporočilo o napaki po meri za b" +msgstr "To je prilagojeno sporočilo o napaki za b" msgid "" "This is the condition that will be added to the WHERE clause. For " @@ -16645,25 +15255,21 @@ msgstr "" " 9'. Če ne želimo prikazati vrstic, razen če uporabnik pripada RLS vlogi," " lahko filter ustvarimo z izrazom `1 = 0` (vedno FALSE)." -#, fuzzy msgid "This is the default dark theme" -msgstr "Privzet datumčas" +msgstr "To je privzeta temna tema" -#, fuzzy msgid "This is the default folder" -msgstr "Osveži privzete vrednosti" +msgstr "To je privzeta mapa" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "This is the default light theme" -msgstr "To je privzeta svetla tema" +msgstr "To je privzeta svetlobna tema" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "This is the only time you will see this key. Store it securely." -msgstr "To je edinkrat, ko boste videli ta ključ. Shranite ga varno." +msgstr "To je edinkrat, ko boste videli ta ključ. Shranite ga na varno." msgid "" "This json object describes the positioning of the widgets in the " @@ -16675,23 +15281,15 @@ msgstr "" "uporabo povleci&spusti v pogledu nadzorne plošče" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [no refs] -#, fuzzy msgid "This link cannot be followed because its address is unsafe." -msgstr "Tej povezavi ni mogoče slediti, ker je njen naslov nevaren." - -#, python-format -msgid "This link expires in %(duration)s (%(when)s UTC)." -msgstr "" +msgstr "Te povezave ni mogoče slediti, ker njen naslov ni varen." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "" "This link will take you to an external website. We cannot guarantee the " "safety of external destinations." -msgstr "" -"Ta povezava vas bo odpeljala na zunanje spletno mesto. Ne moremo " -"zagotoviti varnosti zunanjih destinacij." +msgstr "Ta povezava vas bo pripeljala na zunanje spletno mesto. Ne moremo zagotoviti varnosti zunanjih destinacij." msgid "This markdown component has an error." msgstr "Markdown komponenta ima napako." @@ -16701,26 +15299,22 @@ msgstr "Markdown komponenta ima napako. Povrnite nedavne spremembe." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "" "This may be due to the extension not being activated or the content not " "being available." -msgstr "" -"To je morda posledica tega, da razširitev ni aktivirana ali vsebina ni na" -" voljo." +msgstr "To je lahko posledica tega, da razširitev ni aktivirana ali da vsebina ni na voljo." msgid "This may be triggered by:" msgstr "To je lahko sproženo z/s:" -#, fuzzy, python-format +#, python-format msgid "This metric might be incompatible with current %s" -msgstr "Ta mera je lahko nekompatibilna s trenutnim podatkovnim setom" +msgstr "Ta mera morda ni združljiva s trenutnim %s" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, fr, ja, # lv, ro, ru, sr, sr_Latn, tr, uk] -#, fuzzy msgid "This name is already taken. Please choose another one." -msgstr "To ime je že zasedeno. Prosimo, izberite drugo." +msgstr "To ime je že zasedeno. Prosim izberite drugega." msgid "This option has been disabled by the administrator." msgstr "To opcijo je onemogočil administrator." @@ -16731,9 +15325,8 @@ msgid "" msgstr "Ta stran naj bi bila vdelana kot iframe, vendar izgleda, da temu ni tako." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ja] -#, fuzzy msgid "This password is too common; please choose a less guessable one." -msgstr "To geslo je preveč pogosto; izberite manj ugibljivo geslo." +msgstr "To geslo je prepogosto; izberite manj uganljivega." msgid "" "This section allows you to configure how to use the slice\n" @@ -16773,21 +15366,18 @@ msgstr "" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, pt_BR, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "This theme is set locally" msgstr "Ta tema je nastavljena lokalno" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, pt_BR, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "This theme is set locally for your session" msgstr "Ta tema je nastavljena lokalno za vašo sejo" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fr, ja, lv, mi, pt_BR, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "This username is already taken. Please choose another one." -msgstr "To uporabniško ime je že zasedeno. Prosimo, izberite drugo." +msgstr "To uporabniško ime je že zasedeno. Prosim izberite drugega." msgid "This value should be greater than the left target value" msgstr "Ta vrednost mora biti večja od leve ciljne vrednosti" @@ -16810,9 +15400,9 @@ msgstr[3] "To je bilo sproženo z:" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy, python-format +#, python-format msgid "This will abort (stop) the task for all %s subscriber(s)." -msgstr "To bo prekinilo (ustavilo) nalogo za vseh %s naročnikov." +msgstr "To bo prekinilo (ustavilo) nalogo za vse naročnike %s." msgid "" "This will be applied to the whole table. Arrows (↑ and ↓) will be added " @@ -16825,22 +15415,18 @@ msgstr "" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "This will cancel the task." -msgstr "To bo preklicalo nalogo." +msgstr "To bo preklicalo opravilo." msgid "This will remove your current embed configuration." msgstr "To bo odstranilo trenutno konfiguracijo za vgrajevanje." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, pt_BR, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "" "This will reorganize all metrics and columns into default folders. Any " "custom folders will be removed." -msgstr "" -"To bo preorganiziralo vse metrike in stolpce v privzete mape. Vse mape po" -" meri bodo odstranjene." +msgstr "To bo reorganiziralo vse meritve in stolpce v privzete mape. Vse mape po meri bodo odstranjene." msgid "Threshold" msgstr "Prag" @@ -16848,9 +15434,8 @@ msgstr "Prag" msgid "Threshold alpha level for determining significance" msgstr "Mejna vrednost alfa za določanje značilnosti" -#, fuzzy msgid "Threshold for Other" -msgstr "Prag" +msgstr "Prag za kategorijo »Drugo«" msgid "Threshold: " msgstr "Prag: " @@ -16878,7 +15463,7 @@ msgid "Time Grain" msgstr "Granulacija časa" msgid "Time Grain must be specified when using Time Comparison." -msgstr "" +msgstr "Pri uporabi časovne primerjave mora biti določena časovna zrnatost." msgid "Time Granularity" msgstr "Granulacija časa" @@ -16926,9 +15511,8 @@ msgstr "Časovni stolpec" msgid "Time column \"%(col)s\" does not exist in dataset" msgstr "Časovni stolpec \"%(col)s\" ne obstaja v podatkovnem setu" -#, fuzzy msgid "Time column chart customization plugin" -msgstr "Vtičnik za časovni filter" +msgstr "Vtičnik za prilagajanje grafikona časovnih stolpcev" msgid "Time column filter plugin" msgstr "Vtičnik za časovni filter" @@ -16966,9 +15550,8 @@ msgstr "Oblika zapisa časa" msgid "Time grain" msgstr "Granulacija časa" -#, fuzzy msgid "Time grain chart customization plugin" -msgstr "Vtičnik za filter časovne granulacije" +msgstr "Vtičnik za prilagajanje grafikona časovni zrnatosti" msgid "Time grain filter plugin" msgstr "Vtičnik za filter časovne granulacije" @@ -16976,9 +15559,8 @@ msgstr "Vtičnik za filter časovne granulacije" msgid "Time grain missing" msgstr "Časovna granulacija manjka" -#, fuzzy msgid "Time grain options" -msgstr "Možnosti časovne vrste" +msgstr "Možnosti časovne zrnatosti" msgid "Time granularity" msgstr "Granulacija časa" @@ -17024,24 +15606,20 @@ msgstr "Časovna serija - Vrtenje periode" msgid "Time-series Table" msgstr "Tabela s časovno vrsto" -#, fuzzy msgid "Timed Out" -msgstr "Oblika zapisa časa" +msgstr "Časovna omejitev je potekla" -#, fuzzy msgid "Timeline" -msgstr "Časovni pas" +msgstr "Časovnica" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy, python-format +#, python-format msgid "" "Timeout configured (%s seconds) but no abort handler defined. Task will " "continue running past the timeout." msgstr "" -"Konfigurirana je časovna omejitev (%s sekund), a ni definiran " -"upravljalnik za prekinitev. Naloga bo nadaljevala z izvajanjem po preteku" -" časovne omejitve." +"Časovna omejitev je konfigurirana (%s sekund), vendar ni definiran noben upravljavec za prekinitev. Naloga se bo nadaljevala po preteku časovne omejitve." msgid "Timeout error" msgstr "Napaka pretečenega časa" @@ -17072,28 +15650,22 @@ msgstr "Naslov ali `Slug`" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "" "To begin using your Google Sheets, you need to create a database first. " "Databases are used as a way to identify your data so that it can be " "queried and visualized. This database will hold all of your individual " "Google Sheets you choose to connect here." msgstr "" -"Za začetek uporabe Google Preglednic morate najprej ustvariti bazo " -"podatkov. Baze podatkov se uporabljajo kot način identifikacije vaših " -"podatkov, da jih je mogoče poizvedovati in vizualizirati. Ta baza " -"podatkov bo vsebovala vse vaše posamezne Google Preglednice, ki jih " -"izberete za povezavo tukaj." +"Če želite začeti uporabljati Google Preglednice, morate najprej ustvariti bazo podatkov. Podatkovne baze se uporabljajo kot način identifikacije vaših " +"podatkov, tako da jih je mogoče poizvedovati in vizualizirati. Ta zbirka podatkov bo vsebovala vse vaše posamezne Google Preglednice, ki jih izberete tukaj " +"povezati." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fr, ja, lv, mi, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "" "To enable multiple column sorting, hold down the ⇧ Shift key while " "clicking the column header." -msgstr "" -"Za omogočanje razvrščanja po več stolpcih pridržite tipko ⇧ Shift med " -"klikom na glavo stolpca." +msgstr "Če želite omogočiti razvrščanje več stolpcev, pridržite tipko ⇧ Shift, medtem ko kliknete glavo stolpca." msgid "To filter on a metric, use Custom SQL tab." msgstr "Za filtriranje po meri uporabite zavihek za SQL-izraz." @@ -17103,47 +15675,38 @@ msgstr "Za pridobitev berljivega URL-ja za nadzorno ploščo" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Token Request URI" -msgstr "URI zahteve za žeton" +msgstr "URI zahteve žetona" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ja] -#, fuzzy, python-format +#, python-format msgid "" "Too many sub-slices requested. The maximum allowed is %(max)s, but " "%(count)s were requested." -msgstr "" -"Zahtevanih je preveč pod-rezin. Največje dovoljeno število je %(max)s, " -"zahtevanih pa je bilo %(count)s." +msgstr "Zahtevanih je preveč podrezin. Največja dovoljena vrednost je %(max)s, vendar so bili zahtevani %(count)s." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ja] -#, fuzzy, python-format +#, python-format msgid "" "Too many time comparisons requested. The maximum allowed is %(max)s, but " "%(count)s were requested." -msgstr "" -"Zahtevanih je preveč časovnih primerjav. Največje dovoljeno število je " -"%(max)s, zahtevanih pa je bilo %(count)s." +msgstr "Zahtevanih je preveč časovnih primerjav. Največja dovoljena vrednost je %(max)s, vendar so bili zahtevani %(count)s." -#, fuzzy msgid "Tool Panel" -msgstr "Vsi paneli" +msgstr "Orodna plošča" msgid "Tooltip" msgstr "Opis orodja" -#, fuzzy msgid "Tooltip (columns)" -msgstr "Vsebina opisa orodja" +msgstr "Opis orodja (stolpci)" -#, fuzzy msgid "Tooltip (metrics)" -msgstr "Mera za razvrščanje opisa orodja" +msgstr "Opis orodja (mere)" msgid "Tooltip Contents" msgstr "Vsebina opisa orodja" -#, fuzzy msgid "Tooltip contents" msgstr "Vsebina opisa orodja" @@ -17159,9 +15722,8 @@ msgstr "Zgoraj" msgid "Top left" msgstr "Zgoraj levo" -#, fuzzy msgid "Top n" -msgstr "zgoraj" +msgstr "Najvišjih N" msgid "Top right" msgstr "Zgoraj desno" @@ -17176,19 +15738,22 @@ msgstr "Skupaj" msgid "Total (%(aggfunc)s)" msgstr "Skupaj (%(aggfunc)s)" +#, python-format +msgid "Total (%(aggregatorName)s)" +msgstr "Skupaj (%(aggregatorName)s)" + msgid "" -"Total angle covered by the chart, in degrees. 360° draws a full circle " -"and 180° draws a half donut. Partial arcs are automatically re-centered " -"and scaled to make use of the available space." +"Total angle covered by the chart, in degrees. 360° draws a full circle and 180° draws a half donut. When the sweep is 180° or less and the start angle is a " +"multiple of 90°, the chart is automatically re-centered to make use of the empty space." msgstr "" +"Skupni kot grafikona v stopinjah. 360° izriše poln krog, 180° pa polovični kolobar. Ko je kot loka 180° ali manj in je začetni kot večkratnik 90°, se " +"grafikon samodejno ponovno centrira, da izkoristi prazen prostor." -#, fuzzy msgid "Total color" -msgstr "Barva točke" +msgstr "Barva vsote" -#, fuzzy msgid "Total label" -msgstr "Skupna vsota" +msgstr "Skupna oznaka" msgid "Total value" msgstr "Skupna vsota" @@ -17207,7 +15772,7 @@ msgid "Transparent" msgstr "Prozorno" msgid "Transparent background" -msgstr "" +msgstr "Prosojno ozadje" msgid "Transpose pivot" msgstr "Transponirano vrtenje" @@ -17237,14 +15802,10 @@ msgid "Trigger Alert If..." msgstr "Sproži opozorilo v primeru ..." msgid "Trigger now" -msgstr "" +msgstr "Sproži zdaj" -#, fuzzy msgid "True" -msgstr "TOR" - -msgid "Truncate Axis" -msgstr "" +msgstr "Da" msgid "Truncate Cells" msgstr "Prireži celice" @@ -17273,19 +15834,13 @@ msgstr "" msgid "Truncate long cells to the \"min width\" set above" msgstr "Prireži dolge celice na \"min. širino\" nastavljeno zgoraj" -msgid "" -"Truncate the metric axis. Can be overridden by specifying a min or max " -"bound." -msgstr "" - msgid "Truncates the specified date to the accuracy specified by the date unit." msgstr "Zaokroži datum-čas, glede na definirano časovno enoto." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "Trust this URL and don't ask again" -msgstr "Zaupaj temu URL-ju in ne sprašuj ponovno" +msgstr "Zaupajte temu URL-ju in ne sprašujte več" msgid "Try applying different filters or ensuring your datasource has data" msgstr "" @@ -17314,72 +15869,63 @@ msgstr "Vnesite vrednost" msgid "Type a value here" msgstr "Vnesite vrednost sem" -#, fuzzy msgid "Type a value..." -msgstr "Vnesite vrednost" +msgstr "Vnesite vrednost ..." msgid "Type is required" msgstr "Tip je obvezen" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "Type of Google Sheets allowed" msgstr "Dovoljena vrsta Google Preglednic" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Type of chart to display in sparkline" -msgstr "Vrsta grafikona za prikaz v sparkline" +msgstr "Vrsta grafikona za prikaz v mini grafikonu" msgid "Type of comparison, value difference or percentage" msgstr "Vrsta primerjave, razlike vrednosti ali procenta" -#, fuzzy msgid "Type to search (contains)..." -msgstr "Iskanje stolpcev" +msgstr "Vnesite za iskanje (vsebuje) ..." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "Type to search (ends with)..." -msgstr "Vtipkajte za iskanje (se konča z)..." +msgstr "Vnesite za iskanje (konča se z) ..." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "Type to search (starts with)..." -msgstr "Vtipkajte za iskanje (se začne z)..." +msgstr "Vnesite za iskanje (začne se z) ..." msgid "UI Configuration" msgstr "UI-nastavitve" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "UI theme administration is not enabled." -msgstr "Upravljanje tem uporabniškega vmesnika ni omogočeno." +msgstr "Upravljanje teme uporabniškega vmesnika ni omogočeno." msgid "URL" msgstr "URL" -#, fuzzy msgid "URL Filters" -msgstr "Vsi filtri" +msgstr "URL filtri" msgid "URL Parameters" msgstr "Parametri URL" -#, fuzzy msgid "URL Slug" -msgstr "URL slug" +msgstr "Ključ URL-ja" msgid "URL parameters" msgstr "Parametri URL" msgid "UUID to track the execution status" -msgstr "" +msgstr "UUID za spremljanje stanja izvajanja" msgid "Unable to calculate such a date delta" msgstr "Časovne razlike ni mogoče izračunati" @@ -17403,30 +15949,25 @@ msgstr "" "\"BigQuery Job User\" in so nastavljena naslednja dovoljenja: " "\"bigquery.readsessions.create\", \"bigquery.readsessions.getData\"" -#, fuzzy msgid "" "Unable to connect. Verify that the following roles are set on the service" " account: \"Cloud Datastore Viewer\", \"Cloud Datastore User\", \"Cloud " "Datastore Creator\"" msgstr "" -"Povezava neuspešna. Preverite če so v servisnem računu nastavljene " -"naslednje vloge: \"BigQuery Data Viewer\", \"BigQuery Metadata Viewer\", " -"\"BigQuery Job User\" in so nastavljena naslednja dovoljenja: " -"\"bigquery.readsessions.create\", \"bigquery.readsessions.getData\"" +"Ni mogoče vzpostaviti povezave. Preverite, ali so v računu storitve nastavljene naslednje vloge: »Ogledovalnik shrambe podatkov v oblaku«, »Uporabnik " +"shrambe podatkov v oblaku«, »Ustvarjalec shrambe podatkov v oblaku«" msgid "Unable to create chart without a query id." msgstr "Grafikona ni mogoče ustvariti brez id-ja poizvedbe." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "" "Unable to create report: User email address is required but not found. " "Please ensure your user profile has a valid email address." msgstr "" -"Poročila ni mogoče ustvariti: zahtevani e-poštni naslov uporabnika ni bil" -" najden. Prepričajte se, da ima vaš uporabniški profil veljaven e-poštni " -"naslov." +"Poročila ni mogoče ustvariti: E-poštni naslov uporabnika je zahtevan, vendar ga ni mogoče najti. Prepričajte se, da ima vaš uporabniški profil veljaven e-" +"poštni naslov." msgid "Unable to decode value" msgstr "Vrednosti ni mogoče dešifrirati" @@ -17436,38 +15977,34 @@ msgstr "Vrednosti ni mogoče šifrirati" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "Unable to fetch semantic views. Check the layer configuration." -msgstr "Semantičnih pogledov ni mogoče pridobiti. Preverite konfiguracijo sloja." +msgstr "Semantičnih pogledov ni mogoče pridobiti. Preverite konfiguracijo plasti." #, python-format msgid "Unable to find such a holiday: [%(holiday)s]" msgstr "Ni mogoče najti takšnega praznika: [%(holiday)s]" -#, fuzzy msgid "Unable to generate download payload" -msgstr "Nadzorne plošče ni mogoče naložiti" +msgstr "Podatkov za prenos ni mogoče pripraviti" #, python-format msgid "Unable to generate forecast: %(error)s" -msgstr "" +msgstr "Napovedi ni mogoče ustvariti: %(error)s" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "" "Unable to identify temporal column for date range time comparison.Please " "ensure your dataset has a properly configured time column." msgstr "" -"Časovnega stolpca za primerjavo časovnih razponov ni mogoče " -"identificirati. Prepričajte se, da ima vaš nabor podatkov pravilno " -"konfiguriran časovni stolpec." +"Časovnega stolpca za časovno primerjavo časovnega obsega ni mogoče identificirati. Zagotovite, da ima vaš podatkovni niz pravilno konfiguriran časovni " +"stolpec." #, python-format msgid "" "Unable to interpret the time offset: %(offset)s. Use a relative time such" " as \"1 month ago\"." -msgstr "" +msgstr "Časovnega zamika %(offset)s ni mogoče razložiti. Uporabite relativni čas, na primer »pred 1 mesecem«." msgid "" "Unable to load columns for the selected table. Please select a different " @@ -17501,22 +16038,19 @@ msgstr "" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fa, fr, ja, lv, mi, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Unable to parse SQL" -msgstr "SQL-a ni mogoče razčleniti" +msgstr "Ni mogoče razčleniti SQL" -#, fuzzy msgid "Unable to read the file, please refresh and try again." -msgstr "Prenos slike ni uspel. Osvežite in poskusite ponovno." +msgstr "Datoteke ni mogoče prebrati, osvežite in poskusite znova." msgid "Unable to retrieve dashboard colors" msgstr "Neuspešno pridobivanje barv nadzorne plošče" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fr, ja, lv, mi, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Unable to sync permissions for this database connection." -msgstr "Dovoljenj za to podatkovno povezavo ni mogoče sinhronizirati." +msgstr "Ni mogoče sinhronizirati dovoljenj za to povezavo zbirke podatkov." msgid "Undefined" msgstr "Ni definirano" @@ -17530,9 +16064,8 @@ msgstr "Razveljavi dejanje" msgid "Undo?" msgstr "Povrni?" -#, fuzzy msgid "Unexpected HTTP 401 response. Check your credentials." -msgstr "Zgodila se je nepričakovana napaka. Podrobnosti preverite v dnevnikih" +msgstr "Nepričakovan odziv HTTP 401. Preverite svoje poverilnice." msgid "Unexpected error" msgstr "Nepričakovana napaka" @@ -17550,13 +16083,11 @@ msgstr "Nepričakovana napaka končnice datoteke" msgid "Unexpected time range: %(error)s" msgstr "Nepričakovano časovno obdobje: %(error)s" -#, fuzzy msgid "Ungroup By" -msgstr "Združevanje po (Group by)" +msgstr "Razdruži po" -#, fuzzy msgid "Unhide" -msgstr "razveljavitev" +msgstr "Razkrij" msgid "Unknown" msgstr "Neznano" @@ -17565,7 +16096,6 @@ msgstr "Neznano" msgid "Unknown Doris server host \"%(hostname)s\"." msgstr "Neznan Doris strežnik \"%(hostname)s\"." -#, fuzzy msgid "Unknown Error" msgstr "Neznana napaka" @@ -17595,7 +16125,6 @@ msgstr "Neznana oblika vnosa" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "Unknown tokens will be highlighted as warnings." msgstr "Neznani žetoni bodo označeni kot opozorila." @@ -17605,24 +16134,20 @@ msgstr "Neznan tip" msgid "Unknown value" msgstr "Neznana vrednost" -#, fuzzy msgid "Unpin" -msgstr "v teku" +msgstr "Odpni" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "Unpin from the result panel" -msgstr "Odpni iz plošče z rezultati" +msgstr "Odpnite s plošče z rezultati" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "Unpin from top" msgstr "Odpni z vrha" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [no refs] -#, fuzzy msgid "Unsafe link blocked" msgstr "Nevarna povezava je blokirana" @@ -17640,11 +16165,8 @@ msgstr "Nepodprt tip izraza: %(clause)s" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Unsupported file type. Please use CSV, Excel, or Columnar files." -msgstr "" -"Nepodprta vrsta datoteke. Prosimo, uporabite datoteke CSV, Excel ali " -"stolpčne datoteke." +msgstr "Nepodprta vrsta datoteke. Uporabite datoteke CSV, Excel ali Columnar." #, python-format msgid "Unsupported post processing operation: %(operation)s" @@ -17671,16 +16193,14 @@ msgstr "Neimenovana poizvedba" msgid "Untitled query" msgstr "Neimenovana poizvedba" -#, fuzzy msgid "Unverified" -msgstr "Ni definirano" +msgstr "Nepreverjeno" msgid "Update" msgstr "Posodobi" -#, fuzzy msgid "Update auto-refresh" -msgstr "Nastavi interval samodejnega osveževanja" +msgstr "Posodobite samodejno osveževanje" msgid "Update chart" msgstr "Posodobi grafikon" @@ -17719,9 +16239,8 @@ msgstr "Naloži JSON datoteko" msgid "Upload a file with a valid extension. Valid: [%s]" msgstr "Naložite datoteko z veljavno končnico. Veljavne so: [%s]" -#, fuzzy msgid "Upload credentials" -msgstr "Naloži prijavne podatke" +msgstr "Naloži poverilnice" msgid "Upload file to database" msgstr "Naloži datoteko v podatkovno bazo" @@ -17735,11 +16254,6 @@ msgstr "Zahtevano je nalaganje datoteke" msgid "Upper Threshold" msgstr "Zgornji prag" -msgid "" -"Upper bound of the color scale. When both start and end are set, the " -"legend uses this fixed range instead of the automatic data range." -msgstr "" - msgid "Upper threshold must be greater than lower threshold" msgstr "Zgornji prag mora biti večji od spodnjega" @@ -17755,13 +16269,11 @@ msgstr "Uporabi razmerje površin" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "" "Use Handlebars syntax to create custom tooltips. Available variables are " "based on your tooltip contents selection above." msgstr "" -"Uporabite sintakso Handlebars za ustvarjanje prilagojenih namigov. " -"Razpoložljive spremenljivke temeljijo na zgornji izbiri vsebine namiga." +"Uporabite sintakso Handlebars za ustvarjanje namigov orodij po meri. Razpoložljive spremenljivke temeljijo na vaši zgornji izbiri vsebine orodnih namigov." msgid "Use a log scale" msgstr "Uporabi logaritemsko skalo" @@ -17786,20 +16298,17 @@ msgstr "" "Uporabite enega izmed obstoječih grafikonov kot vir oznak.\n" " Grafikon mora biti naslednjega tipa: [%s]" -#, fuzzy msgid "Use automatic color" -msgstr "Samodejne barve" +msgstr "Uporabite samodejno barvo" -#, fuzzy msgid "Use current extent" -msgstr "Zaženi trenutno poizvedbo" +msgstr "Uporabi trenutni obseg" msgid "Use date formatting even when metric value is not a timestamp" msgstr "Oblikovanje datuma uporabi tudi, ko vrednost mere ni časovna značka" -#, fuzzy msgid "Use gradient" -msgstr "Granulacija časa" +msgstr "Uporabi gradient" msgid "Use metrics as a top level group for columns or for rows" msgstr "Uporabi mere kot vrhovni nivo grupiranja za stolpce ali vrstice" @@ -17839,28 +16348,23 @@ msgstr "" msgid "User" msgstr "Uporabnik" -#, fuzzy msgid "User Name" msgstr "Uporabniško ime" -#, fuzzy msgid "User Registrations" -msgstr "Uporabi razmerje površin" +msgstr "Registracije uporabnikov" msgid "User doesn't have the proper permissions." msgstr "Uporabnik nima ustreznih dovoljenj." -#, fuzzy msgid "User info" -msgstr "Uporabnik" +msgstr "Informacije o uporabniku" -#, fuzzy msgid "User must select a value before applying the chart customization" -msgstr "Uporabnik mora obvezno izbrati vrednost pred uveljavitvijo filtra" +msgstr "Uporabnik mora izbrati vrednost, preden uporabi prilagoditev grafikona" -#, fuzzy msgid "User must select a value before applying the customization" -msgstr "Uporabnik mora obvezno izbrati vrednost pred uveljavitvijo filtra" +msgstr "Uporabnik mora izbrati vrednost, preden uporabi prilagoditev" msgid "User must select a value before applying the filter" msgstr "Uporabnik mora obvezno izbrati vrednost pred uveljavitvijo filtra" @@ -17868,24 +16372,20 @@ msgstr "Uporabnik mora obvezno izbrati vrednost pred uveljavitvijo filtra" msgid "User query" msgstr "Uporabnikova poizvedba" -#, fuzzy msgid "User registrations" -msgstr "Uporabi razmerje površin" +msgstr "Registracije uporabnikov" msgid "Username" msgstr "Uporabniško ime" -#, fuzzy msgid "Username is required" -msgstr "Zahtevano je ime" +msgstr "Zahtevano je uporabniško ime" -#, fuzzy msgid "Username:" -msgstr "Uporabniško ime" +msgstr "Uporabniško ime:" -#, fuzzy msgid "Users" -msgstr "serije" +msgstr "Uporabniki" msgid "Users are not allowed to set a search path for security reasons." msgstr "" @@ -17920,44 +16420,37 @@ msgstr "" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "Uses the first 25 values if the dimension has more." -msgstr "Uporabi prvih 25 vrednosti, če ima dimenzija več." +msgstr "Uporabi prvih 25 vrednosti, če jih ima dimenzija več." -#, fuzzy msgid "Valid SQL expression" -msgstr "SQL-izraz" +msgstr "Veljaven izraz SQL" -#, fuzzy msgid "Validate query" -msgstr "Ogled poizvedbe" +msgstr "Preveri poizvedbo" # Machine-corrected via backfill_po.py (claude-sonnet-4-6) [replaced a # mistranslation] -#, fuzzy msgid "Validate your expression" -msgstr "Preverite vaš izraz" +msgstr "Preveri izraz" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fr, ja, lv, mi, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy, python-format +#, python-format msgid "Validating connectivity for %s" msgstr "Preverjanje povezljivosti za %s" -#, fuzzy msgid "Validating..." -msgstr "Nalagam ..." +msgstr "Preverjanje ..." msgid "Value" msgstr "Vrednost" -#, fuzzy msgid "Value Aggregation" -msgstr "Agregacija" +msgstr "Seštevanje vrednosti" -#, fuzzy msgid "Value Columns" -msgstr "Stolpci tabele" +msgstr "Stolpci vrednosti" msgid "Value Domain" msgstr "Domena vrednosti" @@ -17978,23 +16471,17 @@ msgstr "Vrednost ne sme presegati %s" msgid "Value difference between the time periods" msgstr "Razlika vrednosti med časovnimi obdobji" -#, python-format -msgid "Value exceeds the maximum allowed size of %(max_size)d bytes." -msgstr "" - msgid "Value format" msgstr "Oblika zapisa vrednosti" -#, fuzzy msgid "Value greater than" -msgstr "Vrednost mora biti večja od 0" +msgstr "Vrednost večja od" msgid "Value is required" msgstr "Zahtevana je vrednost" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fr, ja, lv, mi, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Value less than" msgstr "Vrednost manjša od" @@ -18004,9 +16491,8 @@ msgstr "Vrednost mora biti 0 ali večja" msgid "Value must be greater than 0" msgstr "Vrednost mora biti večja od 0" -#, fuzzy msgid "Values" -msgstr "Vrednost" +msgstr "Vrednosti" msgid "Values are dependent on other filters" msgstr "Vrednosti so odvisne od drugih filtrov" @@ -18016,11 +16502,8 @@ msgstr "Vrednosti so odvisne od" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Values less than this percentage will be grouped into the Other category." -msgstr "" -"Vrednosti, ki so manjše od tega odstotka, bodo razvrščene v kategorijo " -"»Ostalo«." +msgstr "Vrednosti, nižje od tega odstotka, bodo razvrščene v kategorijo Drugo." msgid "" "Values selected in other filters will affect the filter options to only " @@ -18042,10 +16525,6 @@ msgstr "Navpično (levo)" msgid "View" msgstr "Ogled" -#, python-format -msgid "View %(type)s" -msgstr "" - msgid "View All »" msgstr "Ogled vseh »" @@ -18064,9 +16543,8 @@ msgstr "Ogled v SQL laboratoriju" msgid "View query" msgstr "Ogled poizvedbe" -#, fuzzy msgid "View theme properties" -msgstr "Uredi lastnosti" +msgstr "Oglejte si lastnosti teme" msgid "Viewed" msgstr "Ogledano" @@ -18131,7 +16609,9 @@ msgid "" "Visualize a related metric across pairs of groups. Heatmaps excel at " "showcasing the correlation or strength between two groups. Color is used " "to emphasize the strength of the link between each pair of groups." -msgstr "Vizualizacija povezanih mer med pari skupin." +msgstr "" +"Prikažite povezano metriko med pari skupin. Toplotni zemljevidi so odlični za ponazoritev korelacije ali moči povezave med dvema skupinama. Barva poudarja " +"moč povezave med posameznim parom skupin." msgid "" "Visualize geospatial data like 3D buildings, landscapes, or objects in " @@ -18216,15 +16696,14 @@ msgstr "SRE" #. do-not-translate msgid "WFS" -msgstr "" +msgstr "WFS" #. do-not-translate msgid "WMS" -msgstr "" +msgstr "WMS" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "Waiting for first refresh" msgstr "Čakanje na prvo osvežitev" @@ -18240,7 +16719,6 @@ msgstr "Želite dodati novo podatkovno bazo?" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Warehouse" msgstr "Skladišče" @@ -18259,13 +16737,10 @@ msgstr "" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "" "Warning: ILIKE queries may be slow on large datasets as they cannot use " "indexes effectively." -msgstr "" -"Opozorilo: poizvedbe ILIKE so lahko počasne na velikih naborih podatkov, " -"ker ne morejo učinkovito uporabljati indeksov." +msgstr "Opozorilo: poizvedbe ILIKE so lahko počasne pri velikih naborih podatkov, saj ne morejo učinkovito uporabljati indeksov." msgid "Was unable to check your query" msgstr "Poizvedbe ni bilo mogoče preveriti" @@ -18273,13 +16748,11 @@ msgstr "Poizvedbe ni bilo mogoče preveriti" msgid "Waterfall Chart" msgstr "Grafikon slapov" -#, fuzzy msgid "We are unable to connect to your database." -msgstr "Povezava s podatkovno bazo \"%(database)s\" ni uspela." +msgstr "Ne moremo se povezati z vašo bazo podatkov." -#, fuzzy msgid "We are working on your query" -msgstr "Ime vaše poizvedbe" +msgstr "Obdelujemo vašo poizvedbo" #, python-format msgid "We can't seem to resolve column \"%(column)s\" at line %(location)s." @@ -18303,9 +16776,8 @@ msgstr "" msgid "We have the following keys: %s" msgstr "Imamo naslednje ključe: %s" -#, fuzzy msgid "We were unable to activate or deactivate this report." -msgstr "Aktiviranje ali deaktiviranje poročila ni uspelo." +msgstr "Tega poročila nismo mogli aktivirati ali deaktivirati." msgid "" "We were unable to carry over any controls when switching to this new " @@ -18423,11 +16895,10 @@ msgstr "Če je podana sekundarna metrika, je uporabljena linearna barvna skala." msgid "When checked, the map will zoom to your data after each query" msgstr "Če želite, da se zemljevid prilagodi vašim podatkom po vsaki poizvedbi" -#, fuzzy msgid "" "When enabled, the axis will display labels for the minimum and maximum " "values of your data" -msgstr "Če želite prikaz min. in max. vrednosti Y-osi" +msgstr "Ko je omogočeno, bo os prikazala oznake za najnižje in največje vrednosti vaših podatkov" msgid "When enabled, users are able to visualize SQL Lab results in Explore." msgstr "" @@ -18439,16 +16910,14 @@ msgstr "" "Če je podana samo primarna metrika, je uporabljena kategorična barvna " "skala." -#, fuzzy msgid "" "When specifying SQL, the datasource acts as a view. Superset will use " "this statement as a subquery while grouping and filtering on the " "generated parent queries.If changes are made to your SQL query, columns " "in your dataset will be synced when saving the dataset." msgstr "" -"Ko uporabite SQL-poizvedbo, se podatkovni vir obnaša kot pogled (view). " -"Superset bo ta zapis uporabil kot podpoizvedbo, pri čemer bo združeval in" -" filtriral v ustvarjeni nadrejeni poizvedbi." +"Ko podajate SQL, vir podatkov deluje kot pogled. Superset bo ta stavek uporabil kot podpoizvedbo med združevanjem in filtriranjem ustvarjenih nadrejenih " +"poizvedb. Če spremenite vašo poizvedbo SQL, bodo stolpci v vašem naboru podatkov sinhronizirani, ko shranite podatkovni niz." msgid "" "When the secondary temporal columns are filtered, apply the same filter " @@ -18457,12 +16926,6 @@ msgstr "" "Če so sekundarni časovni stolpci filtrirani, uporabi enak filter tudi za " "glavni časovni stolpec." -msgid "" -"When typing or pasting filter values, commas will separate values into " -"multiple entries. To include a comma within a value, wrap it in double " -"quotes: \"San Francisco, CA\"" -msgstr "" - msgid "" "When unchecked, colors from the selected color scheme will be used for " "time shifted series" @@ -18491,13 +16954,10 @@ msgstr "Če ne uporabljate prilagodljive oblike, se oznake lahko prekrivajo" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, ro, sr, # sr_Latn] -#, fuzzy msgid "" "When using this option, default value can't be set. Using this option may" " impact the load times for your dashboard." -msgstr "" -"Ko je ta možnost aktivna, privzete vrednosti ni mogoče nastaviti. Uporaba" -" te možnosti lahko vpliva na čas nalaganja vaše nadzorne plošče." +msgstr "Pri uporabi te možnosti privzete vrednosti ni mogoče nastaviti. Uporaba te možnosti lahko vpliva na čas nalaganja vaše nadzorne plošče." msgid "Whether the progress bar overlaps when there are multiple groups of data" msgstr "Če želite prekrivanje območij, ko imate več skupin podatkov" @@ -18547,19 +17007,16 @@ msgid "Whether to display bubbles on top of countries" msgstr "Če želite prikaz mehurčkov nad državami" msgid "Whether to display entries with null values in the hierarchy" -msgstr "" +msgstr "Ali naj se v hierarhiji prikažejo vnosi z ničelnimi vrednostmi" -#, fuzzy msgid "Whether to display in the chart" -msgstr "Če želite prikaz legende za grafikon" +msgstr "Ali naj se prikaže v grafikonu" -#, fuzzy msgid "Whether to display the X Axis" -msgstr "Če želite prikaz oznak." +msgstr "Ali naj se prikaže os X" -#, fuzzy msgid "Whether to display the Y Axis" -msgstr "Če želite prikaz oznak." +msgstr "Ali naj se prikaže os Y" msgid "Whether to display the aggregate count" msgstr "Če želite prikazati agregirano število" @@ -18573,9 +17030,8 @@ msgstr "Če želite prikaz oznak." msgid "Whether to display the legend (toggles)" msgstr "Preklapljanje prikaza legende" -#, fuzzy msgid "Whether to display the metric name" -msgstr "Če želite prikazati ime mere kot naslov" +msgstr "Ali naj se prikaže ime mere" msgid "Whether to display the metric name as a title" msgstr "Če želite prikazati ime mere kot naslov" @@ -18586,16 +17042,14 @@ msgstr "Če želite prikaz min. in max. vrednosti X-osi" msgid "Whether to display the min and max values of the Y-axis" msgstr "Če želite prikaz min. in max. vrednosti Y-osi" -#, fuzzy msgid "Whether to display the numbered column" -msgstr "Če želite prikazati trendno črto" +msgstr "Ali naj se prikaže oštevilčen stolpec" msgid "Whether to display the numerical values within the cells" msgstr "Če želite v celicah prikazati numerične vrednosti" -#, fuzzy msgid "Whether to display the percentage value in the tooltip" -msgstr "Če želite prikaz procentov v opisu orodja" +msgstr "Ali naj se vrednost v odstotkih prikaže v opisu orodja" msgid "Whether to display the stroke" msgstr "Če želite prikazati obrobe" @@ -18609,16 +17063,14 @@ msgstr "Če želite prikazati časovno značko" msgid "Whether to display the tooltip labels." msgstr "Če želite prikaz oznak opisa orodja." -#, fuzzy msgid "Whether to display the total value in the tooltip" -msgstr "Če želite v celicah prikazati numerične vrednosti" +msgstr "Ali naj se v opisu orodja prikaže skupna vrednost" msgid "Whether to display the trend line" msgstr "Če želite prikazati trendno črto" -#, fuzzy msgid "Whether to display the type icon (#, Δ, %)" -msgstr "Če želite prikazati agregirano število" +msgstr "Ali naj se prikaže ikona tipa (#, Δ, %)" msgid "Whether to enable changing graph position and scaling." msgstr "Če želite omogočiti premikanje in povečevanje/zmanjševanje grafikona." @@ -18681,7 +17133,7 @@ msgstr "Če želite padajoče razvrstiti rezultate z izbrano mero." msgid "" "Whether to sort tooltip by the selected metric in descending order. On " "stacked charts, values are shown in ascending order." -msgstr "" +msgstr "Ali naj se opis orodja razvrsti padajoče po izbrani meri. Pri naloženih grafikonih so vrednosti prikazane naraščajoče." msgid "Whether to truncate metrics" msgstr "Če želite odstraniti naziv mere" @@ -18695,9 +17147,8 @@ msgstr "Kateri element se poudari na prehodu z miško" msgid "Whisker/outlier options" msgstr "Možnosti grafikona kvantilov" -#, fuzzy msgid "Why do I need to create a database?" -msgstr "Želite dodati novo podatkovno bazo?" +msgstr "Zakaj moram ustvariti bazo podatkov?" msgid "Width" msgstr "Širina" @@ -18708,9 +17159,8 @@ msgstr "Širina intervala zaupanja. Mora bit med 0 in 1" msgid "Width of the sparkline" msgstr "Širina hitrega grafikona" -#, fuzzy msgid "Width scale multiplier" -msgstr "Množitelj" +msgstr "Množitelj lestvice širine" msgid "Window must be > 0" msgstr "Okno mora biti > 0" @@ -18751,20 +17201,17 @@ msgstr "Oblika X-osi" msgid "X Axis Label" msgstr "Naslov X-osi" -#, fuzzy msgid "X Axis Label Interval" -msgstr "Naslov X-osi" +msgstr "Interval oznake osi X" -#, fuzzy msgid "X Axis Number Format" -msgstr "Oblika X-osi" +msgstr "Oblika številke osi X" msgid "X Axis Title" msgstr "Naslov X-osi" -#, fuzzy msgid "X Axis Title Margin" -msgstr "Rob naslova Y-osi" +msgstr "Rob naslova osi X" msgid "X Log Scale" msgstr "Logaritemska X-os" @@ -18792,7 +17239,7 @@ msgstr "Interval X-osi" #. do-not-translate msgid "XYZ" -msgstr "" +msgstr "XYZ" msgid "Y 2 bounds" msgstr "Meje Y-osi 2" @@ -18846,7 +17293,7 @@ msgid "Y-axis bounds" msgstr "Meje Y-osi" msgid "Y-axis range slider" -msgstr "" +msgstr "Drsnik obsega osi Y" msgid "Y-scale interval" msgstr "Interval Y-osi" @@ -18867,9 +17314,8 @@ msgstr "Leta %s" msgid "Yes" msgstr "Da" -#, fuzzy msgid "Yes, Cancel" -msgstr "Da, prekini" +msgstr "Da, prekliči" msgid "Yes, cancel" msgstr "Da, prekini" @@ -18883,9 +17329,8 @@ msgstr "Oznake dodajate %s %ss" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, ja, lv, # ru, sr, sr_Latn, uk] -#, fuzzy msgid "You are editing a query from the virtual dataset " -msgstr "Urejate poizvedbo iz virtualnega nabora podatkov " +msgstr "Urejate poizvedbo iz navideznega nabora podatkov " msgid "" "You are importing one or more charts that already exist. Overwriting " @@ -18927,40 +17372,32 @@ msgstr "" "Uvažate eno ali več shranjenih poizvedb, ki že obstajajo. S prepisom " "lahko izgubite podatke. Ali ste prepričani, da želite prepisati?" -#, fuzzy msgid "" "You are importing one or more themes that already exist. Overwriting " "might cause you to lose some of your work. Are you sure you want to " "overwrite?" -msgstr "" -"Uvažate enega ali več podatkovnih setov, ki že obstajajo. S prepisom " -"lahko izgubite podatke. Ali ste prepričani, da želite prepisati?" +msgstr "Uvažate eno ali več tem, ki že obstajajo. Prepisovanje lahko povzroči izgubo dela vašega dela. Ali ste prepričani, da želite prepisati?" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fr, ja, lv, mi, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "" "You are viewing this chart in a dashboard context with labels shared " "across multiple charts.\n" " The color scheme selection is disabled." msgstr "" -"Ta grafikon si ogledujete v kontekstu nadzorne plošče z oznakami, ki so " -"skupne več grafikonom.\n" +"Ta grafikon si ogledujete v kontekstu nadzorne plošče z oznakami, ki si jih deli več grafikonov.\n" " Izbira barvne sheme je onemogočena." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fr, ja, lv, mi, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "" "You are viewing this chart in the context of a dashboard that is directly" " affecting its colors.\n" " To edit the color scheme, open this chart outside of the " "dashboard." msgstr "" -"Ta grafikon si ogledujete v kontekstu nadzorne plošče, ki neposredno " -"vpliva na njegove barve.\n" -" Če želite urediti barvno shemo, odprite ta grafikon zunaj " -"nadzorne plošče." +"Ta grafikon si ogledujete v kontekstu nadzorne plošče, ki neposredno vpliva na njene barve.\n" +" Če želite urediti barvno shemo, odprite ta grafikon zunaj nadzorne plošče." msgid "You can" msgstr "Lahko" @@ -19020,9 +17457,8 @@ msgstr "Nimate dovoljenja za urejanje tega grafikona" msgid "You do not have permission to edit this dashboard" msgstr "Nimate dovoljenja za urejanje te nadzorne plošče" -#, fuzzy msgid "You do not have permission to perform this operation" -msgstr "Nimate dovoljenja za urejanje tega grafikona" +msgstr "Nimate dovoljenja za izvedbo te operacije" msgid "You do not have permission to read tags" msgstr "Nimate dovoljenja za branje oznak" @@ -19034,9 +17470,8 @@ msgid "You do not have sufficient permissions to edit the chart" msgstr "Nimate zadostnih dovoljenj za urejanje grafikona" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ja] -#, fuzzy msgid "You don't have access to one or more of the referenced datasources." -msgstr "Nimate dostopa do enega ali več sklicevanih virov podatkov." +msgstr "Nimate dostopa do enega ali več navedenih virov podatkov." msgid "You don't have access to this chart." msgstr "Nimate dostopa do tega grafikona." @@ -19050,21 +17485,17 @@ msgstr "Nimate dostopa do tega podatkovnega seta." msgid "You don't have access to this embedded dashboard config." msgstr "Nimate dostopa do konfiguracije te vgrajene nadzorne plošče." -#, fuzzy msgid "You don't have access to this semantic view." -msgstr "Nimate dostopa do tega podatkovnega seta." +msgstr "Nimate dostopa do tega semantičnega pogleda." -#, fuzzy msgid "You don't have permission to copy to clipboard" -msgstr "Nimate dovoljenja za spreminjanje vrednosti." +msgstr "Nimate dovoljenja za kopiranje v odložišče" -#, fuzzy msgid "You don't have permission to export data" -msgstr "Nimate dovoljenja za branje oznak" +msgstr "Nimate dovoljenja za izvoz podatkov" -#, fuzzy msgid "You don't have permission to export images" -msgstr "Nimate dovoljenja za branje oznak" +msgstr "Nimate dovoljenja za izvoz slik" msgid "You don't have permission to modify the value." msgstr "Nimate dovoljenja za spreminjanje vrednosti." @@ -19088,20 +17519,18 @@ msgstr "Nimate pravic za ustvarjanje grafikona" msgid "You don't have the rights to create a dashboard" msgstr "Nimate pravic za ustvarjanje nadzorne plošče" -#, fuzzy msgid "You don't have the rights to export data" -msgstr "Nimate pravic za ustvarjanje nadzorne plošče" +msgstr "Nimate pravic za izvoz podatkov" -#, fuzzy, python-format +#, python-format msgid "You have been removed from task: %s" -msgstr "Odstranili ste ta filter." +msgstr "Odstranjeni ste bili iz naloge: %s" msgid "You have removed this filter." msgstr "Odstranili ste ta filter." -#, fuzzy msgid "You have unsaved changes" -msgstr "Imate neshranjene spremembe." +msgstr "Imate neshranjene spremembe" msgid "You have unsaved changes." msgstr "Imate neshranjene spremembe." @@ -19127,27 +17556,27 @@ msgstr "" msgid "" "You must be a chart editor in order to delete. Please reach out to a " "chart editor to request modifications or edit access." -msgstr "" +msgstr "Za brisanje morate biti urednik grafikona. Za spremembe ali dostop za urejanje se obrnite na urednika grafikona." msgid "" "You must be a chart editor in order to edit. Please reach out to a chart " "editor to request modifications or edit access." -msgstr "" +msgstr "Za urejanje morate biti urednik grafikona. Za spremembe ali dostop za urejanje se obrnite na urednika grafikona." msgid "" "You must be a dashboard editor in order to delete. Please reach out to a " "dashboard editor to request modifications or edit access." -msgstr "" +msgstr "Za brisanje morate biti urednik nadzorne plošče. Za spremembe ali dostop za urejanje se obrnite na urednika nadzorne plošče." msgid "" "You must be a dashboard editor in order to edit. Please reach out to a " "dashboard editor to request modifications or edit access." -msgstr "" +msgstr "Za urejanje morate biti urednik nadzorne plošče. Za spremembe ali dostop za urejanje se obrnite na urednika nadzorne plošče." msgid "" "You must be a dataset editor in order to delete. Please reach out to a " "dataset editor to request modifications or edit access." -msgstr "" +msgstr "Za brisanje morate biti urednik podatkovnega niza. Za spremembe ali dostop za urejanje se obrnite na urednika podatkovnega niza." msgid "" "You must be a dataset editor in order to edit. Please reach out to a " @@ -19157,9 +17586,8 @@ msgstr "" "nabora podatkov, da zahtevate spremembe ali dostop za urejanje." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ja, tr] -#, fuzzy msgid "You must change your password before continuing." -msgstr "Pred nadaljevanjem morate spremeniti geslo." +msgstr "Preden nadaljujete, morate spremeniti geslo." msgid "You must pick a name for the new dashboard" msgstr "Izbrati morate ime nove nadzorne plošče" @@ -19168,7 +17596,7 @@ msgid "You must run the query successfully first" msgstr "Najprej morate uspešno izvesti poizvedbo" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ja] -#, fuzzy, python-format +#, python-format msgid "" "You need access to the following tables: %(tables)s, " "'all_database_access' or 'all_datasource_access' permission" @@ -19178,7 +17606,6 @@ msgstr "" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "You need to" msgstr "Morate" @@ -19193,13 +17620,11 @@ msgstr "" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy, python-format +#, python-format msgid "" "You'll be removed from this task. It will continue running for %s other " "subscriber(s)." -msgstr "" -"Odstranjeni boste iz te naloge. Nadaljevala se bo izvajati za %s " -"drugega(-ih) naročnika(-ov)." +msgstr "Odstranjeni boste iz te naloge. Še naprej se bo izvajal za %s druge naročnike." msgid "" "You've changed datasets. Any controls with data (columns, metrics) that " @@ -19210,15 +17635,13 @@ msgstr "" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Your account is activated. You can log in with your credentials." -msgstr "Vaš račun je aktiviran. Prijavite se lahko s svojimi poverilnicami." +msgstr "Vaš račun je aktiviran. Lahko se prijavite s svojimi poverilnicami." # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Your changes will be lost if you leave without saving." -msgstr "Vaše spremembe bodo izgubljene, če zapustite brez shranjevanja." +msgstr "Vaše spremembe bodo izgubljene, če zapustite, ne da bi jih shranili." msgid "Your chart is not up to date" msgstr "Grafikon ni aktualen" @@ -19226,19 +17649,10 @@ msgstr "Grafikon ni aktualen" msgid "Your chart is ready to go!" msgstr "Grafikon je pripravljen!" -#, python-format -msgid "Your dashboard export could not be completed: %(title)s" -msgstr "" - -#, python-format -msgid "Your dashboard export is ready: %(title)s" -msgstr "" - # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fr, ja, lv, mi, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "Your dashboard is near the size limit." -msgstr "Vaša nadzorna plošča se približuje omejitvi velikosti." +msgstr "Vaša nadzorna plošča je blizu omejitve velikosti." #, python-format msgid "" @@ -19247,17 +17661,8 @@ msgid "" "into multiple dashboards) or raise the " "SUPERSET_DASHBOARD_POSITION_DATA_LIMIT config setting." msgstr "" - -msgid "Your export is being prepared. You'll receive an email when it's ready." -msgstr "" - -#, python-format -msgid "Your export of \"%(title)s\" could not be completed." -msgstr "" - -#, python-format -msgid "Your export of \"%(title)s\" is ready." -msgstr "" +"Your dashboard is too large to save: the serialized layout length is %s but the limit is %s. Reduce the dashboard size (for example, split it into multiple " +"dashboards) or raise the SUPERSET_DASHBOARD_POSITION_DATA_LIMIT config setting." msgid "Your query could not be saved" msgstr "Vaše poizvedbe ni mogoče shraniti" @@ -19288,17 +17693,14 @@ msgid "Your report could not be deleted" msgstr "Vašega poročila ni mogoče izbrisati" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ja] -#, fuzzy msgid "Your session has ended. Please sign in again." -msgstr "Vaša seja se je končala. Prosimo, prijavite se znova." +msgstr "Vaša seja je končana. Prosimo, prijavite se znova." -#, fuzzy msgid "Your user information" -msgstr "Splošne informacije" +msgstr "Vaši uporabniški podatki" -#, fuzzy msgid "Z-A" -msgstr "ž - a" +msgstr "Z-A" msgid "ZIP file contains multiple file types" msgstr "ZIP-datoteka vsebuje več tipov datotek" @@ -19309,9 +17711,8 @@ msgstr "Nadomeščanje ničel" msgid "Zoom" msgstr "Povečava" -#, fuzzy msgid "Zoom level" -msgstr "približaj območje" +msgstr "Stopnja povečave" msgid "Zoom level of the map" msgstr "Stopnja povečave zemljevida" @@ -19352,9 +17753,8 @@ msgstr "" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, ja, # lv, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "[untitled customization]" -msgstr "[nepoimenovana prilagoditev]" +msgstr "[prilagajanje brez naslova]" msgid "`compare_columns` must have the same length as `source_columns`." msgstr "`compare_columns` morajo imeti enako dolžino kot `source_columns`." @@ -19379,9 +17779,9 @@ msgid "`operation` property of post processing object undefined" msgstr "Lastnost `operation` poprocesirnega objekta ni definirana" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [no refs] -#, fuzzy, python-format +#, python-format msgid "`periods` must be between 1 and %(max)s" -msgstr "`periods` mora biti med 1 in %(max)s" +msgstr "Vrednost `periods` mora biti med 1 in %(max)s" msgid "`prophet` package not installed" msgstr "Knjižnica `prophet` ni nameščena" @@ -19403,13 +17803,11 @@ msgid "`width` must be greater or equal to 0" msgstr "`width` mora biti večja ali enaka 0" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ja] -#, fuzzy msgid "`window` must be between 1 and 10000" -msgstr "`window` mora biti med 1 in 10000" +msgstr "`okno` mora biti med 1 in 10000" -#, fuzzy msgid "a few seconds" -msgstr "5 seconds" +msgstr "nekaj sekund" msgid "aggregate" msgstr "agregacija" @@ -19439,7 +17837,6 @@ msgid "annotation_layer" msgstr "annotation_layer" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ja] -#, fuzzy msgid "apple" msgstr "jabolko" @@ -19455,28 +17852,24 @@ msgstr "samodejno" msgid "background" msgstr "ozadje" -#, fuzzy msgid "background color" -msgstr "ozadje" +msgstr "barva ozadja" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ja] -#, fuzzy msgid "banana" msgstr "banana" msgid "basis" msgstr "basis" -#, fuzzy msgid "begins with" -msgstr "Prijava z" +msgstr "se začne z" msgid "below (example:" msgstr "v polju spodaj (primer:" -#, fuzzy msgid "beta" -msgstr "Dodatno" +msgstr "beta" #, python-brace-format msgid "between {down} and {up} {name}" @@ -19489,9 +17882,8 @@ msgstr "bfill" msgid "bolt" msgstr "vijak" -#, fuzzy msgid "boolean" -msgstr "BOOLEAN" +msgstr "logično" msgid "boolean type icon" msgstr "ikona binarnega tipa" @@ -19511,9 +17903,8 @@ msgstr "ne sme biti prazno" msgid "cardinal" msgstr "cardinal" -#, fuzzy msgid "cell bar" -msgstr "Prikaži grafe v celicah" +msgstr "celična vrstica" msgid "change" msgstr "sprememba" @@ -19521,9 +17912,8 @@ msgstr "sprememba" msgid "chart" msgstr "grafikona" -#, fuzzy msgid "charts" -msgstr "Grafikoni" +msgstr "grafikoni" msgid "choose WHERE or HAVING..." msgstr "izberite WHERE ali HAVING..." @@ -19531,9 +17921,8 @@ msgstr "izberite WHERE ali HAVING..." msgid "click here" msgstr "kliknite tukaj" -#, fuzzy msgid "close" -msgstr "Zapri" +msgstr "zapri" msgid "code ISO 3166-1 alpha-2 (cca2)" msgstr "koda ISO 3166-1 alpha-2 (cca2)" @@ -19557,9 +17946,8 @@ msgstr "stolpec" msgid "connecting to %(dbModelName)s" msgstr "povezovanju z/s %(dbModelName)s" -#, fuzzy msgid "containing" -msgstr "Nadaljuj" +msgstr "ki vsebuje" msgid "content type" msgstr "vrsta vsebine" @@ -19592,24 +17980,20 @@ msgstr "kumulativna vsota" msgid "dashboard" msgstr "nadzorna plošča" -#, fuzzy msgid "dashboards" -msgstr "Nadzorne plošče" +msgstr "nadzorne plošče" -#, fuzzy msgid "data connection" -msgstr "Povezave na podatkovne baze" +msgstr "podatkovna povezava" -#, fuzzy msgid "data connections" -msgstr "Povezave na podatkovne baze" +msgstr "podatkovne povezave" msgid "database" msgstr "podatkovna baza" -#, fuzzy msgid "databases" -msgstr "Podatkovne baze" +msgstr "baze podatkov" msgid "dataset" msgstr "podatkovni set" @@ -19617,17 +18001,14 @@ msgstr "podatkovni set" msgid "dataset name" msgstr "ime podatkovnega seta" -#, fuzzy msgid "datasets" -msgstr "Podatkovni seti" +msgstr "podatkovni nizi" -#, fuzzy msgid "datasource" -msgstr "Podatkovni vir" +msgstr "vir podatkov" -#, fuzzy msgid "datasources" -msgstr "Podatkovni vir" +msgstr "viri podatkov" msgid "date" msgstr "datum" @@ -19675,9 +18056,8 @@ msgstr "deck.gl - raztreseni grafikon" msgid "deck.gl Screen Grid" msgstr "deck.gl - mreža" -#, fuzzy msgid "deck.gl layers (charts)" -msgstr "deck.gl grafikoni" +msgstr "plasti deck.gl (grafikoni)" msgid "deckGL" msgstr "deckGL" @@ -19697,9 +18077,8 @@ msgstr "deviacija" msgid "dialect+driver://username:password@host:port/database" msgstr "dialect+driver://username:password@host:port/database" -#, fuzzy msgid "documentation" -msgstr "Dokumentacija" +msgstr "dokumentacija" #. do-not-translate msgid "dttm" @@ -19743,9 +18122,8 @@ msgstr "npr. xy12345.us-east-2.aws" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "e.g., CI/CD Pipeline, Analytics Script" -msgstr "npr. CI/CD Pipeline, Analytics Script" +msgstr "npr. cevovod CI/CD, analitični skript" msgid "edit mode" msgstr "načinu urejanja" @@ -19756,13 +18134,11 @@ msgstr "uredniki" msgid "email subject" msgstr "zadeva sporočila" -#, fuzzy msgid "ends with" -msgstr "Debelina povezave" +msgstr "konča z" -#, fuzzy msgid "entire row" -msgstr "Prazna vrstica" +msgstr "celotno vrsto" msgid "entries" msgstr "vnosi" @@ -19797,18 +18173,16 @@ msgstr "razširi" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "extra.dashboard must be an object" -msgstr "extra.dashboard mora biti objekt" +msgstr "Vrednost extra.dashboard mora biti objekt" msgid "failed" msgstr "ni uspelo" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "farewell" -msgstr "zbogom" +msgstr "slovo" msgid "fetching" msgstr "pridobivanje" @@ -19819,16 +18193,14 @@ msgstr "ffill" msgid "flat" msgstr "ravno" -#, fuzzy msgid "for a list of available helpers." -msgstr "Ni razpoložljivih filtrov." +msgstr "za seznam razpoložljivih pomočnikov." msgid "for more information on how to structure your URI." msgstr "za več informacij o oblikovanju URI." -#, fuzzy msgid "formatted" -msgstr "Oblikovan datum" +msgstr "formatiran" msgid "function type icon" msgstr "ikona funkcijskega tipa" @@ -19836,9 +18208,8 @@ msgstr "ikona funkcijskega tipa" msgid "geohash (square)" msgstr "geohash (kvadrat)" -#, fuzzy msgid "greeting" -msgstr "Hranjenje dnevnikov" +msgstr "pozdrav" msgid "heatmap" msgstr "toplotni prikaz" @@ -19848,7 +18219,6 @@ msgstr "heatmap: vrednosti so normirane po celotni temperaturni lestvici" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "hello" msgstr "zdravo" @@ -19863,26 +18233,21 @@ msgstr "v" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "in order to run this operation." -msgstr "da bi izvedli to operacijo." +msgstr "za izvedbo te operacije." msgid "invalid email" msgstr "neveljaven email" -#, fuzzy msgid "is" -msgstr "Razdelki" +msgstr "je" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "" "is expected to be a Mapbox/OSM URL (eg. mapbox://styles/...) or a tile " "server URL (eg. tile://http...)" -msgstr "" -"mora biti Mapbox/OSM URL (npr. mapbox://styles/...) ali URL strežnika za " -"ploščice (npr. tile://http...)" +msgstr "pričakuje se, da bo URL Mapbox/OSM (npr. mapbox://styles/...) ali URL strežnika ploščic (npr. tile://http...)" msgid "is expected to be a number" msgstr "pričakovano je število" @@ -19890,9 +18255,8 @@ msgstr "pričakovano je število" msgid "is expected to be an integer" msgstr "pričakovano je celo število" -#, fuzzy msgid "is false" -msgstr "Je FALSE" +msgstr "je neresnično" #, python-format msgid "" @@ -19915,21 +18279,17 @@ msgstr "" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fr, ja, lv, mi, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "is not" msgstr "ni" -#, fuzzy msgid "is not null" -msgstr "Ni NULL" +msgstr "ni prazno" -#, fuzzy msgid "is null" -msgstr "Je NULL" +msgstr "je prazno" -#, fuzzy msgid "is true" -msgstr "Je TRUE" +msgstr "je resnično" msgid "key a-z" msgstr "a - ž" @@ -19953,9 +18313,8 @@ msgstr "manj kot {min} {name}" msgid "linear" msgstr "linearno" -#, fuzzy msgid "locale_key" -msgstr "Logaritemska skala" +msgstr "locale_key" msgid "log" msgstr "dnevnik" @@ -19982,9 +18341,8 @@ msgstr "metri" msgid "metric" msgstr "mera" -#, fuzzy msgid "metric type icon" -msgstr "ikona numeričnega tipa" +msgstr "ikona vrste mere" msgid "min" msgstr "min" @@ -20013,43 +18371,40 @@ msgstr "ime" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "nativeFilters must be a list" msgstr "nativeFilters mora biti seznam" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy, python-format +#, python-format msgid "nativeFilters[%(idx)s] missing required keys: %(keys)s" -msgstr "nativeFilters[%(idx)s] manjkajo zahtevani ključi: %(keys)s" +msgstr "nativeFilters[ %(idx)s] manjkajo zahtevani ključi: %(keys)s" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy, python-format +#, python-format msgid "nativeFilters[%(idx)s] must be an object" -msgstr "nativeFilters[%(idx)s] mora biti objekt" +msgstr "Vrednost nativeFilters[%(idx)s] mora biti objekt" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy, python-format +#, python-format msgid "nativeFilters[%(idx)s].filterValues must be a list" -msgstr "nativeFilters[%(idx)s].filterValues mora biti seznam" +msgstr "nativeFilters[ %(idx)s ].filterValues mora biti seznam" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy, python-format +#, python-format msgid "" "nativeFilters[%(idx)s].nativeFilterId '%(filter_id)s' does not exist on " "the dashboard" -msgstr "" -"nativeFilters[%(idx)s].nativeFilterId '%(filter_id)s' ne obstaja na " -"nadzorni plošči" +msgstr "nativeFilters[ %(idx)s].nativeFilterId ' %(filter_id)s ' ne obstaja na nadzorni plošči" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy, python-format +#, python-format msgid "nativeFilters[%(idx)s].nativeFilterId must be a non-empty string" -msgstr "nativeFilters[%(idx)s].nativeFilterId mora biti neprazen niz znakov" +msgstr "nativeFilters[ %(idx)s].nativeFilterId mora biti neprazen niz" msgid "no SQL validator is configured" msgstr "potrjevalnik SQL ni nastavljen" @@ -20058,13 +18413,11 @@ msgstr "potrjevalnik SQL ni nastavljen" msgid "no SQL validator is configured for %(engine_spec)s" msgstr "potrjevalnik SQL ni nastavljen za %(engine_spec)s" -#, fuzzy msgid "not containing" -msgstr "Ne vsebuje (NOT IN)" +msgstr "ne vsebuje" -#, fuzzy msgid "numeric" -msgstr "NUMERIC" +msgstr "številčno" msgid "numeric type icon" msgstr "ikona numeričnega tipa" @@ -20074,7 +18427,6 @@ msgstr "nvd3" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: cs, de, fr, # ja, lv, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "of" msgstr "od" @@ -20093,9 +18445,8 @@ msgstr "ali uporabite obstoječe iz panela na desni" msgid "orderby column must be populated" msgstr "stolpec za razvrščanje (orderby) mora biti izpolnjen" -#, fuzzy msgid "original" -msgstr "Izvoren" +msgstr "izvirno" msgid "overall" msgstr "skupaj" @@ -20133,9 +18484,8 @@ msgid "permalink state not found" msgstr "stanje povezave ni najdeno" #. do-not-translate -#, fuzzy msgid "pivoted_xlsx" -msgstr "Vrtilni" +msgstr "pivoted_xlsx" msgid "pixels" msgstr "piksli" @@ -20143,9 +18493,8 @@ msgstr "piksli" msgid "previous calendar month" msgstr "prejšnji koledarski mesec" -#, fuzzy msgid "previous calendar quarter" -msgstr "prejšnje koledarsko leto" +msgstr "prejšnje koledarsko četrtletje" msgid "previous calendar week" msgstr "prejšnji koledarski teden" @@ -20153,15 +18502,14 @@ msgstr "prejšnji koledarski teden" msgid "previous calendar year" msgstr "prejšnje koledarsko leto" -#, fuzzy msgid "provide authorization" -msgstr "Potrebna je avtorizacija" +msgstr "odobriti dostop" msgid "quarter" msgstr "četrtletje" msgid "queries" -msgstr "" +msgstr "poizvedbe" msgid "query" msgstr "poizvedba" @@ -20196,19 +18544,18 @@ msgstr "varnost na nivoju vrstic" msgid "running" msgstr "v teku" -#, fuzzy msgid "save" -msgstr "Shrani" +msgstr "shrani" #. do-not-translate msgid "schema1,schema2" -msgstr "" +msgstr "schema1,schema2" msgid "seconds" msgstr "sekunde" msgid "semantic layer" -msgstr "" +msgstr "semantična plast" msgid "series" msgstr "serije" @@ -20252,9 +18599,8 @@ msgstr "ustavljeno" msgid "stream" msgstr "tok" -#, fuzzy msgid "string" -msgstr "STRING" +msgstr "niz" msgid "string type icon" msgstr "ikona znakovnega tipa" @@ -20267,7 +18613,7 @@ msgstr "vsota" #. do-not-translate msgid "superset.example.com" -msgstr "" +msgstr "superset.example.com" msgid "syntax." msgstr "sintakse." @@ -20275,38 +18621,32 @@ msgstr "sintakse." msgid "tag" msgstr "oznaka" -#, fuzzy msgid "task" -msgstr "oznake" +msgstr "naloga" msgid "temporal type icon" msgstr "ikona časovnega tipa" -#, fuzzy msgid "text color" -msgstr "Ciljna barva" +msgstr "barva besedila" msgid "textarea" msgstr "področje besedila" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "the Handlebars chart documentation" -msgstr "dokumentacijo grafikona Handlebars" +msgstr "dokumentacija grafikona Handlebars" # SUPERSET UI -#, fuzzy msgid "theme" -msgstr "Čas" +msgstr "tema" -#, fuzzy msgid "timestamp" -msgstr "Prikaži časovno značko" +msgstr "časovni žig" -#, fuzzy msgid "to" -msgstr "zgoraj" +msgstr "do" msgid "top" msgstr "zgoraj" @@ -20317,13 +18657,11 @@ msgstr "razveljavitev" msgid "unknown type icon" msgstr "ikona neznanega tipa" -#, fuzzy msgid "unset" -msgstr "Junij" +msgstr "nenastavljeno" -#, fuzzy msgid "updated" -msgstr "%s posodobljeni" +msgstr "posodobljeno" msgid "" "upper percentile must be greater than 0 and less than 100. Must be higher" @@ -20335,9 +18673,8 @@ msgstr "" msgid "use latest_partition template" msgstr "uporaba predloge latest_partition" -#, fuzzy msgid "username" -msgstr "Uporabniško ime" +msgstr "uporabniško ime" msgid "value ascending" msgstr "0 - 9" @@ -20345,9 +18682,6 @@ msgstr "0 - 9" msgid "value descending" msgstr "9 - 0" -msgid "valuename" -msgstr "" - msgid "var" msgstr "var" @@ -20392,19 +18726,17 @@ msgstr "leto" #. do-not-translate msgid "your-project-1234-a1" -msgstr "" +msgstr "your-project-1234-a1" msgid "zoom area" msgstr "približaj območje" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: ca, cs, de, # es, fr, ja, lv, mi, ro, ru, sk, sr, sr_Latn, tr, uk] -#, fuzzy msgid "© Layer attribution" -msgstr "© Atribucija sloja" +msgstr "© Pripis plasti" # Machine-translated via backfill_po.py (claude-sonnet-4-6) [refs: de, sr, # sr_Latn] -#, fuzzy msgid "№" -msgstr "№" +msgstr "Št" From f5e427083e2e504eca77e3839f8eafd33f21869a Mon Sep 17 00:00:00 2001 From: Rafael Benitez Date: Wed, 2 Sep 2026 13:25:18 -0400 Subject: [PATCH 11/12] fix(native-filters): keep "Select all" count stable while searching the Value filter (#43460) Co-authored-by: Claude Opus 4.8 (1M context) --- UPDATING.md | 4 + .../src/components/Select/Select.test.tsx | 370 ++++++++++++++++++ .../src/components/Select/Select.tsx | 150 +++++-- .../src/components/Select/types.ts | 15 + .../Select/SelectFilterPlugin.test.tsx | 101 +++++ .../components/Select/SelectFilterPlugin.tsx | 1 + 6 files changed, 609 insertions(+), 32 deletions(-) diff --git a/UPDATING.md b/UPDATING.md index 98e193512553..1c582a081b4d 100644 --- a/UPDATING.md +++ b/UPDATING.md @@ -27,6 +27,10 @@ assists people when migrating to a new version. - `SAMPLES_ROW_LIMIT` is now the default for `/datasource/samples` requests without a valid explicit `per_page`, rather than a hard per-request ceiling; explicit limits are honored up to the existing global row-limit ceiling, matching `/chart/data` SAMPLES requests. - The `cockroachdb` extra (`pip install apache-superset[cockroachdb]`) now installs `sqlalchemy-cockroachdb` instead of the abandoned `cockroachdb` package, whose SQLAlchemy dialect could not be imported under SQLAlchemy 2.0. Existing environments with the old package installed should `pip uninstall cockroachdb && pip install sqlalchemy-cockroachdb` (or simply reinstall the extra) to restore CockroachDB connectivity. +### Native Value filter "Select all" always targets the whole column + +The native "Value" filter's bulk "Select all" / "Clear" controls now operate on the entire loaded set of column values regardless of any text typed into the filter's search box. Previously the "Select all (N)" count briefly flickered to the search-scoped count before settling on the full-column count, and clicking "Select all" while searching could select only the currently matching subset. Search-scoped bulk selection was never a supported feature; the count is now stable and always matches what "Select all" selects (the full column). No configuration change is required. + ### MCP tool results preserve stored string values Structured MCP tool results no longer add `` wrappers or diff --git a/superset-frontend/packages/superset-ui-core/src/components/Select/Select.test.tsx b/superset-frontend/packages/superset-ui-core/src/components/Select/Select.test.tsx index 8e71afb4b794..ebe5dc72d49a 100644 --- a/superset-frontend/packages/superset-ui-core/src/components/Select/Select.test.tsx +++ b/superset-frontend/packages/superset-ui-core/src/components/Select/Select.test.tsx @@ -17,6 +17,7 @@ * under the License. */ import { + act, createEvent, fireEvent, render, @@ -26,6 +27,7 @@ import { within, } from '@superset-ui/core/spec'; import { formatNumber } from '@superset-ui/core'; +import { Constants } from '@superset-ui/core/components'; import { Select } from '.'; type Option = { @@ -69,6 +71,38 @@ const NULL_OPTION = { label: '', value: null } as unknown as { value: number; }; +// A dedicated option set for the stableSelectAll tests, kept local so it is +// isolated from tests that mutate the shared OPTIONS array (e.g. toggling +// `disabled`). A search for "Ap" matches a strict subset (Apple, Apricot). +const STABLE_OPTIONS = [ + { label: 'Apple', value: 1 }, + { label: 'Apricot', value: 2 }, + { label: 'Banana', value: 3 }, + { label: 'Blueberry', value: 4 }, + { label: 'Cherry', value: 5 }, + { label: 'Cranberry', value: 6 }, +]; + +// A grouped option list for the stableSelectAll tests: bulk "Select all" must +// target the five leaf options, not the two value-less group headers. +const GROUPED_STABLE_OPTIONS = [ + { + label: 'Citrus', + options: [ + { label: 'Orange', value: 1 }, + { label: 'Lemon', value: 2 }, + ], + }, + { + label: 'Berries', + options: [ + { label: 'Strawberry', value: 3 }, + { label: 'Blueberry', value: 4 }, + { label: 'Raspberry', value: 5 }, + ], + }, +]; + const defaultProps = { allowClear: true, ariaLabel: ARIA_LABEL, @@ -1152,6 +1186,342 @@ test('abbreviates large numbers in bulk action buttons', async () => { expect(await screen.findByText('Select all (1.5k)')).toBeInTheDocument(); }); +// The stableSelectAll tests advance fake timers past the FAST_DEBOUNCE so the +// component's own search filter narrows `visibleOptions` (and flips +// `isSearching`) before asserting — the exact point at which the un-fixed code +// drops the badge to the search-scoped count. Asserting before that debounce +// fires (as an earlier revision did) would pass against the un-fixed code too. +test('stableSelectAll pins the "Select all" count to the full option set while searching', async () => { + jest.useFakeTimers({ advanceTimers: true }); + try { + render( + , + ); + const select = getSelect(); + userEvent.click(select); + expect( + await screen.findByText(selectAllButtonText(STABLE_OPTIONS.length)), + ).toBeInTheDocument(); + + await userEvent.type(select, 'Ap'); + act(() => { + jest.advanceTimersByTime(Constants.FAST_DEBOUNCE + 50); + }); + await waitFor(() => expect(getAllSelectOptions().length).toBe(2)); + + // Generic consumers keep the search-scoped count. + expect(screen.getByText(selectAllButtonText(2))).toBeInTheDocument(); + expect( + screen.queryByText(selectAllButtonText(STABLE_OPTIONS.length)), + ).not.toBeInTheDocument(); + } finally { + jest.useRealTimers(); + } +}); + +test('stableSelectAll selects the entire option set even while a search is active', async () => { + jest.useFakeTimers({ advanceTimers: true }); + try { + const onChange = jest.fn(); + render( + , + ); + const select = getSelect(); + userEvent.click(select); + expect(await screen.findByText(selectAllButtonText(5))).toBeInTheDocument(); + + await userEvent.type(select, 'Ap'); + act(() => { + jest.advanceTimersByTime(Constants.FAST_DEBOUNCE + 50); + }); + await waitFor(() => expect(getAllSelectOptions().length).toBe(2)); + + // The count reflects the full selectable set (5), not the 2 visible. + expect(screen.getByText(selectAllButtonText(5))).toBeInTheDocument(); + expect(screen.queryByText(selectAllButtonText(2))).not.toBeInTheDocument(); + } finally { + jest.useRealTimers(); + } +}); + +test('stableSelectAll deduplicates already-selected values when selecting the full set', async () => { + jest.useFakeTimers({ advanceTimers: true }); + try { + const onChange = jest.fn(); + // Apple (1) is already selected; the "Ap" search narrows the visible list + // to a subset while "Select all" still targets the whole set. + render( + , + ); + const select = getSelect(); + userEvent.click(select); + expect( + await screen.findByText(deselectAllButtonText(2)), + ).toBeInTheDocument(); + + await userEvent.type(select, 'Ap'); + act(() => { + jest.advanceTimersByTime(Constants.FAST_DEBOUNCE + 50); + }); + await waitFor(() => expect(getAllSelectOptions().length).toBe(2)); + + // "Clear" still reflects the full selection (2), not the visible subset (0). + expect(screen.getByText(deselectAllButtonText(2))).toBeInTheDocument(); + expect( + screen.queryByText(deselectAllButtonText(0)), + ).not.toBeInTheDocument(); + + // Clicking it removes the whole selection even though those values are not + // in the search results. + await userEvent.click(screen.getByText(deselectAllButtonText(2))); + await waitFor(() => expect(onChange).toHaveBeenCalled()); + expect(onChange.mock.calls.at(-1)?.[0]).toHaveLength(0); + } finally { + jest.useRealTimers(); + } +}); + +test('stableSelectAll "Clear" count matches the action for a selected value while searching', async () => { + jest.useFakeTimers({ advanceTimers: true }); + try { + const onChange = jest.fn(); + // The option carries a falsy value, which "Select all" skips but + // "Clear" (like the un-gated path) still removes. Pre-select and + // Banana (3); "Ap" hides both. The Clear count must equal what Clear + // removes — otherwise the label overstates the action. + render( + , + ); + const select = getSelect(); + userEvent.click(select); + + await userEvent.type(select, 'erry'); + act(() => { + jest.advanceTimersByTime(Constants.FAST_DEBOUNCE + 50); + }); + // Blueberry, Cherry, Cranberry match "erry". + await waitFor(() => expect(getAllSelectOptions().length).toBe(3)); + + // Four selected, two shown → two hidden. The overflow badge must report + // "+ 2 ...", not the sentinel-undercounted "+ 1 ...". + expect(screen.getByText('+ 2 ...')).toBeInTheDocument(); + expect(screen.queryByText('+ 1 ...')).not.toBeInTheDocument(); + } finally { + jest.useRealTimers(); + } +}); + +test('stableSelectAll counts and selects grouped options by their leaf values', async () => { + const onChange = jest.fn(); + render( +