Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions .changeset/25889-map-style-failure-notice.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
'@object-ui/plugin-map': patch
'@object-ui/i18n': patch
---

fix(plugin-map): a map whose style or tiles fail to load shows the record list with a translated notice, instead of a grey canvas under an English alert

Clause-②: no
Metadata-protocol: none

- **`@object-ui/plugin-map`:** when MapLibre reports a style or tile load failure (an intranet or proxied deployment that cannot reach the tile host, an unreachable style URL), the map view now removes the map and lists its records in its place, the same list a browser without WebGL2 already got: searchable, and each row opens the record the way its marker did. A "Try the map again" button brings the map back. The notice above the list keeps MapLibre's reason and names a remedy that exists: a view with its own map style is told to check that URL, and a view on the public default style is told to ask an administrator to set a map style for the view. It no longer says the markers are "listed in the search box" or asks for a "custom map style for production use" setting that does not exist. That notice, the WebGL2 notice, the list's label and empty text, and the "records excluded for missing or invalid coordinates" count now read the translation bundle, so a zh-CN console shows them in Chinese.
- **`@object-ui/i18n`:** eight new `element.map.*` keys in all ten packs.

What to do: nothing. A deployment-wide map style setting is not part of this change.
2 changes: 1 addition & 1 deletion scripts/sdui-manifest.record.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,6 @@
"ui/packages/types"
],
"registrySources": 922,
"registrySourcesSha256": "3fe916234f1b5346bff70f6f99322077630b851ebef81c9ae6ba8c4ac08e2063"
"registrySourcesSha256": "28bb61d046e46c8286a75a7b887d31bfc0d23220c8fd51d2fdff1d99134c932f"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ const BACKLOG: Declared[] = (
['packages/plugin-list/src/ListView.tsx', ['Bulk actions']],
[
'packages/plugin-map/src/ObjectMap.tsx',
['Locations', 'Show my location', 'Your location', 'Location details', 'Close details'],
['Show my location', 'Your location', 'Location details', 'Close details'],
],
] as Array<[string, string[]]>
).map(([file, names]) => ({ file, names, verdict: 'backlog' as const, reason: BACKLOG_REASON }));
Expand Down
8 changes: 8 additions & 0 deletions ui/packages/i18n/src/locales/ar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5148,6 +5148,14 @@ const ar = {
},
map: {
sourceUnresolved: "تعذّر تحديد مصدر بيانات هذه الخريطة",
invalidCoordinatesExcluded: "السجلات المستبعدة من الخريطة بسبب إحداثيات مفقودة أو غير صالحة: {{excluded}}",
styleFailedConfigured: "تعذّر تحميل الخريطة ({{reason}}). السجلات مدرجة أدناه؛ تحقّق من عنوان URL لنمط الخريطة المحدد في طريقة العرض هذه.",
styleFailedDefault: "تعذّر تحميل الخريطة ({{reason}}). السجلات مدرجة أدناه؛ تعذّر تحميل مربعات الخريطة العامة الافتراضية هنا، لذا اطلب من المسؤول تعيين نمط خريطة لطريقة العرض هذه.",
styleFailedUnknownReason: "تعذّر تحميل نمط الخريطة أو مربعاتها",
webgl2Unavailable: "تعذّر تحميل الخريطة (هذا المتصفح لا يوفّر WebGL2 الذي تحتاجه الخريطة). السجلات مدرجة أدناه؛ فعّل تسريع الأجهزة أو استخدم متصفحًا يدعم WebGL2 لعرض الخريطة.",
retry: "إعادة محاولة تحميل الخريطة",
listLabel: "المواقع",
listEmpty: "لا توجد مواقع لعرضها.",
},
timeline: {
sourceUnresolved: "تعذّر تحديد مصدر بيانات هذا المخطط الزمني",
Expand Down
8 changes: 8 additions & 0 deletions ui/packages/i18n/src/locales/de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4694,6 +4694,14 @@ const de = {
},
map: {
sourceUnresolved: "Die Datenquelle dieser Karte konnte nicht aufgelöst werden",
invalidCoordinatesExcluded: "Wegen fehlender oder ungültiger Koordinaten nicht auf der Karte angezeigte Datensätze: {{excluded}}",
styleFailedConfigured: "Die Karte konnte nicht geladen werden ({{reason}}). Die Datensätze sind unten aufgelistet; prüfen Sie die für diese Ansicht festgelegte Kartenstil-URL.",
styleFailedDefault: "Die Karte konnte nicht geladen werden ({{reason}}). Die Datensätze sind unten aufgelistet; die öffentlichen Standard-Kartenkacheln konnten hier nicht geladen werden. Bitten Sie Ihren Administrator, für diese Ansicht einen Kartenstil festzulegen.",
styleFailedUnknownReason: "Kartenstil oder Kacheln konnten nicht geladen werden",
webgl2Unavailable: "Die Karte konnte nicht geladen werden (dieser Browser unterstützt kein WebGL2, das die Karte benötigt). Die Datensätze sind unten aufgelistet; aktivieren Sie die Hardwarebeschleunigung oder verwenden Sie einen Browser mit WebGL2, um die Karte zu sehen.",
retry: "Karte erneut laden",
listLabel: "Orte",
listEmpty: "Keine Orte vorhanden.",
},
timeline: {
sourceUnresolved: "Die Datenquelle dieser Zeitleiste konnte nicht aufgelöst werden",
Expand Down
12 changes: 12 additions & 0 deletions ui/packages/i18n/src/locales/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5485,6 +5485,18 @@ const en = {
},
map: {
sourceUnresolved: 'This map’s data source could not be resolved',
// objectstack#25889 — the map view's own notices. Both style failures
// fill `{{reason}}` with MapLibre's message, or `styleFailedUnknownReason`
// when it gave none; the excluded count reads "Label: N" so no key needs
// a plural family.
invalidCoordinatesExcluded: 'Records excluded from the map for missing or invalid coordinates: {{excluded}}',
styleFailedConfigured: 'Map failed to load ({{reason}}). The records are listed below; check the map style URL set on this view.',
styleFailedDefault: 'Map failed to load ({{reason}}). The records are listed below; the public default map tiles could not be loaded here, so ask your administrator to set a map style for this view.',
styleFailedUnknownReason: 'the map style or tiles could not be loaded',
webgl2Unavailable: 'Map failed to load (this browser does not provide WebGL2, which the map needs). The records are listed below; turn on hardware acceleration or use a browser with WebGL2 to see the map.',
retry: 'Try the map again',
listLabel: 'Locations',
listEmpty: 'No locations to list.',
},
timeline: {
sourceUnresolved: 'This timeline’s data source could not be resolved',
Expand Down
8 changes: 8 additions & 0 deletions ui/packages/i18n/src/locales/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4807,6 +4807,14 @@ const es = {
},
map: {
sourceUnresolved: "No se pudo resolver el origen de datos de este mapa",
invalidCoordinatesExcluded: "Registros excluidos del mapa por coordenadas ausentes o no válidas: {{excluded}}",
styleFailedConfigured: "No se pudo cargar el mapa ({{reason}}). Los registros aparecen a continuación; revise la URL del estilo de mapa configurada en esta vista.",
styleFailedDefault: "No se pudo cargar el mapa ({{reason}}). Los registros aparecen a continuación; aquí no se pudieron cargar los mosaicos de mapa públicos predeterminados, así que pida a su administrador que configure un estilo de mapa para esta vista.",
styleFailedUnknownReason: "no se pudieron cargar el estilo o los mosaicos del mapa",
webgl2Unavailable: "No se pudo cargar el mapa (este navegador no admite WebGL2, que el mapa necesita). Los registros aparecen a continuación; active la aceleración por hardware o use un navegador con WebGL2 para ver el mapa.",
retry: "Reintentar el mapa",
listLabel: "Ubicaciones",
listEmpty: "No hay ubicaciones para mostrar.",
},
timeline: {
sourceUnresolved: "No se pudo resolver el origen de datos de esta línea de tiempo",
Expand Down
8 changes: 8 additions & 0 deletions ui/packages/i18n/src/locales/fr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4803,6 +4803,14 @@ const fr = {
},
map: {
sourceUnresolved: "La source de données de cette carte n’a pas pu être résolue",
invalidCoordinatesExcluded: "Enregistrements exclus de la carte (coordonnées manquantes ou invalides) : {{excluded}}",
styleFailedConfigured: "Échec du chargement de la carte ({{reason}}). Les enregistrements sont listés ci-dessous ; vérifiez l’URL du style de carte défini sur cette vue.",
styleFailedDefault: "Échec du chargement de la carte ({{reason}}). Les enregistrements sont listés ci-dessous ; les tuiles de carte publiques par défaut n’ont pas pu être chargées ici, demandez à votre administrateur de définir un style de carte pour cette vue.",
styleFailedUnknownReason: "le style ou les tuiles de la carte n’ont pas pu être chargés",
webgl2Unavailable: "Échec du chargement de la carte (ce navigateur ne prend pas en charge WebGL2, nécessaire à la carte). Les enregistrements sont listés ci-dessous ; activez l’accélération matérielle ou utilisez un navigateur compatible WebGL2 pour afficher la carte.",
retry: "Réessayer la carte",
listLabel: "Lieux",
listEmpty: "Aucun lieu à afficher.",
},
timeline: {
sourceUnresolved: "La source de données de cette chronologie n’a pas pu être résolue",
Expand Down
8 changes: 8 additions & 0 deletions ui/packages/i18n/src/locales/ja.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4695,6 +4695,14 @@ const ja = {
},
map: {
sourceUnresolved: "この地図のデータソースを解決できませんでした",
invalidCoordinatesExcluded: "座標が未設定または無効なため地図から除外されたレコード:{{excluded}}",
styleFailedConfigured: "地図を読み込めませんでした({{reason}})。レコードは下に一覧表示しています。このビューに設定された地図スタイルの URL を確認してください。",
styleFailedDefault: "地図を読み込めませんでした({{reason}})。レコードは下に一覧表示しています。公開のデフォルト地図タイルをここでは読み込めないため、このビューの地図スタイルを設定するよう管理者に依頼してください。",
styleFailedUnknownReason: "地図スタイルまたはタイルを読み込めませんでした",
webgl2Unavailable: "地図を読み込めませんでした(このブラウザーは地図に必要な WebGL2 に対応していません)。レコードは下に一覧表示しています。ハードウェアアクセラレーションを有効にするか、WebGL2 対応のブラウザーで地図を表示してください。",
retry: "地図を再読み込み",
listLabel: "場所",
listEmpty: "表示する場所はありません。",
},
timeline: {
sourceUnresolved: "このタイムラインのデータソースを解決できませんでした",
Expand Down
8 changes: 8 additions & 0 deletions ui/packages/i18n/src/locales/ko.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4692,6 +4692,14 @@ const ko = {
},
map: {
sourceUnresolved: "이 지도의 데이터 소스를 확인할 수 없습니다",
invalidCoordinatesExcluded: "좌표가 없거나 잘못되어 지도에서 제외된 레코드: {{excluded}}",
styleFailedConfigured: "지도를 불러오지 못했습니다({{reason}}). 레코드는 아래에 나열되어 있습니다. 이 보기에 설정된 지도 스타일 URL을 확인하세요.",
styleFailedDefault: "지도를 불러오지 못했습니다({{reason}}). 레코드는 아래에 나열되어 있습니다. 여기에서는 공개 기본 지도 타일을 불러올 수 없으므로 관리자에게 이 보기의 지도 스타일을 설정해 달라고 요청하세요.",
styleFailedUnknownReason: "지도 스타일 또는 타일을 불러올 수 없습니다",
webgl2Unavailable: "지도를 불러오지 못했습니다(이 브라우저는 지도에 필요한 WebGL2를 지원하지 않습니다). 레코드는 아래에 나열되어 있습니다. 하드웨어 가속을 켜거나 WebGL2를 지원하는 브라우저에서 지도를 확인하세요.",
retry: "지도 다시 시도",
listLabel: "위치",
listEmpty: "표시할 위치가 없습니다.",
},
timeline: {
sourceUnresolved: "이 타임라인의 데이터 소스를 확인할 수 없습니다",
Expand Down
8 changes: 8 additions & 0 deletions ui/packages/i18n/src/locales/pt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4802,6 +4802,14 @@ const pt = {
},
map: {
sourceUnresolved: "Não foi possível resolver a fonte de dados deste mapa",
invalidCoordinatesExcluded: "Registros excluídos do mapa por coordenadas ausentes ou inválidas: {{excluded}}",
styleFailedConfigured: "Não foi possível carregar o mapa ({{reason}}). Os registros estão listados abaixo; verifique a URL do estilo de mapa definida nesta visualização.",
styleFailedDefault: "Não foi possível carregar o mapa ({{reason}}). Os registros estão listados abaixo; não foi possível carregar aqui os blocos de mapa públicos padrão, então peça ao seu administrador que defina um estilo de mapa para esta visualização.",
styleFailedUnknownReason: "não foi possível carregar o estilo ou os blocos do mapa",
webgl2Unavailable: "Não foi possível carregar o mapa (este navegador não oferece WebGL2, necessário para o mapa). Os registros estão listados abaixo; ative a aceleração de hardware ou use um navegador com WebGL2 para ver o mapa.",
retry: "Tentar carregar o mapa novamente",
listLabel: "Locais",
listEmpty: "Nenhum local para listar.",
},
timeline: {
sourceUnresolved: "Não foi possível resolver a fonte de dados desta linha do tempo",
Expand Down
8 changes: 8 additions & 0 deletions ui/packages/i18n/src/locales/ru.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4929,6 +4929,14 @@ const ru = {
},
map: {
sourceUnresolved: "Не удалось определить источник данных этой карты",
invalidCoordinatesExcluded: "Записи, исключённые с карты из-за отсутствующих или неверных координат: {{excluded}}",
styleFailedConfigured: "Не удалось загрузить карту ({{reason}}). Записи перечислены ниже; проверьте URL стиля карты, заданный для этого представления.",
styleFailedDefault: "Не удалось загрузить карту ({{reason}}). Записи перечислены ниже; общедоступные тайлы карты по умолчанию здесь загрузить не удалось, попросите администратора задать стиль карты для этого представления.",
styleFailedUnknownReason: "не удалось загрузить стиль или тайлы карты",
webgl2Unavailable: "Не удалось загрузить карту (этот браузер не поддерживает WebGL2, необходимый для карты). Записи перечислены ниже; включите аппаратное ускорение или откройте карту в браузере с поддержкой WebGL2.",
retry: "Повторить загрузку карты",
listLabel: "Местоположения",
listEmpty: "Нет местоположений для отображения.",
},
timeline: {
sourceUnresolved: "Не удалось определить источник данных этой временной шкалы",
Expand Down
8 changes: 8 additions & 0 deletions ui/packages/i18n/src/locales/zh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4750,6 +4750,14 @@ const zh = {
},
map: {
sourceUnresolved: '无法解析此地图的数据源',
invalidCoordinatesExcluded: '因坐标缺失或无效而未显示在地图上的记录:{{excluded}}',
styleFailedConfigured: '地图加载失败({{reason}})。记录已列在下方;请检查此视图设置的地图样式 URL。',
styleFailedDefault: '地图加载失败({{reason}})。记录已列在下方;此处无法加载公共默认地图瓦片,请联系管理员为此视图设置地图样式。',
styleFailedUnknownReason: '无法加载地图样式或瓦片',
webgl2Unavailable: '地图加载失败(此浏览器不支持地图所需的 WebGL2)。记录已列在下方;请开启硬件加速,或使用支持 WebGL2 的浏览器查看地图。',
retry: '重试加载地图',
listLabel: '位置',
listEmpty: '没有可列出的位置。',
},
timeline: {
sourceUnresolved: '无法解析此时间线的数据源',
Expand Down
73 changes: 73 additions & 0 deletions ui/packages/plugin-map/src/ObjectMap.noticesI18n-25889.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/**
* ObjectUI
* Copyright (c) 2024-present ObjectStack Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

/**
* objectstack#25889 — the map's notices read the bundle: a zh-CN console shows
* them in Chinese, not as the English literals they used to be.
*
* Its own FILE because mounting `I18nProvider` registers its instance as
* react-i18next's module-global default for the rest of the file; the
* provider-less English path is pinned in
* `ObjectMap.styleFailureList-25889.test.tsx`, which never mounts one.
*/

import React from 'react';
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import { describe, it, expect, vi } from 'vitest';
import type { ObjectMapSchema } from '@object-ui/types';
import { I18nProvider } from '@object-ui/react';
import { ObjectMap } from './ObjectMap';
import './__tests__/webgl2Available';

type Slot = { children?: React.ReactNode };

vi.mock('react-map-gl/maplibre', () => ({
default: (props: Slot & { onError?: (e: { error?: Error }) => void }) => (
<div aria-label="Map">
<button
type="button"
data-testid="simulate-style-error"
onClick={() => props.onError?.({ error: new Error('Failed to fetch') })}
/>
{props.children}
</div>
),
NavigationControl: () => <div data-testid="nav-control" />,
Marker: ({ children }: Slot) => <div data-testid="map-marker">{children}</div>,
Popup: ({ children }: Slot) => <div data-testid="map-popup">{children}</div>,
}));

const records = [
{ id: 't1', title: 'Install rooftop unit', location: { lat: 47.6062, lng: -122.3321 } },
{ id: 't2', title: 'No coordinates' },
];

const schema: ObjectMapSchema = { type: 'object-map', map: { locationField: 'location', titleField: 'title' } };

describe('ObjectMap notices under zh-CN (objectstack#25889)', () => {
it('the excluded-records notice and the style-failure alert are in Chinese', async () => {
render(
<I18nProvider persistLanguage={false} config={{ defaultLanguage: 'zh-CN', detectBrowserLanguage: false }}>
<ObjectMap schema={schema} data={records} />
</I18nProvider>,
);
await screen.findByLabelText('Map');
await waitFor(() =>
expect(screen.getByText('因坐标缺失或无效而未显示在地图上的记录:1')).toBeInTheDocument(),
);

fireEvent.click(screen.getByTestId('simulate-style-error'));

const alert = await screen.findByRole('alert');
expect(alert).toHaveTextContent(
'地图加载失败(Failed to fetch)。记录已列在下方;此处无法加载公共默认地图瓦片,请联系管理员为此视图设置地图样式。',
);
expect(screen.getByTestId('map-style-retry')).toHaveTextContent('重试加载地图');
expect(screen.getByRole('list', { name: '位置' })).toBeInTheDocument();
});
});
Loading
Loading