Merged
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
52 changes: 52 additions & 0 deletions .changeset/7459-timeline-absent-date-axis-refusal.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
---
'@object-ui/plugin-timeline': minor
'@object-ui/i18n': minor
---

`ObjectTimeline` refuses an undeclared date axis instead of inventing one
(objectui#7459).

Steps ① and ② of the three-step sequence the maintainer ruled on objectui#7070
(2026-09-01, 总监批 #28). House posture, on record with that ruling:
日期轴永不虚构 — a date axis is never fabricated.

`ObjectTimeline` resolved its date axis through five declared bindings and then
closed the chain with a sixth rung that was a bare literal field name nobody
has ever declared. A name therefore ALWAYS resolved: for a view that declared
no axis, every record read a key its object does not carry, every event landed
in the "No date" bucket, and the screen read as a timeline that had been built
and simply had nothing in it.

Two changes, shipped together because neither is observable alone:

- **The renderer now refuses.** An object-bound timeline with no declared date
axis renders a diagnostic naming every binding it accepts —
`timeline.startDateField`, `timeline.dateField`, `mapping.date`, and the two
deprecated flat spellings — instead of a chart. The twin of `ObjectGantt`'s
"Gantt configuration required" screen, in the shape objectui#7070 settled.
- **The invented sixth rung is gone**, which is the only thing that makes the
refusal reachable. Added while the floor stood, it would have been dead code;
retired without the refusal, it would have produced exactly the silent
"No date" outcome the ruling rejects.

**What changes for an author.** A view that declares a date axis is completely
unaffected — all five declared spellings resolve exactly as before, and a
timeline authored from literal `items` is never refused, since its items carry
their own dates and no field name is read for them. A view that declared no
axis anywhere, and was rendering an empty-looking timeline, now says so.

⚠️ Both premises were RE-MEASURED on the current tree before anything was
edited, rather than taken from the card: the renderer had no absent-axis
refusal (against a live control term that fires in the same file), and the
floor was still present and still spelled as reported. The pairing itself is
pinned — the refusal cases go red the moment the floor returns, including one
whose records carry a column that happens to be named `date`, where a returned
floor renders a convincing timeline rather than an empty one.

Refusal is distinguished from "renders an empty timeline" by asserting the
canvas is ABSENT, not merely event-free. The component's success surface is now
named (`data-testid="timeline-canvas"`) so that distinction can be measured;
every other terminal state of the component already named itself.

Step ③ of the ruling — the `'created_at'` floors on the two plugin faces —
stays on objectui#7070 and is deliberately NOT in this change.
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/ar.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -706,6 +706,9 @@ const ar = {
unsupported: {
objectBoundGantt: "النوع \"gantt\" غير مدعوم — المخطط الزمني المرتبط بكائن يعرض أنواع التغذية ({{variants}}). يحتاج مخطط جانت إلى صفوف صريحة، لكل منها عناصر items متداخلة خاصة به، لذلك لا يؤثر محور جانت (scale) هنا.",
},
unconfigured: {
noDateAxis: "محور تواريخ المخطط الزمني مطلوب — هذا العرض لا يعلن أي حقل تاريخ، والمخطط الزمني المرتبط بكائن لا يخترع حقلاً. أعلن أحد الحقول التالية: {{fields}}. الأول هو صيغة المواصفة، والبقية أسماء مستعارة قديمة.",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/de.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -702,6 +702,9 @@ const de = {
unsupported: {
objectBoundGantt: "Nicht unterstützte Variante „gantt“ — eine objektgebundene Timeline rendert die Feed-Varianten ({{variants}}). Gantt benötigt literale Zeilen mit jeweils eigenen verschachtelten items; die Gantt-Achse (scale) hat hier daher keine Wirkung.",
},
unconfigured: {
noDateAxis: "Zeitachse für die Timeline erforderlich — diese Ansicht deklariert kein Datumsfeld, und eine objektgebundene Timeline erfindet keines. Deklarieren Sie eines von: {{fields}}. Das erste ist die Spec-Schreibweise, die übrigen sind veraltete Aliase.",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/en.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -819,6 +819,9 @@ const en = {
unsupported: {
objectBoundGantt: 'Unsupported variant "gantt" — an object-bound timeline renders the feed variants ({{variants}}). Gantt needs literal rows, each with its own nested items, so the gantt axis (scale) has no effect here.',
},
unconfigured: {
noDateAxis: 'Timeline date axis required — this view declares no date field, and an object-bound timeline will not invent one. Declare one of: {{fields}}. The first is the spec spelling; the rest are legacy aliases.',
},
},
gantt: {
column: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/es.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -706,6 +706,9 @@ const es = {
unsupported: {
objectBoundGantt: "Variante \"gantt\" no admitida: una línea de tiempo vinculada a un objeto representa las variantes de feed ({{variants}}). Gantt necesita filas literales, cada una con sus propios items anidados, por lo que el eje gantt (scale) no tiene efecto aquí.",
},
unconfigured: {
noDateAxis: "Se requiere el eje de fechas de la línea de tiempo: esta vista no declara ningún campo de fecha y una línea de tiempo vinculada a un objeto no inventa ninguno. Declare uno de: {{fields}}. El primero es la grafía de la especificación; los demás son alias heredados.",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/fr.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -702,6 +702,9 @@ const fr = {
unsupported: {
objectBoundGantt: "Variante « gantt » non prise en charge — une timeline liée à un objet affiche les variantes de flux ({{variants}}). Gantt nécessite des lignes littérales, chacune avec ses propres items imbriqués ; l'axe gantt (scale) est donc sans effet ici.",
},
unconfigured: {
noDateAxis: "Axe de dates requis pour la timeline — cette vue ne déclare aucun champ de date, et une timeline liée à un objet n'en invente pas. Déclarez l'un de : {{fields}}. Le premier est l'orthographe de la spec, les autres sont des alias hérités.",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/ja.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -702,6 +702,9 @@ const ja = {
unsupported: {
objectBoundGantt: "サポートされていないバリアント \"gantt\" — オブジェクト連動のタイムラインはフィードバリアント({{variants}})を描画します。ガントには、それぞれが入れ子の items を持つリテラル行が必要なため、ここではガント軸(scale)は効果がありません。",
},
unconfigured: {
noDateAxis: "タイムラインの日付軸が必要です — このビューは日付フィールドを宣言しておらず、オブジェクト連動のタイムラインが日付フィールドを作り出すことはありません。次のいずれかを宣言してください: {{fields}}。最初のものが spec の記法で、残りは旧来のエイリアスです。",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/ko.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -702,6 +702,9 @@ const ko = {
unsupported: {
objectBoundGantt: "지원되지 않는 variant \"gantt\" — 객체 바인딩 타임라인은 피드 variant({{variants}})를 렌더링합니다. 간트는 각각 중첩된 items를 가진 리터럴 행이 필요하므로 여기서는 간트 축(scale)이 적용되지 않습니다.",
},
unconfigured: {
noDateAxis: "타임라인 날짜 축이 필요합니다 — 이 뷰는 날짜 필드를 선언하지 않았으며, 객체 바인딩 타임라인은 날짜 필드를 지어내지 않습니다. 다음 중 하나를 선언하세요: {{fields}}. 첫 번째가 spec 표기이고 나머지는 레거시 별칭입니다.",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/pt.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -701,6 +701,9 @@ const pt = {
unsupported: {
objectBoundGantt: "Variante \"gantt\" não suportada: uma linha do tempo vinculada a um objeto renderiza as variantes de feed ({{variants}}). O gantt precisa de linhas literais, cada uma com os seus próprios items aninhados, por isso o eixo gantt (scale) não tem efeito aqui.",
},
unconfigured: {
noDateAxis: "Eixo de datas da linha do tempo necessário: esta vista não declara nenhum campo de data e uma linha do tempo vinculada a um objeto não inventa nenhum. Declare um de: {{fields}}. O primeiro é a grafia da spec; os restantes são aliases legados.",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/ru.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -708,6 +708,9 @@ const ru = {
unsupported: {
objectBoundGantt: "Неподдерживаемый вариант \"gantt\" — временная шкала, привязанная к объекту, отображает ленточные варианты ({{variants}}). Для гантта нужны литеральные строки, каждая со своим вложенным items, поэтому ось гантта (scale) здесь не действует.",
},
unconfigured: {
noDateAxis: "Требуется ось дат временной шкалы — это представление не объявляет ни одного поля даты, а временная шкала, привязанная к объекту, не придумывает его сама. Объявите одно из: {{fields}}. Первое — написание из спецификации, остальные — устаревшие псевдонимы.",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/zh.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -726,6 +726,9 @@ const zh = {
unsupported: {
objectBoundGantt: '不支持的变体 "gantt" —— 对象绑定的时间线只渲染 feed 变体({{variants}})。甘特图需要字面量行,每行自带嵌套的 items,因此此处的甘特轴(scale)不起作用。',
},
unconfigured: {
noDateAxis: '时间线需要日期轴 —— 该视图未声明任何日期字段,而对象绑定的时间线不会虚构一个。请声明以下之一:{{fields}}。第一个是 spec 写法,其余为遗留别名。',
},
},
gantt: {
column: {
Expand Down
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
Merged
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
52 changes: 52 additions & 0 deletions .changeset/7459-timeline-absent-date-axis-refusal.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
---
'@object-ui/plugin-timeline': minor
'@object-ui/i18n': minor
---

`ObjectTimeline` refuses an undeclared date axis instead of inventing one
(objectui#7459).

Steps ① and ② of the three-step sequence the maintainer ruled on objectui#7070
(2026-09-01, 总监批 #28). House posture, on record with that ruling:
日期轴永不虚构 — a date axis is never fabricated.

`ObjectTimeline` resolved its date axis through five declared bindings and then
closed the chain with a sixth rung that was a bare literal field name nobody
has ever declared. A name therefore ALWAYS resolved: for a view that declared
no axis, every record read a key its object does not carry, every event landed
in the "No date" bucket, and the screen read as a timeline that had been built
and simply had nothing in it.

Two changes, shipped together because neither is observable alone:

- **The renderer now refuses.** An object-bound timeline with no declared date
axis renders a diagnostic naming every binding it accepts —
`timeline.startDateField`, `timeline.dateField`, `mapping.date`, and the two
deprecated flat spellings — instead of a chart. The twin of `ObjectGantt`'s
"Gantt configuration required" screen, in the shape objectui#7070 settled.
- **The invented sixth rung is gone**, which is the only thing that makes the
refusal reachable. Added while the floor stood, it would have been dead code;
retired without the refusal, it would have produced exactly the silent
"No date" outcome the ruling rejects.

**What changes for an author.** A view that declares a date axis is completely
unaffected — all five declared spellings resolve exactly as before, and a
timeline authored from literal `items` is never refused, since its items carry
their own dates and no field name is read for them. A view that declared no
axis anywhere, and was rendering an empty-looking timeline, now says so.

⚠️ Both premises were RE-MEASURED on the current tree before anything was
edited, rather than taken from the card: the renderer had no absent-axis
refusal (against a live control term that fires in the same file), and the
floor was still present and still spelled as reported. The pairing itself is
pinned — the refusal cases go red the moment the floor returns, including one
whose records carry a column that happens to be named `date`, where a returned
floor renders a convincing timeline rather than an empty one.

Refusal is distinguished from "renders an empty timeline" by asserting the
canvas is ABSENT, not merely event-free. The component's success surface is now
named (`data-testid="timeline-canvas"`) so that distinction can be measured;
every other terminal state of the component already named itself.

Step ③ of the ruling — the `'created_at'` floors on the two plugin faces —
stays on objectui#7070 and is deliberately NOT in this change.
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/ar.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -706,6 +706,9 @@ const ar = {
unsupported: {
objectBoundGantt: "النوع \"gantt\" غير مدعوم — المخطط الزمني المرتبط بكائن يعرض أنواع التغذية ({{variants}}). يحتاج مخطط جانت إلى صفوف صريحة، لكل منها عناصر items متداخلة خاصة به، لذلك لا يؤثر محور جانت (scale) هنا.",
},
unconfigured: {
noDateAxis: "محور تواريخ المخطط الزمني مطلوب — هذا العرض لا يعلن أي حقل تاريخ، والمخطط الزمني المرتبط بكائن لا يخترع حقلاً. أعلن أحد الحقول التالية: {{fields}}. الأول هو صيغة المواصفة، والبقية أسماء مستعارة قديمة.",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/de.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -702,6 +702,9 @@ const de = {
unsupported: {
objectBoundGantt: "Nicht unterstützte Variante „gantt“ — eine objektgebundene Timeline rendert die Feed-Varianten ({{variants}}). Gantt benötigt literale Zeilen mit jeweils eigenen verschachtelten items; die Gantt-Achse (scale) hat hier daher keine Wirkung.",
},
unconfigured: {
noDateAxis: "Zeitachse für die Timeline erforderlich — diese Ansicht deklariert kein Datumsfeld, und eine objektgebundene Timeline erfindet keines. Deklarieren Sie eines von: {{fields}}. Das erste ist die Spec-Schreibweise, die übrigen sind veraltete Aliase.",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/en.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -819,6 +819,9 @@ const en = {
unsupported: {
objectBoundGantt: 'Unsupported variant "gantt" — an object-bound timeline renders the feed variants ({{variants}}). Gantt needs literal rows, each with its own nested items, so the gantt axis (scale) has no effect here.',
},
unconfigured: {
noDateAxis: 'Timeline date axis required — this view declares no date field, and an object-bound timeline will not invent one. Declare one of: {{fields}}. The first is the spec spelling; the rest are legacy aliases.',
},
},
gantt: {
column: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/es.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -706,6 +706,9 @@ const es = {
unsupported: {
objectBoundGantt: "Variante \"gantt\" no admitida: una línea de tiempo vinculada a un objeto representa las variantes de feed ({{variants}}). Gantt necesita filas literales, cada una con sus propios items anidados, por lo que el eje gantt (scale) no tiene efecto aquí.",
},
unconfigured: {
noDateAxis: "Se requiere el eje de fechas de la línea de tiempo: esta vista no declara ningún campo de fecha y una línea de tiempo vinculada a un objeto no inventa ninguno. Declare uno de: {{fields}}. El primero es la grafía de la especificación; los demás son alias heredados.",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/fr.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -702,6 +702,9 @@ const fr = {
unsupported: {
objectBoundGantt: "Variante « gantt » non prise en charge — une timeline liée à un objet affiche les variantes de flux ({{variants}}). Gantt nécessite des lignes littérales, chacune avec ses propres items imbriqués ; l'axe gantt (scale) est donc sans effet ici.",
},
unconfigured: {
noDateAxis: "Axe de dates requis pour la timeline — cette vue ne déclare aucun champ de date, et une timeline liée à un objet n'en invente pas. Déclarez l'un de : {{fields}}. Le premier est l'orthographe de la spec, les autres sont des alias hérités.",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/ja.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -702,6 +702,9 @@ const ja = {
unsupported: {
objectBoundGantt: "サポートされていないバリアント \"gantt\" — オブジェクト連動のタイムラインはフィードバリアント({{variants}})を描画します。ガントには、それぞれが入れ子の items を持つリテラル行が必要なため、ここではガント軸(scale)は効果がありません。",
},
unconfigured: {
noDateAxis: "タイムラインの日付軸が必要です — このビューは日付フィールドを宣言しておらず、オブジェクト連動のタイムラインが日付フィールドを作り出すことはありません。次のいずれかを宣言してください: {{fields}}。最初のものが spec の記法で、残りは旧来のエイリアスです。",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/ko.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -702,6 +702,9 @@ const ko = {
unsupported: {
objectBoundGantt: "지원되지 않는 variant \"gantt\" — 객체 바인딩 타임라인은 피드 variant({{variants}})를 렌더링합니다. 간트는 각각 중첩된 items를 가진 리터럴 행이 필요하므로 여기서는 간트 축(scale)이 적용되지 않습니다.",
},
unconfigured: {
noDateAxis: "타임라인 날짜 축이 필요합니다 — 이 뷰는 날짜 필드를 선언하지 않았으며, 객체 바인딩 타임라인은 날짜 필드를 지어내지 않습니다. 다음 중 하나를 선언하세요: {{fields}}. 첫 번째가 spec 표기이고 나머지는 레거시 별칭입니다.",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/pt.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -701,6 +701,9 @@ const pt = {
unsupported: {
objectBoundGantt: "Variante \"gantt\" não suportada: uma linha do tempo vinculada a um objeto renderiza as variantes de feed ({{variants}}). O gantt precisa de linhas literais, cada uma com os seus próprios items aninhados, por isso o eixo gantt (scale) não tem efeito aqui.",
},
unconfigured: {
noDateAxis: "Eixo de datas da linha do tempo necessário: esta vista não declara nenhum campo de data e uma linha do tempo vinculada a um objeto não inventa nenhum. Declare um de: {{fields}}. O primeiro é a grafia da spec; os restantes são aliases legados.",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/ru.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -708,6 +708,9 @@ const ru = {
unsupported: {
objectBoundGantt: "Неподдерживаемый вариант \"gantt\" — временная шкала, привязанная к объекту, отображает ленточные варианты ({{variants}}). Для гантта нужны литеральные строки, каждая со своим вложенным items, поэтому ось гантта (scale) здесь не действует.",
},
unconfigured: {
noDateAxis: "Требуется ось дат временной шкалы — это представление не объявляет ни одного поля даты, а временная шкала, привязанная к объекту, не придумывает его сама. Объявите одно из: {{fields}}. Первое — написание из спецификации, остальные — устаревшие псевдонимы.",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/zh.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -726,6 +726,9 @@ const zh = {
unsupported: {
objectBoundGantt: '不支持的变体 "gantt" —— 对象绑定的时间线只渲染 feed 变体({{variants}})。甘特图需要字面量行,每行自带嵌套的 items,因此此处的甘特轴(scale)不起作用。',
},
unconfigured: {
noDateAxis: '时间线需要日期轴 —— 该视图未声明任何日期字段,而对象绑定的时间线不会虚构一个。请声明以下之一:{{fields}}。第一个是 spec 写法,其余为遗留别名。',
},
},
gantt: {
column: {
Expand Down
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
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
52 changes: 52 additions & 0 deletions .changeset/7459-timeline-absent-date-axis-refusal.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
---
'@object-ui/plugin-timeline': minor
'@object-ui/i18n': minor
---

`ObjectTimeline` refuses an undeclared date axis instead of inventing one
(objectui#7459).

Steps ① and ② of the three-step sequence the maintainer ruled on objectui#7070
(2026-09-01, 总监批 #28). House posture, on record with that ruling:
日期轴永不虚构 — a date axis is never fabricated.

`ObjectTimeline` resolved its date axis through five declared bindings and then
closed the chain with a sixth rung that was a bare literal field name nobody
has ever declared. A name therefore ALWAYS resolved: for a view that declared
no axis, every record read a key its object does not carry, every event landed
in the "No date" bucket, and the screen read as a timeline that had been built
and simply had nothing in it.

Two changes, shipped together because neither is observable alone:

- **The renderer now refuses.** An object-bound timeline with no declared date
axis renders a diagnostic naming every binding it accepts —
`timeline.startDateField`, `timeline.dateField`, `mapping.date`, and the two
deprecated flat spellings — instead of a chart. The twin of `ObjectGantt`'s
"Gantt configuration required" screen, in the shape objectui#7070 settled.
- **The invented sixth rung is gone**, which is the only thing that makes the
refusal reachable. Added while the floor stood, it would have been dead code;
retired without the refusal, it would have produced exactly the silent
"No date" outcome the ruling rejects.

**What changes for an author.** A view that declares a date axis is completely
unaffected — all five declared spellings resolve exactly as before, and a
timeline authored from literal `items` is never refused, since its items carry
their own dates and no field name is read for them. A view that declared no
axis anywhere, and was rendering an empty-looking timeline, now says so.

⚠️ Both premises were RE-MEASURED on the current tree before anything was
edited, rather than taken from the card: the renderer had no absent-axis
refusal (against a live control term that fires in the same file), and the
floor was still present and still spelled as reported. The pairing itself is
pinned — the refusal cases go red the moment the floor returns, including one
whose records carry a column that happens to be named `date`, where a returned
floor renders a convincing timeline rather than an empty one.

Refusal is distinguished from "renders an empty timeline" by asserting the
canvas is ABSENT, not merely event-free. The component's success surface is now
named (`data-testid="timeline-canvas"`) so that distinction can be measured;
every other terminal state of the component already named itself.

Step ③ of the ruling — the `'created_at'` floors on the two plugin faces —
stays on objectui#7070 and is deliberately NOT in this change.
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/ar.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -706,6 +706,9 @@ const ar = {
unsupported: {
objectBoundGantt: "النوع \"gantt\" غير مدعوم — المخطط الزمني المرتبط بكائن يعرض أنواع التغذية ({{variants}}). يحتاج مخطط جانت إلى صفوف صريحة، لكل منها عناصر items متداخلة خاصة به، لذلك لا يؤثر محور جانت (scale) هنا.",
},
unconfigured: {
noDateAxis: "محور تواريخ المخطط الزمني مطلوب — هذا العرض لا يعلن أي حقل تاريخ، والمخطط الزمني المرتبط بكائن لا يخترع حقلاً. أعلن أحد الحقول التالية: {{fields}}. الأول هو صيغة المواصفة، والبقية أسماء مستعارة قديمة.",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/de.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -702,6 +702,9 @@ const de = {
unsupported: {
objectBoundGantt: "Nicht unterstützte Variante „gantt“ — eine objektgebundene Timeline rendert die Feed-Varianten ({{variants}}). Gantt benötigt literale Zeilen mit jeweils eigenen verschachtelten items; die Gantt-Achse (scale) hat hier daher keine Wirkung.",
},
unconfigured: {
noDateAxis: "Zeitachse für die Timeline erforderlich — diese Ansicht deklariert kein Datumsfeld, und eine objektgebundene Timeline erfindet keines. Deklarieren Sie eines von: {{fields}}. Das erste ist die Spec-Schreibweise, die übrigen sind veraltete Aliase.",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/en.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -819,6 +819,9 @@ const en = {
unsupported: {
objectBoundGantt: 'Unsupported variant "gantt" — an object-bound timeline renders the feed variants ({{variants}}). Gantt needs literal rows, each with its own nested items, so the gantt axis (scale) has no effect here.',
},
unconfigured: {
noDateAxis: 'Timeline date axis required — this view declares no date field, and an object-bound timeline will not invent one. Declare one of: {{fields}}. The first is the spec spelling; the rest are legacy aliases.',
},
},
gantt: {
column: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/es.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -706,6 +706,9 @@ const es = {
unsupported: {
objectBoundGantt: "Variante \"gantt\" no admitida: una línea de tiempo vinculada a un objeto representa las variantes de feed ({{variants}}). Gantt necesita filas literales, cada una con sus propios items anidados, por lo que el eje gantt (scale) no tiene efecto aquí.",
},
unconfigured: {
noDateAxis: "Se requiere el eje de fechas de la línea de tiempo: esta vista no declara ningún campo de fecha y una línea de tiempo vinculada a un objeto no inventa ninguno. Declare uno de: {{fields}}. El primero es la grafía de la especificación; los demás son alias heredados.",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/fr.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -702,6 +702,9 @@ const fr = {
unsupported: {
objectBoundGantt: "Variante « gantt » non prise en charge — une timeline liée à un objet affiche les variantes de flux ({{variants}}). Gantt nécessite des lignes littérales, chacune avec ses propres items imbriqués ; l'axe gantt (scale) est donc sans effet ici.",
},
unconfigured: {
noDateAxis: "Axe de dates requis pour la timeline — cette vue ne déclare aucun champ de date, et une timeline liée à un objet n'en invente pas. Déclarez l'un de : {{fields}}. Le premier est l'orthographe de la spec, les autres sont des alias hérités.",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/ja.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -702,6 +702,9 @@ const ja = {
unsupported: {
objectBoundGantt: "サポートされていないバリアント \"gantt\" — オブジェクト連動のタイムラインはフィードバリアント({{variants}})を描画します。ガントには、それぞれが入れ子の items を持つリテラル行が必要なため、ここではガント軸(scale)は効果がありません。",
},
unconfigured: {
noDateAxis: "タイムラインの日付軸が必要です — このビューは日付フィールドを宣言しておらず、オブジェクト連動のタイムラインが日付フィールドを作り出すことはありません。次のいずれかを宣言してください: {{fields}}。最初のものが spec の記法で、残りは旧来のエイリアスです。",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/ko.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -702,6 +702,9 @@ const ko = {
unsupported: {
objectBoundGantt: "지원되지 않는 variant \"gantt\" — 객체 바인딩 타임라인은 피드 variant({{variants}})를 렌더링합니다. 간트는 각각 중첩된 items를 가진 리터럴 행이 필요하므로 여기서는 간트 축(scale)이 적용되지 않습니다.",
},
unconfigured: {
noDateAxis: "타임라인 날짜 축이 필요합니다 — 이 뷰는 날짜 필드를 선언하지 않았으며, 객체 바인딩 타임라인은 날짜 필드를 지어내지 않습니다. 다음 중 하나를 선언하세요: {{fields}}. 첫 번째가 spec 표기이고 나머지는 레거시 별칭입니다.",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/pt.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -701,6 +701,9 @@ const pt = {
unsupported: {
objectBoundGantt: "Variante \"gantt\" não suportada: uma linha do tempo vinculada a um objeto renderiza as variantes de feed ({{variants}}). O gantt precisa de linhas literais, cada uma com os seus próprios items aninhados, por isso o eixo gantt (scale) não tem efeito aqui.",
},
unconfigured: {
noDateAxis: "Eixo de datas da linha do tempo necessário: esta vista não declara nenhum campo de data e uma linha do tempo vinculada a um objeto não inventa nenhum. Declare um de: {{fields}}. O primeiro é a grafia da spec; os restantes são aliases legados.",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/ru.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -708,6 +708,9 @@ const ru = {
unsupported: {
objectBoundGantt: "Неподдерживаемый вариант \"gantt\" — временная шкала, привязанная к объекту, отображает ленточные варианты ({{variants}}). Для гантта нужны литеральные строки, каждая со своим вложенным items, поэтому ось гантта (scale) здесь не действует.",
},
unconfigured: {
noDateAxis: "Требуется ось дат временной шкалы — это представление не объявляет ни одного поля даты, а временная шкала, привязанная к объекту, не придумывает его сама. Объявите одно из: {{fields}}. Первое — написание из спецификации, остальные — устаревшие псевдонимы.",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/zh.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -726,6 +726,9 @@ const zh = {
unsupported: {
objectBoundGantt: '不支持的变体 "gantt" —— 对象绑定的时间线只渲染 feed 变体({{variants}})。甘特图需要字面量行,每行自带嵌套的 items,因此此处的甘特轴(scale)不起作用。',
},
unconfigured: {
noDateAxis: '时间线需要日期轴 —— 该视图未声明任何日期字段,而对象绑定的时间线不会虚构一个。请声明以下之一:{{fields}}。第一个是 spec 写法,其余为遗留别名。',
},
},
gantt: {
column: {
Expand Down
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
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
52 changes: 52 additions & 0 deletions .changeset/7459-timeline-absent-date-axis-refusal.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
---
'@object-ui/plugin-timeline': minor
'@object-ui/i18n': minor
---

`ObjectTimeline` refuses an undeclared date axis instead of inventing one
(objectui#7459).

Steps ① and ② of the three-step sequence the maintainer ruled on objectui#7070
(2026-09-01, 总监批 #28). House posture, on record with that ruling:
日期轴永不虚构 — a date axis is never fabricated.

`ObjectTimeline` resolved its date axis through five declared bindings and then
closed the chain with a sixth rung that was a bare literal field name nobody
has ever declared. A name therefore ALWAYS resolved: for a view that declared
no axis, every record read a key its object does not carry, every event landed
in the "No date" bucket, and the screen read as a timeline that had been built
and simply had nothing in it.

Two changes, shipped together because neither is observable alone:

- **The renderer now refuses.** An object-bound timeline with no declared date
axis renders a diagnostic naming every binding it accepts —
`timeline.startDateField`, `timeline.dateField`, `mapping.date`, and the two
deprecated flat spellings — instead of a chart. The twin of `ObjectGantt`'s
"Gantt configuration required" screen, in the shape objectui#7070 settled.
- **The invented sixth rung is gone**, which is the only thing that makes the
refusal reachable. Added while the floor stood, it would have been dead code;
retired without the refusal, it would have produced exactly the silent
"No date" outcome the ruling rejects.

**What changes for an author.** A view that declares a date axis is completely
unaffected — all five declared spellings resolve exactly as before, and a
timeline authored from literal `items` is never refused, since its items carry
their own dates and no field name is read for them. A view that declared no
axis anywhere, and was rendering an empty-looking timeline, now says so.

⚠️ Both premises were RE-MEASURED on the current tree before anything was
edited, rather than taken from the card: the renderer had no absent-axis
refusal (against a live control term that fires in the same file), and the
floor was still present and still spelled as reported. The pairing itself is
pinned — the refusal cases go red the moment the floor returns, including one
whose records carry a column that happens to be named `date`, where a returned
floor renders a convincing timeline rather than an empty one.

Refusal is distinguished from "renders an empty timeline" by asserting the
canvas is ABSENT, not merely event-free. The component's success surface is now
named (`data-testid="timeline-canvas"`) so that distinction can be measured;
every other terminal state of the component already named itself.

Step ③ of the ruling — the `'created_at'` floors on the two plugin faces —
stays on objectui#7070 and is deliberately NOT in this change.
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/ar.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -706,6 +706,9 @@ const ar = {
unsupported: {
objectBoundGantt: "النوع \"gantt\" غير مدعوم — المخطط الزمني المرتبط بكائن يعرض أنواع التغذية ({{variants}}). يحتاج مخطط جانت إلى صفوف صريحة، لكل منها عناصر items متداخلة خاصة به، لذلك لا يؤثر محور جانت (scale) هنا.",
},
unconfigured: {
noDateAxis: "محور تواريخ المخطط الزمني مطلوب — هذا العرض لا يعلن أي حقل تاريخ، والمخطط الزمني المرتبط بكائن لا يخترع حقلاً. أعلن أحد الحقول التالية: {{fields}}. الأول هو صيغة المواصفة، والبقية أسماء مستعارة قديمة.",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/de.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -702,6 +702,9 @@ const de = {
unsupported: {
objectBoundGantt: "Nicht unterstützte Variante „gantt“ — eine objektgebundene Timeline rendert die Feed-Varianten ({{variants}}). Gantt benötigt literale Zeilen mit jeweils eigenen verschachtelten items; die Gantt-Achse (scale) hat hier daher keine Wirkung.",
},
unconfigured: {
noDateAxis: "Zeitachse für die Timeline erforderlich — diese Ansicht deklariert kein Datumsfeld, und eine objektgebundene Timeline erfindet keines. Deklarieren Sie eines von: {{fields}}. Das erste ist die Spec-Schreibweise, die übrigen sind veraltete Aliase.",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/en.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -819,6 +819,9 @@ const en = {
unsupported: {
objectBoundGantt: 'Unsupported variant "gantt" — an object-bound timeline renders the feed variants ({{variants}}). Gantt needs literal rows, each with its own nested items, so the gantt axis (scale) has no effect here.',
},
unconfigured: {
noDateAxis: 'Timeline date axis required — this view declares no date field, and an object-bound timeline will not invent one. Declare one of: {{fields}}. The first is the spec spelling; the rest are legacy aliases.',
},
},
gantt: {
column: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/es.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -706,6 +706,9 @@ const es = {
unsupported: {
objectBoundGantt: "Variante \"gantt\" no admitida: una línea de tiempo vinculada a un objeto representa las variantes de feed ({{variants}}). Gantt necesita filas literales, cada una con sus propios items anidados, por lo que el eje gantt (scale) no tiene efecto aquí.",
},
unconfigured: {
noDateAxis: "Se requiere el eje de fechas de la línea de tiempo: esta vista no declara ningún campo de fecha y una línea de tiempo vinculada a un objeto no inventa ninguno. Declare uno de: {{fields}}. El primero es la grafía de la especificación; los demás son alias heredados.",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/fr.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -702,6 +702,9 @@ const fr = {
unsupported: {
objectBoundGantt: "Variante « gantt » non prise en charge — une timeline liée à un objet affiche les variantes de flux ({{variants}}). Gantt nécessite des lignes littérales, chacune avec ses propres items imbriqués ; l'axe gantt (scale) est donc sans effet ici.",
},
unconfigured: {
noDateAxis: "Axe de dates requis pour la timeline — cette vue ne déclare aucun champ de date, et une timeline liée à un objet n'en invente pas. Déclarez l'un de : {{fields}}. Le premier est l'orthographe de la spec, les autres sont des alias hérités.",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/ja.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -702,6 +702,9 @@ const ja = {
unsupported: {
objectBoundGantt: "サポートされていないバリアント \"gantt\" — オブジェクト連動のタイムラインはフィードバリアント({{variants}})を描画します。ガントには、それぞれが入れ子の items を持つリテラル行が必要なため、ここではガント軸(scale)は効果がありません。",
},
unconfigured: {
noDateAxis: "タイムラインの日付軸が必要です — このビューは日付フィールドを宣言しておらず、オブジェクト連動のタイムラインが日付フィールドを作り出すことはありません。次のいずれかを宣言してください: {{fields}}。最初のものが spec の記法で、残りは旧来のエイリアスです。",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/ko.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -702,6 +702,9 @@ const ko = {
unsupported: {
objectBoundGantt: "지원되지 않는 variant \"gantt\" — 객체 바인딩 타임라인은 피드 variant({{variants}})를 렌더링합니다. 간트는 각각 중첩된 items를 가진 리터럴 행이 필요하므로 여기서는 간트 축(scale)이 적용되지 않습니다.",
},
unconfigured: {
noDateAxis: "타임라인 날짜 축이 필요합니다 — 이 뷰는 날짜 필드를 선언하지 않았으며, 객체 바인딩 타임라인은 날짜 필드를 지어내지 않습니다. 다음 중 하나를 선언하세요: {{fields}}. 첫 번째가 spec 표기이고 나머지는 레거시 별칭입니다.",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/pt.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -701,6 +701,9 @@ const pt = {
unsupported: {
objectBoundGantt: "Variante \"gantt\" não suportada: uma linha do tempo vinculada a um objeto renderiza as variantes de feed ({{variants}}). O gantt precisa de linhas literais, cada uma com os seus próprios items aninhados, por isso o eixo gantt (scale) não tem efeito aqui.",
},
unconfigured: {
noDateAxis: "Eixo de datas da linha do tempo necessário: esta vista não declara nenhum campo de data e uma linha do tempo vinculada a um objeto não inventa nenhum. Declare um de: {{fields}}. O primeiro é a grafia da spec; os restantes são aliases legados.",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/ru.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -708,6 +708,9 @@ const ru = {
unsupported: {
objectBoundGantt: "Неподдерживаемый вариант \"gantt\" — временная шкала, привязанная к объекту, отображает ленточные варианты ({{variants}}). Для гантта нужны литеральные строки, каждая со своим вложенным items, поэтому ось гантта (scale) здесь не действует.",
},
unconfigured: {
noDateAxis: "Требуется ось дат временной шкалы — это представление не объявляет ни одного поля даты, а временная шкала, привязанная к объекту, не придумывает его сама. Объявите одно из: {{fields}}. Первое — написание из спецификации, остальные — устаревшие псевдонимы.",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/zh.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -726,6 +726,9 @@ const zh = {
unsupported: {
objectBoundGantt: '不支持的变体 "gantt" —— 对象绑定的时间线只渲染 feed 变体({{variants}})。甘特图需要字面量行,每行自带嵌套的 items,因此此处的甘特轴(scale)不起作用。',
},
unconfigured: {
noDateAxis: '时间线需要日期轴 —— 该视图未声明任何日期字段,而对象绑定的时间线不会虚构一个。请声明以下之一:{{fields}}。第一个是 spec 写法,其余为遗留别名。',
},
},
gantt: {
column: {
Expand Down
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
Merged
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
52 changes: 52 additions & 0 deletions .changeset/7459-timeline-absent-date-axis-refusal.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
---
'@object-ui/plugin-timeline': minor
'@object-ui/i18n': minor
---

`ObjectTimeline` refuses an undeclared date axis instead of inventing one
(objectui#7459).

Steps ① and ② of the three-step sequence the maintainer ruled on objectui#7070
(2026-09-01, 总监批 #28). House posture, on record with that ruling:
日期轴永不虚构 — a date axis is never fabricated.

`ObjectTimeline` resolved its date axis through five declared bindings and then
closed the chain with a sixth rung that was a bare literal field name nobody
has ever declared. A name therefore ALWAYS resolved: for a view that declared
no axis, every record read a key its object does not carry, every event landed
in the "No date" bucket, and the screen read as a timeline that had been built
and simply had nothing in it.

Two changes, shipped together because neither is observable alone:

- **The renderer now refuses.** An object-bound timeline with no declared date
axis renders a diagnostic naming every binding it accepts —
`timeline.startDateField`, `timeline.dateField`, `mapping.date`, and the two
deprecated flat spellings — instead of a chart. The twin of `ObjectGantt`'s
"Gantt configuration required" screen, in the shape objectui#7070 settled.
- **The invented sixth rung is gone**, which is the only thing that makes the
refusal reachable. Added while the floor stood, it would have been dead code;
retired without the refusal, it would have produced exactly the silent
"No date" outcome the ruling rejects.

**What changes for an author.** A view that declares a date axis is completely
unaffected — all five declared spellings resolve exactly as before, and a
timeline authored from literal `items` is never refused, since its items carry
their own dates and no field name is read for them. A view that declared no
axis anywhere, and was rendering an empty-looking timeline, now says so.

⚠️ Both premises were RE-MEASURED on the current tree before anything was
edited, rather than taken from the card: the renderer had no absent-axis
refusal (against a live control term that fires in the same file), and the
floor was still present and still spelled as reported. The pairing itself is
pinned — the refusal cases go red the moment the floor returns, including one
whose records carry a column that happens to be named `date`, where a returned
floor renders a convincing timeline rather than an empty one.

Refusal is distinguished from "renders an empty timeline" by asserting the
canvas is ABSENT, not merely event-free. The component's success surface is now
named (`data-testid="timeline-canvas"`) so that distinction can be measured;
every other terminal state of the component already named itself.

Step ③ of the ruling — the `'created_at'` floors on the two plugin faces —
stays on objectui#7070 and is deliberately NOT in this change.
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/ar.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -706,6 +706,9 @@ const ar = {
unsupported: {
objectBoundGantt: "النوع \"gantt\" غير مدعوم — المخطط الزمني المرتبط بكائن يعرض أنواع التغذية ({{variants}}). يحتاج مخطط جانت إلى صفوف صريحة، لكل منها عناصر items متداخلة خاصة به، لذلك لا يؤثر محور جانت (scale) هنا.",
},
unconfigured: {
noDateAxis: "محور تواريخ المخطط الزمني مطلوب — هذا العرض لا يعلن أي حقل تاريخ، والمخطط الزمني المرتبط بكائن لا يخترع حقلاً. أعلن أحد الحقول التالية: {{fields}}. الأول هو صيغة المواصفة، والبقية أسماء مستعارة قديمة.",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/de.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -702,6 +702,9 @@ const de = {
unsupported: {
objectBoundGantt: "Nicht unterstützte Variante „gantt“ — eine objektgebundene Timeline rendert die Feed-Varianten ({{variants}}). Gantt benötigt literale Zeilen mit jeweils eigenen verschachtelten items; die Gantt-Achse (scale) hat hier daher keine Wirkung.",
},
unconfigured: {
noDateAxis: "Zeitachse für die Timeline erforderlich — diese Ansicht deklariert kein Datumsfeld, und eine objektgebundene Timeline erfindet keines. Deklarieren Sie eines von: {{fields}}. Das erste ist die Spec-Schreibweise, die übrigen sind veraltete Aliase.",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/en.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -819,6 +819,9 @@ const en = {
unsupported: {
objectBoundGantt: 'Unsupported variant "gantt" — an object-bound timeline renders the feed variants ({{variants}}). Gantt needs literal rows, each with its own nested items, so the gantt axis (scale) has no effect here.',
},
unconfigured: {
noDateAxis: 'Timeline date axis required — this view declares no date field, and an object-bound timeline will not invent one. Declare one of: {{fields}}. The first is the spec spelling; the rest are legacy aliases.',
},
},
gantt: {
column: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/es.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -706,6 +706,9 @@ const es = {
unsupported: {
objectBoundGantt: "Variante \"gantt\" no admitida: una línea de tiempo vinculada a un objeto representa las variantes de feed ({{variants}}). Gantt necesita filas literales, cada una con sus propios items anidados, por lo que el eje gantt (scale) no tiene efecto aquí.",
},
unconfigured: {
noDateAxis: "Se requiere el eje de fechas de la línea de tiempo: esta vista no declara ningún campo de fecha y una línea de tiempo vinculada a un objeto no inventa ninguno. Declare uno de: {{fields}}. El primero es la grafía de la especificación; los demás son alias heredados.",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/fr.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -702,6 +702,9 @@ const fr = {
unsupported: {
objectBoundGantt: "Variante « gantt » non prise en charge — une timeline liée à un objet affiche les variantes de flux ({{variants}}). Gantt nécessite des lignes littérales, chacune avec ses propres items imbriqués ; l'axe gantt (scale) est donc sans effet ici.",
},
unconfigured: {
noDateAxis: "Axe de dates requis pour la timeline — cette vue ne déclare aucun champ de date, et une timeline liée à un objet n'en invente pas. Déclarez l'un de : {{fields}}. Le premier est l'orthographe de la spec, les autres sont des alias hérités.",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/ja.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -702,6 +702,9 @@ const ja = {
unsupported: {
objectBoundGantt: "サポートされていないバリアント \"gantt\" — オブジェクト連動のタイムラインはフィードバリアント({{variants}})を描画します。ガントには、それぞれが入れ子の items を持つリテラル行が必要なため、ここではガント軸(scale)は効果がありません。",
},
unconfigured: {
noDateAxis: "タイムラインの日付軸が必要です — このビューは日付フィールドを宣言しておらず、オブジェクト連動のタイムラインが日付フィールドを作り出すことはありません。次のいずれかを宣言してください: {{fields}}。最初のものが spec の記法で、残りは旧来のエイリアスです。",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/ko.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -702,6 +702,9 @@ const ko = {
unsupported: {
objectBoundGantt: "지원되지 않는 variant \"gantt\" — 객체 바인딩 타임라인은 피드 variant({{variants}})를 렌더링합니다. 간트는 각각 중첩된 items를 가진 리터럴 행이 필요하므로 여기서는 간트 축(scale)이 적용되지 않습니다.",
},
unconfigured: {
noDateAxis: "타임라인 날짜 축이 필요합니다 — 이 뷰는 날짜 필드를 선언하지 않았으며, 객체 바인딩 타임라인은 날짜 필드를 지어내지 않습니다. 다음 중 하나를 선언하세요: {{fields}}. 첫 번째가 spec 표기이고 나머지는 레거시 별칭입니다.",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/pt.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -701,6 +701,9 @@ const pt = {
unsupported: {
objectBoundGantt: "Variante \"gantt\" não suportada: uma linha do tempo vinculada a um objeto renderiza as variantes de feed ({{variants}}). O gantt precisa de linhas literais, cada uma com os seus próprios items aninhados, por isso o eixo gantt (scale) não tem efeito aqui.",
},
unconfigured: {
noDateAxis: "Eixo de datas da linha do tempo necessário: esta vista não declara nenhum campo de data e uma linha do tempo vinculada a um objeto não inventa nenhum. Declare um de: {{fields}}. O primeiro é a grafia da spec; os restantes são aliases legados.",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/ru.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -708,6 +708,9 @@ const ru = {
unsupported: {
objectBoundGantt: "Неподдерживаемый вариант \"gantt\" — временная шкала, привязанная к объекту, отображает ленточные варианты ({{variants}}). Для гантта нужны литеральные строки, каждая со своим вложенным items, поэтому ось гантта (scale) здесь не действует.",
},
unconfigured: {
noDateAxis: "Требуется ось дат временной шкалы — это представление не объявляет ни одного поля даты, а временная шкала, привязанная к объекту, не придумывает его сама. Объявите одно из: {{fields}}. Первое — написание из спецификации, остальные — устаревшие псевдонимы.",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/zh.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -726,6 +726,9 @@ const zh = {
unsupported: {
objectBoundGantt: '不支持的变体 "gantt" —— 对象绑定的时间线只渲染 feed 变体({{variants}})。甘特图需要字面量行,每行自带嵌套的 items,因此此处的甘特轴(scale)不起作用。',
},
unconfigured: {
noDateAxis: '时间线需要日期轴 —— 该视图未声明任何日期字段,而对象绑定的时间线不会虚构一个。请声明以下之一:{{fields}}。第一个是 spec 写法,其余为遗留别名。',
},
},
gantt: {
column: {
Expand Down
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
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
52 changes: 52 additions & 0 deletions .changeset/7459-timeline-absent-date-axis-refusal.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
---
'@object-ui/plugin-timeline': minor
'@object-ui/i18n': minor
---

`ObjectTimeline` refuses an undeclared date axis instead of inventing one
(objectui#7459).

Steps ① and ② of the three-step sequence the maintainer ruled on objectui#7070
(2026-09-01, 总监批 #28). House posture, on record with that ruling:
日期轴永不虚构 — a date axis is never fabricated.

`ObjectTimeline` resolved its date axis through five declared bindings and then
closed the chain with a sixth rung that was a bare literal field name nobody
has ever declared. A name therefore ALWAYS resolved: for a view that declared
no axis, every record read a key its object does not carry, every event landed
in the "No date" bucket, and the screen read as a timeline that had been built
and simply had nothing in it.

Two changes, shipped together because neither is observable alone:

- **The renderer now refuses.** An object-bound timeline with no declared date
axis renders a diagnostic naming every binding it accepts —
`timeline.startDateField`, `timeline.dateField`, `mapping.date`, and the two
deprecated flat spellings — instead of a chart. The twin of `ObjectGantt`'s
"Gantt configuration required" screen, in the shape objectui#7070 settled.
- **The invented sixth rung is gone**, which is the only thing that makes the
refusal reachable. Added while the floor stood, it would have been dead code;
retired without the refusal, it would have produced exactly the silent
"No date" outcome the ruling rejects.

**What changes for an author.** A view that declares a date axis is completely
unaffected — all five declared spellings resolve exactly as before, and a
timeline authored from literal `items` is never refused, since its items carry
their own dates and no field name is read for them. A view that declared no
axis anywhere, and was rendering an empty-looking timeline, now says so.

⚠️ Both premises were RE-MEASURED on the current tree before anything was
edited, rather than taken from the card: the renderer had no absent-axis
refusal (against a live control term that fires in the same file), and the
floor was still present and still spelled as reported. The pairing itself is
pinned — the refusal cases go red the moment the floor returns, including one
whose records carry a column that happens to be named `date`, where a returned
floor renders a convincing timeline rather than an empty one.

Refusal is distinguished from "renders an empty timeline" by asserting the
canvas is ABSENT, not merely event-free. The component's success surface is now
named (`data-testid="timeline-canvas"`) so that distinction can be measured;
every other terminal state of the component already named itself.

Step ③ of the ruling — the `'created_at'` floors on the two plugin faces —
stays on objectui#7070 and is deliberately NOT in this change.
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/ar.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -706,6 +706,9 @@ const ar = {
unsupported: {
objectBoundGantt: "النوع \"gantt\" غير مدعوم — المخطط الزمني المرتبط بكائن يعرض أنواع التغذية ({{variants}}). يحتاج مخطط جانت إلى صفوف صريحة، لكل منها عناصر items متداخلة خاصة به، لذلك لا يؤثر محور جانت (scale) هنا.",
},
unconfigured: {
noDateAxis: "محور تواريخ المخطط الزمني مطلوب — هذا العرض لا يعلن أي حقل تاريخ، والمخطط الزمني المرتبط بكائن لا يخترع حقلاً. أعلن أحد الحقول التالية: {{fields}}. الأول هو صيغة المواصفة، والبقية أسماء مستعارة قديمة.",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/de.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -702,6 +702,9 @@ const de = {
unsupported: {
objectBoundGantt: "Nicht unterstützte Variante „gantt“ — eine objektgebundene Timeline rendert die Feed-Varianten ({{variants}}). Gantt benötigt literale Zeilen mit jeweils eigenen verschachtelten items; die Gantt-Achse (scale) hat hier daher keine Wirkung.",
},
unconfigured: {
noDateAxis: "Zeitachse für die Timeline erforderlich — diese Ansicht deklariert kein Datumsfeld, und eine objektgebundene Timeline erfindet keines. Deklarieren Sie eines von: {{fields}}. Das erste ist die Spec-Schreibweise, die übrigen sind veraltete Aliase.",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/en.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -819,6 +819,9 @@ const en = {
unsupported: {
objectBoundGantt: 'Unsupported variant "gantt" — an object-bound timeline renders the feed variants ({{variants}}). Gantt needs literal rows, each with its own nested items, so the gantt axis (scale) has no effect here.',
},
unconfigured: {
noDateAxis: 'Timeline date axis required — this view declares no date field, and an object-bound timeline will not invent one. Declare one of: {{fields}}. The first is the spec spelling; the rest are legacy aliases.',
},
},
gantt: {
column: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/es.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -706,6 +706,9 @@ const es = {
unsupported: {
objectBoundGantt: "Variante \"gantt\" no admitida: una línea de tiempo vinculada a un objeto representa las variantes de feed ({{variants}}). Gantt necesita filas literales, cada una con sus propios items anidados, por lo que el eje gantt (scale) no tiene efecto aquí.",
},
unconfigured: {
noDateAxis: "Se requiere el eje de fechas de la línea de tiempo: esta vista no declara ningún campo de fecha y una línea de tiempo vinculada a un objeto no inventa ninguno. Declare uno de: {{fields}}. El primero es la grafía de la especificación; los demás son alias heredados.",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/fr.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -702,6 +702,9 @@ const fr = {
unsupported: {
objectBoundGantt: "Variante « gantt » non prise en charge — une timeline liée à un objet affiche les variantes de flux ({{variants}}). Gantt nécessite des lignes littérales, chacune avec ses propres items imbriqués ; l'axe gantt (scale) est donc sans effet ici.",
},
unconfigured: {
noDateAxis: "Axe de dates requis pour la timeline — cette vue ne déclare aucun champ de date, et une timeline liée à un objet n'en invente pas. Déclarez l'un de : {{fields}}. Le premier est l'orthographe de la spec, les autres sont des alias hérités.",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/ja.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -702,6 +702,9 @@ const ja = {
unsupported: {
objectBoundGantt: "サポートされていないバリアント \"gantt\" — オブジェクト連動のタイムラインはフィードバリアント({{variants}})を描画します。ガントには、それぞれが入れ子の items を持つリテラル行が必要なため、ここではガント軸(scale)は効果がありません。",
},
unconfigured: {
noDateAxis: "タイムラインの日付軸が必要です — このビューは日付フィールドを宣言しておらず、オブジェクト連動のタイムラインが日付フィールドを作り出すことはありません。次のいずれかを宣言してください: {{fields}}。最初のものが spec の記法で、残りは旧来のエイリアスです。",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/ko.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -702,6 +702,9 @@ const ko = {
unsupported: {
objectBoundGantt: "지원되지 않는 variant \"gantt\" — 객체 바인딩 타임라인은 피드 variant({{variants}})를 렌더링합니다. 간트는 각각 중첩된 items를 가진 리터럴 행이 필요하므로 여기서는 간트 축(scale)이 적용되지 않습니다.",
},
unconfigured: {
noDateAxis: "타임라인 날짜 축이 필요합니다 — 이 뷰는 날짜 필드를 선언하지 않았으며, 객체 바인딩 타임라인은 날짜 필드를 지어내지 않습니다. 다음 중 하나를 선언하세요: {{fields}}. 첫 번째가 spec 표기이고 나머지는 레거시 별칭입니다.",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/pt.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -701,6 +701,9 @@ const pt = {
unsupported: {
objectBoundGantt: "Variante \"gantt\" não suportada: uma linha do tempo vinculada a um objeto renderiza as variantes de feed ({{variants}}). O gantt precisa de linhas literais, cada uma com os seus próprios items aninhados, por isso o eixo gantt (scale) não tem efeito aqui.",
},
unconfigured: {
noDateAxis: "Eixo de datas da linha do tempo necessário: esta vista não declara nenhum campo de data e uma linha do tempo vinculada a um objeto não inventa nenhum. Declare um de: {{fields}}. O primeiro é a grafia da spec; os restantes são aliases legados.",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/ru.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -708,6 +708,9 @@ const ru = {
unsupported: {
objectBoundGantt: "Неподдерживаемый вариант \"gantt\" — временная шкала, привязанная к объекту, отображает ленточные варианты ({{variants}}). Для гантта нужны литеральные строки, каждая со своим вложенным items, поэтому ось гантта (scale) здесь не действует.",
},
unconfigured: {
noDateAxis: "Требуется ось дат временной шкалы — это представление не объявляет ни одного поля даты, а временная шкала, привязанная к объекту, не придумывает его сама. Объявите одно из: {{fields}}. Первое — написание из спецификации, остальные — устаревшие псевдонимы.",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/zh.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -726,6 +726,9 @@ const zh = {
unsupported: {
objectBoundGantt: '不支持的变体 "gantt" —— 对象绑定的时间线只渲染 feed 变体({{variants}})。甘特图需要字面量行,每行自带嵌套的 items,因此此处的甘特轴(scale)不起作用。',
},
unconfigured: {
noDateAxis: '时间线需要日期轴 —— 该视图未声明任何日期字段,而对象绑定的时间线不会虚构一个。请声明以下之一:{{fields}}。第一个是 spec 写法,其余为遗留别名。',
},
},
gantt: {
column: {
Expand Down
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
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
52 changes: 52 additions & 0 deletions .changeset/7459-timeline-absent-date-axis-refusal.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
---
'@object-ui/plugin-timeline': minor
'@object-ui/i18n': minor
---

`ObjectTimeline` refuses an undeclared date axis instead of inventing one
(objectui#7459).

Steps ① and ② of the three-step sequence the maintainer ruled on objectui#7070
(2026-09-01, 总监批 #28). House posture, on record with that ruling:
日期轴永不虚构 — a date axis is never fabricated.

`ObjectTimeline` resolved its date axis through five declared bindings and then
closed the chain with a sixth rung that was a bare literal field name nobody
has ever declared. A name therefore ALWAYS resolved: for a view that declared
no axis, every record read a key its object does not carry, every event landed
in the "No date" bucket, and the screen read as a timeline that had been built
and simply had nothing in it.

Two changes, shipped together because neither is observable alone:

- **The renderer now refuses.** An object-bound timeline with no declared date
axis renders a diagnostic naming every binding it accepts —
`timeline.startDateField`, `timeline.dateField`, `mapping.date`, and the two
deprecated flat spellings — instead of a chart. The twin of `ObjectGantt`'s
"Gantt configuration required" screen, in the shape objectui#7070 settled.
- **The invented sixth rung is gone**, which is the only thing that makes the
refusal reachable. Added while the floor stood, it would have been dead code;
retired without the refusal, it would have produced exactly the silent
"No date" outcome the ruling rejects.

**What changes for an author.** A view that declares a date axis is completely
unaffected — all five declared spellings resolve exactly as before, and a
timeline authored from literal `items` is never refused, since its items carry
their own dates and no field name is read for them. A view that declared no
axis anywhere, and was rendering an empty-looking timeline, now says so.

⚠️ Both premises were RE-MEASURED on the current tree before anything was
edited, rather than taken from the card: the renderer had no absent-axis
refusal (against a live control term that fires in the same file), and the
floor was still present and still spelled as reported. The pairing itself is
pinned — the refusal cases go red the moment the floor returns, including one
whose records carry a column that happens to be named `date`, where a returned
floor renders a convincing timeline rather than an empty one.

Refusal is distinguished from "renders an empty timeline" by asserting the
canvas is ABSENT, not merely event-free. The component's success surface is now
named (`data-testid="timeline-canvas"`) so that distinction can be measured;
every other terminal state of the component already named itself.

Step ③ of the ruling — the `'created_at'` floors on the two plugin faces —
stays on objectui#7070 and is deliberately NOT in this change.
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/ar.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -706,6 +706,9 @@ const ar = {
unsupported: {
objectBoundGantt: "النوع \"gantt\" غير مدعوم — المخطط الزمني المرتبط بكائن يعرض أنواع التغذية ({{variants}}). يحتاج مخطط جانت إلى صفوف صريحة، لكل منها عناصر items متداخلة خاصة به، لذلك لا يؤثر محور جانت (scale) هنا.",
},
unconfigured: {
noDateAxis: "محور تواريخ المخطط الزمني مطلوب — هذا العرض لا يعلن أي حقل تاريخ، والمخطط الزمني المرتبط بكائن لا يخترع حقلاً. أعلن أحد الحقول التالية: {{fields}}. الأول هو صيغة المواصفة، والبقية أسماء مستعارة قديمة.",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/de.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -702,6 +702,9 @@ const de = {
unsupported: {
objectBoundGantt: "Nicht unterstützte Variante „gantt“ — eine objektgebundene Timeline rendert die Feed-Varianten ({{variants}}). Gantt benötigt literale Zeilen mit jeweils eigenen verschachtelten items; die Gantt-Achse (scale) hat hier daher keine Wirkung.",
},
unconfigured: {
noDateAxis: "Zeitachse für die Timeline erforderlich — diese Ansicht deklariert kein Datumsfeld, und eine objektgebundene Timeline erfindet keines. Deklarieren Sie eines von: {{fields}}. Das erste ist die Spec-Schreibweise, die übrigen sind veraltete Aliase.",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/en.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -819,6 +819,9 @@ const en = {
unsupported: {
objectBoundGantt: 'Unsupported variant "gantt" — an object-bound timeline renders the feed variants ({{variants}}). Gantt needs literal rows, each with its own nested items, so the gantt axis (scale) has no effect here.',
},
unconfigured: {
noDateAxis: 'Timeline date axis required — this view declares no date field, and an object-bound timeline will not invent one. Declare one of: {{fields}}. The first is the spec spelling; the rest are legacy aliases.',
},
},
gantt: {
column: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/es.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -706,6 +706,9 @@ const es = {
unsupported: {
objectBoundGantt: "Variante \"gantt\" no admitida: una línea de tiempo vinculada a un objeto representa las variantes de feed ({{variants}}). Gantt necesita filas literales, cada una con sus propios items anidados, por lo que el eje gantt (scale) no tiene efecto aquí.",
},
unconfigured: {
noDateAxis: "Se requiere el eje de fechas de la línea de tiempo: esta vista no declara ningún campo de fecha y una línea de tiempo vinculada a un objeto no inventa ninguno. Declare uno de: {{fields}}. El primero es la grafía de la especificación; los demás son alias heredados.",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/fr.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -702,6 +702,9 @@ const fr = {
unsupported: {
objectBoundGantt: "Variante « gantt » non prise en charge — une timeline liée à un objet affiche les variantes de flux ({{variants}}). Gantt nécessite des lignes littérales, chacune avec ses propres items imbriqués ; l'axe gantt (scale) est donc sans effet ici.",
},
unconfigured: {
noDateAxis: "Axe de dates requis pour la timeline — cette vue ne déclare aucun champ de date, et une timeline liée à un objet n'en invente pas. Déclarez l'un de : {{fields}}. Le premier est l'orthographe de la spec, les autres sont des alias hérités.",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/ja.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -702,6 +702,9 @@ const ja = {
unsupported: {
objectBoundGantt: "サポートされていないバリアント \"gantt\" — オブジェクト連動のタイムラインはフィードバリアント({{variants}})を描画します。ガントには、それぞれが入れ子の items を持つリテラル行が必要なため、ここではガント軸(scale)は効果がありません。",
},
unconfigured: {
noDateAxis: "タイムラインの日付軸が必要です — このビューは日付フィールドを宣言しておらず、オブジェクト連動のタイムラインが日付フィールドを作り出すことはありません。次のいずれかを宣言してください: {{fields}}。最初のものが spec の記法で、残りは旧来のエイリアスです。",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/ko.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -702,6 +702,9 @@ const ko = {
unsupported: {
objectBoundGantt: "지원되지 않는 variant \"gantt\" — 객체 바인딩 타임라인은 피드 variant({{variants}})를 렌더링합니다. 간트는 각각 중첩된 items를 가진 리터럴 행이 필요하므로 여기서는 간트 축(scale)이 적용되지 않습니다.",
},
unconfigured: {
noDateAxis: "타임라인 날짜 축이 필요합니다 — 이 뷰는 날짜 필드를 선언하지 않았으며, 객체 바인딩 타임라인은 날짜 필드를 지어내지 않습니다. 다음 중 하나를 선언하세요: {{fields}}. 첫 번째가 spec 표기이고 나머지는 레거시 별칭입니다.",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/pt.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -701,6 +701,9 @@ const pt = {
unsupported: {
objectBoundGantt: "Variante \"gantt\" não suportada: uma linha do tempo vinculada a um objeto renderiza as variantes de feed ({{variants}}). O gantt precisa de linhas literais, cada uma com os seus próprios items aninhados, por isso o eixo gantt (scale) não tem efeito aqui.",
},
unconfigured: {
noDateAxis: "Eixo de datas da linha do tempo necessário: esta vista não declara nenhum campo de data e uma linha do tempo vinculada a um objeto não inventa nenhum. Declare um de: {{fields}}. O primeiro é a grafia da spec; os restantes são aliases legados.",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/ru.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -708,6 +708,9 @@ const ru = {
unsupported: {
objectBoundGantt: "Неподдерживаемый вариант \"gantt\" — временная шкала, привязанная к объекту, отображает ленточные варианты ({{variants}}). Для гантта нужны литеральные строки, каждая со своим вложенным items, поэтому ось гантта (scale) здесь не действует.",
},
unconfigured: {
noDateAxis: "Требуется ось дат временной шкалы — это представление не объявляет ни одного поля даты, а временная шкала, привязанная к объекту, не придумывает его сама. Объявите одно из: {{fields}}. Первое — написание из спецификации, остальные — устаревшие псевдонимы.",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/zh.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -726,6 +726,9 @@ const zh = {
unsupported: {
objectBoundGantt: '不支持的变体 "gantt" —— 对象绑定的时间线只渲染 feed 变体({{variants}})。甘特图需要字面量行,每行自带嵌套的 items,因此此处的甘特轴(scale)不起作用。',
},
unconfigured: {
noDateAxis: '时间线需要日期轴 —— 该视图未声明任何日期字段,而对象绑定的时间线不会虚构一个。请声明以下之一:{{fields}}。第一个是 spec 写法,其余为遗留别名。',
},
},
gantt: {
column: {
Expand Down
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
Merged
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
52 changes: 52 additions & 0 deletions .changeset/7459-timeline-absent-date-axis-refusal.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
---
'@object-ui/plugin-timeline': minor
'@object-ui/i18n': minor
---

`ObjectTimeline` refuses an undeclared date axis instead of inventing one
(objectui#7459).

Steps ① and ② of the three-step sequence the maintainer ruled on objectui#7070
(2026-09-01, 总监批 #28). House posture, on record with that ruling:
日期轴永不虚构 — a date axis is never fabricated.

`ObjectTimeline` resolved its date axis through five declared bindings and then
closed the chain with a sixth rung that was a bare literal field name nobody
has ever declared. A name therefore ALWAYS resolved: for a view that declared
no axis, every record read a key its object does not carry, every event landed
in the "No date" bucket, and the screen read as a timeline that had been built
and simply had nothing in it.

Two changes, shipped together because neither is observable alone:

- **The renderer now refuses.** An object-bound timeline with no declared date
axis renders a diagnostic naming every binding it accepts —
`timeline.startDateField`, `timeline.dateField`, `mapping.date`, and the two
deprecated flat spellings — instead of a chart. The twin of `ObjectGantt`'s
"Gantt configuration required" screen, in the shape objectui#7070 settled.
- **The invented sixth rung is gone**, which is the only thing that makes the
refusal reachable. Added while the floor stood, it would have been dead code;
retired without the refusal, it would have produced exactly the silent
"No date" outcome the ruling rejects.

**What changes for an author.** A view that declares a date axis is completely
unaffected — all five declared spellings resolve exactly as before, and a
timeline authored from literal `items` is never refused, since its items carry
their own dates and no field name is read for them. A view that declared no
axis anywhere, and was rendering an empty-looking timeline, now says so.

⚠️ Both premises were RE-MEASURED on the current tree before anything was
edited, rather than taken from the card: the renderer had no absent-axis
refusal (against a live control term that fires in the same file), and the
floor was still present and still spelled as reported. The pairing itself is
pinned — the refusal cases go red the moment the floor returns, including one
whose records carry a column that happens to be named `date`, where a returned
floor renders a convincing timeline rather than an empty one.

Refusal is distinguished from "renders an empty timeline" by asserting the
canvas is ABSENT, not merely event-free. The component's success surface is now
named (`data-testid="timeline-canvas"`) so that distinction can be measured;
every other terminal state of the component already named itself.

Step ③ of the ruling — the `'created_at'` floors on the two plugin faces —
stays on objectui#7070 and is deliberately NOT in this change.
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/ar.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -706,6 +706,9 @@ const ar = {
unsupported: {
objectBoundGantt: "النوع \"gantt\" غير مدعوم — المخطط الزمني المرتبط بكائن يعرض أنواع التغذية ({{variants}}). يحتاج مخطط جانت إلى صفوف صريحة، لكل منها عناصر items متداخلة خاصة به، لذلك لا يؤثر محور جانت (scale) هنا.",
},
unconfigured: {
noDateAxis: "محور تواريخ المخطط الزمني مطلوب — هذا العرض لا يعلن أي حقل تاريخ، والمخطط الزمني المرتبط بكائن لا يخترع حقلاً. أعلن أحد الحقول التالية: {{fields}}. الأول هو صيغة المواصفة، والبقية أسماء مستعارة قديمة.",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/de.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -702,6 +702,9 @@ const de = {
unsupported: {
objectBoundGantt: "Nicht unterstützte Variante „gantt“ — eine objektgebundene Timeline rendert die Feed-Varianten ({{variants}}). Gantt benötigt literale Zeilen mit jeweils eigenen verschachtelten items; die Gantt-Achse (scale) hat hier daher keine Wirkung.",
},
unconfigured: {
noDateAxis: "Zeitachse für die Timeline erforderlich — diese Ansicht deklariert kein Datumsfeld, und eine objektgebundene Timeline erfindet keines. Deklarieren Sie eines von: {{fields}}. Das erste ist die Spec-Schreibweise, die übrigen sind veraltete Aliase.",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/en.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -819,6 +819,9 @@ const en = {
unsupported: {
objectBoundGantt: 'Unsupported variant "gantt" — an object-bound timeline renders the feed variants ({{variants}}). Gantt needs literal rows, each with its own nested items, so the gantt axis (scale) has no effect here.',
},
unconfigured: {
noDateAxis: 'Timeline date axis required — this view declares no date field, and an object-bound timeline will not invent one. Declare one of: {{fields}}. The first is the spec spelling; the rest are legacy aliases.',
},
},
gantt: {
column: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/es.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -706,6 +706,9 @@ const es = {
unsupported: {
objectBoundGantt: "Variante \"gantt\" no admitida: una línea de tiempo vinculada a un objeto representa las variantes de feed ({{variants}}). Gantt necesita filas literales, cada una con sus propios items anidados, por lo que el eje gantt (scale) no tiene efecto aquí.",
},
unconfigured: {
noDateAxis: "Se requiere el eje de fechas de la línea de tiempo: esta vista no declara ningún campo de fecha y una línea de tiempo vinculada a un objeto no inventa ninguno. Declare uno de: {{fields}}. El primero es la grafía de la especificación; los demás son alias heredados.",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/fr.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -702,6 +702,9 @@ const fr = {
unsupported: {
objectBoundGantt: "Variante « gantt » non prise en charge — une timeline liée à un objet affiche les variantes de flux ({{variants}}). Gantt nécessite des lignes littérales, chacune avec ses propres items imbriqués ; l'axe gantt (scale) est donc sans effet ici.",
},
unconfigured: {
noDateAxis: "Axe de dates requis pour la timeline — cette vue ne déclare aucun champ de date, et une timeline liée à un objet n'en invente pas. Déclarez l'un de : {{fields}}. Le premier est l'orthographe de la spec, les autres sont des alias hérités.",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/ja.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -702,6 +702,9 @@ const ja = {
unsupported: {
objectBoundGantt: "サポートされていないバリアント \"gantt\" — オブジェクト連動のタイムラインはフィードバリアント({{variants}})を描画します。ガントには、それぞれが入れ子の items を持つリテラル行が必要なため、ここではガント軸(scale)は効果がありません。",
},
unconfigured: {
noDateAxis: "タイムラインの日付軸が必要です — このビューは日付フィールドを宣言しておらず、オブジェクト連動のタイムラインが日付フィールドを作り出すことはありません。次のいずれかを宣言してください: {{fields}}。最初のものが spec の記法で、残りは旧来のエイリアスです。",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/ko.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -702,6 +702,9 @@ const ko = {
unsupported: {
objectBoundGantt: "지원되지 않는 variant \"gantt\" — 객체 바인딩 타임라인은 피드 variant({{variants}})를 렌더링합니다. 간트는 각각 중첩된 items를 가진 리터럴 행이 필요하므로 여기서는 간트 축(scale)이 적용되지 않습니다.",
},
unconfigured: {
noDateAxis: "타임라인 날짜 축이 필요합니다 — 이 뷰는 날짜 필드를 선언하지 않았으며, 객체 바인딩 타임라인은 날짜 필드를 지어내지 않습니다. 다음 중 하나를 선언하세요: {{fields}}. 첫 번째가 spec 표기이고 나머지는 레거시 별칭입니다.",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/pt.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -701,6 +701,9 @@ const pt = {
unsupported: {
objectBoundGantt: "Variante \"gantt\" não suportada: uma linha do tempo vinculada a um objeto renderiza as variantes de feed ({{variants}}). O gantt precisa de linhas literais, cada uma com os seus próprios items aninhados, por isso o eixo gantt (scale) não tem efeito aqui.",
},
unconfigured: {
noDateAxis: "Eixo de datas da linha do tempo necessário: esta vista não declara nenhum campo de data e uma linha do tempo vinculada a um objeto não inventa nenhum. Declare um de: {{fields}}. O primeiro é a grafia da spec; os restantes são aliases legados.",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/ru.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -708,6 +708,9 @@ const ru = {
unsupported: {
objectBoundGantt: "Неподдерживаемый вариант \"gantt\" — временная шкала, привязанная к объекту, отображает ленточные варианты ({{variants}}). Для гантта нужны литеральные строки, каждая со своим вложенным items, поэтому ось гантта (scale) здесь не действует.",
},
unconfigured: {
noDateAxis: "Требуется ось дат временной шкалы — это представление не объявляет ни одного поля даты, а временная шкала, привязанная к объекту, не придумывает его сама. Объявите одно из: {{fields}}. Первое — написание из спецификации, остальные — устаревшие псевдонимы.",
},
},
gantt: {
viewMode: {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/zh.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -726,6 +726,9 @@ const zh = {
unsupported: {
objectBoundGantt: '不支持的变体 "gantt" —— 对象绑定的时间线只渲染 feed 变体({{variants}})。甘特图需要字面量行,每行自带嵌套的 items,因此此处的甘特轴(scale)不起作用。',
},
unconfigured: {
noDateAxis: '时间线需要日期轴 —— 该视图未声明任何日期字段,而对象绑定的时间线不会虚构一个。请声明以下之一:{{fields}}。第一个是 spec 写法,其余为遗留别名。',
},
},
gantt: {
column: {
Expand Down
Loading
Loading