diff --git a/.changeset/7192-retire-seven-unmounted-detail-exports.md b/.changeset/7192-retire-seven-unmounted-detail-exports.md new file mode 100644 index 0000000000..441201c999 --- /dev/null +++ b/.changeset/7192-retire-seven-unmounted-detail-exports.md @@ -0,0 +1,62 @@ +--- +'@object-ui/plugin-detail': minor +'@object-ui/i18n': minor +--- + +**BREAKING:** `@object-ui/plugin-detail` no longer exports seven components that +nothing registered and nothing mounted (objectui#7192, objectui#7175). This +narrows the package's published surface. It is declared `minor`, not `major`, +because this fixed release group follows the `@objectstack` major (AGENTS.md +§9); the breaking change is stated here instead. + +Removed, with every type exported beside them: + +- `CommentInput`, with `CommentInputProps` +- `DiffView`, with `DiffViewProps`, `DiffFieldType`, `DiffMode` and `DiffLine` +- `InlineCreateRelated`, with `InlineCreateRelatedProps`, + `RelatedFieldDefinition` and `RelatedRecordOption` +- `MentionAutocomplete` and the helper `createMentionFromSuggestion`, with + `MentionAutocompleteProps` and `MentionSuggestionItem` +- `PointInTimeRestore`, with `PointInTimeRestoreProps` and `RevisionEntry` +- `RecordNavigationEnhanced`, with `RecordNavigationEnhancedProps` +- `RelationshipGraph`, with `RelationshipGraphProps` and `GraphNode` + +Why they went: none of the seven was passed to `ComponentRegistry.register`, so +metadata had no type string to name any of them, and none was mounted anywhere +in this repository. The downstream readings agree: `cloud` references none of +the seven names (objectstack#14187), and `hotcrm` depends on no `@object-ui/*` +package at all. The maintainer ruled to delete them; the ruling is relayed on +objectui#7192. + +Not affected: `RichTextCommentInput` and its `MentionSuggestion` type (the +composer `RecordActivityTimeline` mounts), `RecordComments` (`DetailView` +mounts it) and `extractMentions` all stay exported. + +`@object-ui/i18n`: the `detail.*` keys that only these components read are +removed from all ten locale packs, and the matching rows from +`DETAIL_DEFAULT_TRANSLATIONS`: + +- `PointInTimeRestore`'s ten, added by objectui#7163: `revisionHistory`, + `noRevisions`, `revisionFieldsChanged`, `revisionFieldsChangedOne`, + `revisionPreview`, `revisionSnapshot`, `restoreConfirm`, `restoring`, + `confirmRestore`, `restoreToPoint` +- `emptyValue`, an older key whose last reader was `PointInTimeRestore` +- `DiffView`'s five: `unifiedDiff`, `sideBySideDiff`, `noChanges`, + `previousVersion`, `currentVersion` +- `RecordNavigationEnhanced`'s six: `firstRecord`, `previousRecordKey`, + `nextRecordKey`, `lastRecord`, `searchWhileNavigating`, `searchRecords` + +Keys these components shared with surfaces that stay (`detail.recordOf`, +`detail.noRecords`, `detail.cancel`, `detail.activityEmptyValue`, the +relative-time keys) are kept. A host that read one of the removed keys itself +now gets the raw key back. + +Other entries in this same release describe work on `PointInTimeRestore` and +`DiffView` (their translation and display-locale fixes). That work shipped in +components this entry removes. + +**Migration:** there is no replacement. If you import one of these components, +copy its source file (`packages/plugin-detail/src/`, the file named after the +component) from a release tag that still ships it, for example +`@object-ui/plugin-detail@17.5.0`, into your own code. If you need one of them +back in the package, open an issue that says who uses it and where. diff --git a/content/docs/plugins/plugin-detail.mdx b/content/docs/plugins/plugin-detail.mdx index f8e2318b95..9ac56bb668 100644 --- a/content/docs/plugins/plugin-detail.mdx +++ b/content/docs/plugins/plugin-detail.mdx @@ -25,9 +25,7 @@ The Feed & Chatter system provides Airtable-style record-level collaboration. It |-----------|---------| | `RecordChatterPanel` | Main wrapper panel (bottom/right/left positioning, collapsible) | | `RecordActivityTimeline` | Core activity feed renderer (filter, pagination, actor display) | -| `CommentInput` | Comment submission with Ctrl+Enter shortcut | | `FieldChangeItem` | Field change history display (old → new values) | -| `MentionAutocomplete` | @mention suggestion dropdown | | `ReactionPicker` | Emoji reaction selector | | `ThreadedReplies` | Collapsible reply threading | | `SubscriptionToggle` | Bell notification toggle | @@ -444,15 +442,6 @@ decision as a defect is how a warning channel gets ignored: | `onToggleSubscription` | `(subscribed: boolean) => void` | — | Toggle subscription callback | | `className` | `string` | `''` | Additional CSS classes | -### CommentInput - -| Property | Type | Default | Description | -|----------|------|---------|-------------| -| `onSubmit` | `(text: string) => void` | required | Comment submit callback | -| `placeholder` | `string` | `'Add a comment...'` | Input placeholder text | -| `disabled` | `boolean` | `false` | Disable input | -| `className` | `string` | `''` | Additional CSS classes | - ### ReactionPicker | Property | Type | Default | Description | @@ -517,7 +506,6 @@ import type { import type { RecordChatterPanelProps, RecordActivityTimelineProps, - CommentInputProps, FieldChangeItemProps, ReactionPickerProps, ThreadedRepliesProps, diff --git a/docs/audits/2026-09-plugin-detail-downstream-consumer-census.md b/docs/audits/2026-09-plugin-detail-downstream-consumer-census.md index e6f9973762..cd7c3c9b56 100644 --- a/docs/audits/2026-09-plugin-detail-downstream-consumer-census.md +++ b/docs/audits/2026-09-plugin-detail-downstream-consumer-census.md @@ -18,6 +18,33 @@ makes that decision *possible*, not the decision. --- +## Conclusion (2026-09-24): the maintainer ruled **delete** + +The decision this audit made possible has since been taken. On 2026-09-24 triage put the +question "delete the seven unregistered, unmounted `plugin-detail` exports?" to the +maintainer with a recommendation to delete, and relayed the reply on objectui#7192 (triage +comment 5819441716, which quotes it verbatim). The reply declined two other items by number +and approved the rest. The seven exports were among the rest, so the ruling is **delete**. + +- **The gap this audit left open was closed first.** `cloud` was read on + objectstack#14187 (all seven names, controls firing, zero). `hotcrm` is zero by + construction: it depends on no `@object-ui/*` package (the objectui#7175 reading of + 2026-09-04). +- **Delivered by the pull request that closes objectui#7192 and objectui#7175**, on branch + `claude/issue-7192-retire-seven-unmounted-detail-exports`. It deletes all seven components + (`CommentInput`, `DiffView`, `InlineCreateRelated`, `MentionAutocomplete`, + `PointInTimeRestore`, `RecordNavigationEnhanced`, `RelationshipGraph`), their own tests, + their value and type exports from the barrel, and the i18n keys that only they read. + Its changeset lists every removed export and the migration. +- **No replacement is kept "in case".** If a real consumer turns up, it gets a new card that + says who needs the component and where, and the component comes back on that evidence. + +The rest of this document is the audit as written on 2026-09-01. Its "does not retire" and +"does NOT claim" statements describe what this measurement established on its own, and they +stay as that record. + +--- + ## Summary | Population | Channel | Positive control | `PointInTimeRestore` | Verdict | diff --git a/packages/app-shell/src/views/RecordDetailView.discussionExplicitComposition-7298.test.tsx b/packages/app-shell/src/views/RecordDetailView.discussionExplicitComposition-7298.test.tsx index 36bd4e064d..824c5b65f6 100644 --- a/packages/app-shell/src/views/RecordDetailView.discussionExplicitComposition-7298.test.tsx +++ b/packages/app-shell/src/views/RecordDetailView.discussionExplicitComposition-7298.test.tsx @@ -103,7 +103,8 @@ const COMMENT_MARKER = 'A comment on the record'; /** The panel's own chrome — present whenever it mounts, empty feed or not. */ const PANEL_HEADING = 'Discussion'; const PANEL_EMPTY = 'No comments yet'; -/** `CommentInput`'s textarea — the write surface the ruling is about. Read by +/** The composer's textarea (`RichTextCommentInput`, as `RecordActivityTimeline` + * mounts it) — the write surface the ruling is about. Read by * PLACEHOLDER, not by the submit button: that button mounts only once the box * has text, so counting it reads zero on a panel that is fully open for * writes. */ diff --git a/packages/components/src/__tests__/sheet-dialog-close-i18n.test.tsx b/packages/components/src/__tests__/sheet-dialog-close-i18n.test.tsx index 03d56d105e..27cd93e47a 100644 --- a/packages/components/src/__tests__/sheet-dialog-close-i18n.test.tsx +++ b/packages/components/src/__tests__/sheet-dialog-close-i18n.test.tsx @@ -28,7 +28,7 @@ * * A large amount of existing coverage addresses these controls by their * English name with NO `I18nProvider` mounted (`discardGuard.test.tsx`, - * `InlineCreateRelated.closeButtonName.test.tsx`, e2e specs). The safe + * e2e specs). The safe * translation's English fallback is what keeps those green, so it is pinned * here explicitly rather than assumed. */ diff --git a/packages/components/src/__tests__/sheet-dialog-close-no-provider-fallback.test.tsx b/packages/components/src/__tests__/sheet-dialog-close-no-provider-fallback.test.tsx index b23ea2e915..82d552169a 100644 --- a/packages/components/src/__tests__/sheet-dialog-close-no-provider-fallback.test.tsx +++ b/packages/components/src/__tests__/sheet-dialog-close-no-provider-fallback.test.tsx @@ -15,9 +15,7 @@ * `DialogContent` consumer in the repo, and a large amount of existing * coverage addresses those controls by their ENGLISH accessible name with no * provider in the tree — `packages/plugin-form/src/discardGuard.test.tsx` - * (`getByRole('button', { name: 'Close' })`) and - * `packages/plugin-detail/src/__tests__/InlineCreateRelated.closeButtonName.test.tsx` - * (`/^Close$/`) among them. A `t()` call without a working default renders the + * (`getByRole('button', { name: 'Close' })`) among them. A `t()` call without a working default renders the * raw `common.close` key and breaks all of it — in other packages' suites, not * this one's. * diff --git a/packages/components/src/lib/close-label.tsx b/packages/components/src/lib/close-label.tsx index f550642a6b..3bc55f5610 100644 --- a/packages/components/src/lib/close-label.tsx +++ b/packages/components/src/lib/close-label.tsx @@ -34,8 +34,7 @@ * The no-provider path must stay English. A large number of existing unit * tests and e2e specs address dialogs and drawers by their English accessible * name with no `I18nProvider` mounted (e.g. - * `packages/plugin-form/src/discardGuard.test.tsx`, - * `packages/plugin-detail/src/__tests__/InlineCreateRelated.closeButtonName.test.tsx`), + * `packages/plugin-form/src/discardGuard.test.tsx`), * and a primitive that rendered a raw `common.close` key there would break all * of them. `createSafeTranslation` probes its test key and falls back to the * defaults map below when translations are not configured, so "no provider" diff --git a/packages/i18n/src/locales/ar.ts b/packages/i18n/src/locales/ar.ts index 64f927a97b..3d295f103b 100644 --- a/packages/i18n/src/locales/ar.ts +++ b/packages/i18n/src/locales/ar.ts @@ -966,7 +966,6 @@ const ar = { viewAll: "عرض الكل", new: "جديد", add: "إضافة", - emptyValue: "—", comments: "التعليقات", searchComments: "البحث في التعليقات…", addCommentPlaceholder: "أضف تعليقاً… (Ctrl+Enter للإرسال)", @@ -999,11 +998,6 @@ const ar = { attachmentsLoadFailed: "تعذر تحميل مرفقات هذا السجل.", attachmentsApiUnavailable: "قائمة المرفقات غير متاحة على هذا الكائن.", retryLoadAttachments: "إعادة المحاولة", - unifiedDiff: "عرض موحد", - sideBySideDiff: "عرض جنباً إلى جنب", - noChanges: "لا توجد تغييرات", - previousVersion: "السابق", - currentVersion: "الحالي", discussion: "المناقشة", showDiscussion: "إظهار المناقشة ({{count}})", hideDiscussion: "إخفاء المناقشة", @@ -1018,13 +1012,7 @@ const ar = { writeComment: "اكتب تعليقاً…", subscribedTooltip: "مشترك — انقر لإلغاء الاشتراك", unsubscribedTooltip: "الاشتراك في الإشعارات", - firstRecord: "السجل الأول (Home)", - previousRecordKey: "السجل السابق (←)", - nextRecordKey: "السجل التالي (→)", - lastRecord: "السجل الأخير (End)", noRecords: "لا توجد سجلات", - searchWhileNavigating: "البحث أثناء التصفح", - searchRecords: "البحث في السجلات…", allActivity: "كل النشاط", commentsOnly: "التعليقات فقط", fieldChangesFilter: "تغييرات الحقول", @@ -1139,21 +1127,6 @@ const ar = { fileCount: "{{count}} ملف (ملفات)", fileCount_one: "{{count}} ملف", fileCount_other: "{{count}} ملفات", - // objectui#7163 — PointInTimeRestore's revision-history chrome. The file - // used no translation hook at all, so every one of these read English in - // every session; swept in one pass rather than converting the timestamps - // alone. `Cancel`, `(empty)` and the empty-value dash reuse the keys this - // namespace already has, so only these ten are new. - revisionHistory: 'سجل المراجعات', - noRevisions: 'لا توجد مراجعات مسجلة', - revisionFieldsChanged: 'تم تغيير {{count}} حقول', - revisionFieldsChangedOne: 'تم تغيير {{count}} حقل', - revisionPreview: 'معاينة المراجعة', - revisionSnapshot: 'حالة السجل في هذه النقطة', - restoreConfirm: 'سيؤدي هذا إلى استعادة السجل إلى حالته في {{when}}. هل تريد المتابعة؟', - restoring: 'جارٍ الاستعادة…', - confirmRestore: 'تأكيد الاستعادة', - restoreToPoint: 'الاستعادة إلى هذه النقطة', }, chart: { loading: "جارٍ تحميل الرسم البياني…", diff --git a/packages/i18n/src/locales/de.ts b/packages/i18n/src/locales/de.ts index 0e67ff532a..3bf6531107 100644 --- a/packages/i18n/src/locales/de.ts +++ b/packages/i18n/src/locales/de.ts @@ -956,7 +956,6 @@ const de = { viewAll: "Alle anzeigen", new: "Neu", add: "Hinzufügen", - emptyValue: "—", comments: "Kommentare", searchComments: "Kommentare suchen…", addCommentPlaceholder: "Kommentar hinzufügen… (Strg+Enter zum Senden)", @@ -989,11 +988,6 @@ const de = { attachmentsLoadFailed: "Die Anhänge dieses Datensatzes konnten nicht geladen werden.", attachmentsApiUnavailable: "Die Anhangsliste ist für dieses Objekt nicht verfügbar.", retryLoadAttachments: "Erneut versuchen", - unifiedDiff: "Einheitliche Ansicht", - sideBySideDiff: "Nebeneinander-Ansicht", - noChanges: "Keine Änderungen", - previousVersion: "Vorherige", - currentVersion: "Aktuelle", discussion: "Diskussion", showDiscussion: "Diskussion anzeigen ({{count}})", hideDiscussion: "Diskussion ausblenden", @@ -1008,13 +1002,7 @@ const de = { writeComment: "Kommentar schreiben…", subscribedTooltip: "Abonniert — Klicken zum Abbestellen", unsubscribedTooltip: "Benachrichtigungen abonnieren", - firstRecord: "Erster Datensatz (Pos1)", - previousRecordKey: "Vorheriger Datensatz (←)", - nextRecordKey: "Nächster Datensatz (→)", - lastRecord: "Letzter Datensatz (Ende)", noRecords: "Keine Datensätze", - searchWhileNavigating: "Während der Navigation suchen", - searchRecords: "Datensätze suchen…", allActivity: "Alle Aktivitäten", commentsOnly: "Nur Kommentare", fieldChangesFilter: "Feldänderungen", @@ -1128,21 +1116,6 @@ const de = { fileCount: "{{count}} Dateien", fileCount_one: "{{count}} Datei", fileCount_other: "{{count}} Dateien", - // objectui#7163 — PointInTimeRestore's revision-history chrome. The file - // used no translation hook at all, so every one of these read English in - // every session; swept in one pass rather than converting the timestamps - // alone. `Cancel`, `(empty)` and the empty-value dash reuse the keys this - // namespace already has, so only these ten are new. - revisionHistory: 'Versionsverlauf', - noRevisions: 'Keine Versionen aufgezeichnet', - revisionFieldsChanged: '{{count}} Felder geändert', - revisionFieldsChangedOne: '{{count}} Feld geändert', - revisionPreview: 'Versionsvorschau', - revisionSnapshot: 'Datensatzstand zu diesem Zeitpunkt', - restoreConfirm: 'Dadurch wird der Datensatz auf seinen Stand von {{when}} zurückgesetzt. Fortfahren?', - restoring: 'Wird wiederhergestellt…', - confirmRestore: 'Wiederherstellung bestätigen', - restoreToPoint: 'Auf diesen Zeitpunkt zurücksetzen', }, chart: { loading: "Diagramm wird geladen…", diff --git a/packages/i18n/src/locales/en.ts b/packages/i18n/src/locales/en.ts index 444ff45fac..eb4f3a677a 100644 --- a/packages/i18n/src/locales/en.ts +++ b/packages/i18n/src/locales/en.ts @@ -1158,7 +1158,6 @@ const en = { viewAll: 'View All', new: 'New', add: 'Add', - emptyValue: '—', activity: 'Activity', history: 'History', historyEmpty: 'No history yet', @@ -1218,12 +1217,6 @@ const en = { attachmentsLoadFailed: "We couldn't load the attachments for this record.", attachmentsApiUnavailable: 'The attachments list is not available on this object.', retryLoadAttachments: 'Retry', - // Diff - unifiedDiff: 'Unified diff', - sideBySideDiff: 'Side-by-side diff', - noChanges: 'No changes', - previousVersion: 'Previous', - currentVersion: 'Current', // Discussion discussion: 'Discussion', showDiscussion: 'Show Discussion ({{count}})', @@ -1241,11 +1234,7 @@ const en = { // Subscription subscribedTooltip: 'Subscribed — click to unsubscribe', unsubscribedTooltip: 'Subscribe to notifications', - // Navigation - firstRecord: 'First record (Home)', - previousRecordKey: 'Previous record (←)', - nextRecordKey: 'Next record (→)', - lastRecord: 'Last record (End)', + // The reference rail's empty related-record list noRecords: 'No records', // objectui#3863 — the BASE key is the slot every plural category a pack did not // enumerate resolves to, keeping that pack in its own language instead of falling @@ -1256,8 +1245,6 @@ const en = { showEmptyRelated: '+ {{count}} empty', showEmptyRelated_one: '+ {{count}} empty', showEmptyRelated_other: '+ {{count}} empty', - searchWhileNavigating: 'Search while navigating', - searchRecords: 'Search records…', // Activity timeline allActivity: 'All Activity', commentsOnly: 'Comments Only', @@ -1320,21 +1307,6 @@ const en = { fileCount: '{{count}} files', fileCount_one: '{{count}} file', fileCount_other: '{{count}} files', - // objectui#7163 — PointInTimeRestore's revision-history chrome. The file - // used no translation hook at all, so every one of these read English in - // every session; swept in one pass rather than converting the timestamps - // alone. `Cancel`, `(empty)` and the empty-value dash reuse the keys this - // namespace already has, so only these ten are new. - revisionHistory: 'Revision History', - noRevisions: 'No revisions recorded', - revisionFieldsChanged: '{{count}} fields changed', - revisionFieldsChangedOne: '{{count}} field changed', - revisionPreview: 'Revision Preview', - revisionSnapshot: 'Record state at this point', - restoreConfirm: 'This will restore the record to its state at {{when}}. Continue?', - restoring: 'Restoring…', - confirmRestore: 'Confirm Restore', - restoreToPoint: 'Restore to this point', }, chart: { loading: 'Loading chart…', diff --git a/packages/i18n/src/locales/es.ts b/packages/i18n/src/locales/es.ts index 72d144438f..5aad95a3dc 100644 --- a/packages/i18n/src/locales/es.ts +++ b/packages/i18n/src/locales/es.ts @@ -960,7 +960,6 @@ const es = { viewAll: "Ver todo", new: "Nuevo", add: "Agregar", - emptyValue: "—", comments: "Comentarios", searchComments: "Buscar comentarios…", addCommentPlaceholder: "Añadir comentario… (Ctrl+Enter para enviar)", @@ -993,11 +992,6 @@ const es = { attachmentsLoadFailed: "No se pudieron cargar los adjuntos de este registro.", attachmentsApiUnavailable: "La lista de adjuntos no está disponible en este objeto.", retryLoadAttachments: "Reintentar", - unifiedDiff: "Vista unificada", - sideBySideDiff: "Vista lado a lado", - noChanges: "Sin cambios", - previousVersion: "Anterior", - currentVersion: "Actual", discussion: "Discusión", showDiscussion: "Mostrar discusión ({{count}})", hideDiscussion: "Ocultar discusión", @@ -1012,13 +1006,7 @@ const es = { writeComment: "Escribe un comentario…", subscribedTooltip: "Suscrito — clic para cancelar suscripción", unsubscribedTooltip: "Suscribirse a notificaciones", - firstRecord: "Primer registro (Inicio)", - previousRecordKey: "Registro anterior (←)", - nextRecordKey: "Siguiente registro (→)", - lastRecord: "Último registro (Fin)", noRecords: "Sin registros", - searchWhileNavigating: "Buscar mientras navegas", - searchRecords: "Buscar registros…", allActivity: "Toda la actividad", commentsOnly: "Solo comentarios", fieldChangesFilter: "Cambios de campo", @@ -1132,21 +1120,6 @@ const es = { fileCount: "{{count}} archivos", fileCount_one: "{{count}} archivo", fileCount_other: "{{count}} archivos", - // objectui#7163 — PointInTimeRestore's revision-history chrome. The file - // used no translation hook at all, so every one of these read English in - // every session; swept in one pass rather than converting the timestamps - // alone. `Cancel`, `(empty)` and the empty-value dash reuse the keys this - // namespace already has, so only these ten are new. - revisionHistory: 'Historial de revisiones', - noRevisions: 'Sin revisiones registradas', - revisionFieldsChanged: '{{count}} campos modificados', - revisionFieldsChangedOne: '{{count}} campo modificado', - revisionPreview: 'Vista previa de la revisión', - revisionSnapshot: 'Estado del registro en este punto', - restoreConfirm: 'Esto restaurará el registro a su estado del {{when}}. ¿Continuar?', - restoring: 'Restaurando…', - confirmRestore: 'Confirmar restauración', - restoreToPoint: 'Restaurar a este punto', }, chart: { loading: "Cargando gráfico…", diff --git a/packages/i18n/src/locales/fr.ts b/packages/i18n/src/locales/fr.ts index 936ea33583..8449de56f5 100644 --- a/packages/i18n/src/locales/fr.ts +++ b/packages/i18n/src/locales/fr.ts @@ -958,7 +958,6 @@ const fr = { viewAll: "Tout afficher", new: "Nouveau", add: "Ajouter", - emptyValue: "—", comments: "Commentaires", searchComments: "Rechercher des commentaires…", addCommentPlaceholder: "Ajouter un commentaire… (Ctrl+Entrée pour envoyer)", @@ -991,11 +990,6 @@ const fr = { attachmentsLoadFailed: "Impossible de charger les pièces jointes de cet enregistrement.", attachmentsApiUnavailable: "La liste des pièces jointes n'est pas disponible sur cet objet.", retryLoadAttachments: "Réessayer", - unifiedDiff: "Vue unifiée", - sideBySideDiff: "Vue côte à côte", - noChanges: "Aucune modification", - previousVersion: "Précédent", - currentVersion: "Actuel", discussion: "Discussion", showDiscussion: "Afficher la discussion ({{count}})", hideDiscussion: "Masquer la discussion", @@ -1010,13 +1004,7 @@ const fr = { writeComment: "Écrire un commentaire…", subscribedTooltip: "Abonné — cliquez pour vous désabonner", unsubscribedTooltip: "S'abonner aux notifications", - firstRecord: "Premier enregistrement (Début)", - previousRecordKey: "Enregistrement précédent (←)", - nextRecordKey: "Enregistrement suivant (→)", - lastRecord: "Dernier enregistrement (Fin)", noRecords: "Aucun enregistrement", - searchWhileNavigating: "Rechercher pendant la navigation", - searchRecords: "Rechercher des enregistrements…", allActivity: "Toute l'activité", commentsOnly: "Commentaires uniquement", fieldChangesFilter: "Modifications de champs", @@ -1130,21 +1118,6 @@ const fr = { fileCount: "{{count}} fichiers", fileCount_one: "{{count}} fichier", fileCount_other: "{{count}} fichiers", - // objectui#7163 — PointInTimeRestore's revision-history chrome. The file - // used no translation hook at all, so every one of these read English in - // every session; swept in one pass rather than converting the timestamps - // alone. `Cancel`, `(empty)` and the empty-value dash reuse the keys this - // namespace already has, so only these ten are new. - revisionHistory: 'Historique des révisions', - noRevisions: 'Aucune révision enregistrée', - revisionFieldsChanged: '{{count}} champs modifiés', - revisionFieldsChangedOne: '{{count}} champ modifié', - revisionPreview: 'Aperçu de la révision', - revisionSnapshot: "État de l'enregistrement à ce moment", - restoreConfirm: "Cela restaurera l'enregistrement à son état du {{when}}. Continuer ?", - restoring: 'Restauration…', - confirmRestore: 'Confirmer la restauration', - restoreToPoint: 'Restaurer à ce point', }, chart: { loading: "Chargement du graphique…", diff --git a/packages/i18n/src/locales/ja.ts b/packages/i18n/src/locales/ja.ts index dbcaef15ef..9971b64377 100644 --- a/packages/i18n/src/locales/ja.ts +++ b/packages/i18n/src/locales/ja.ts @@ -956,7 +956,6 @@ const ja = { viewAll: "すべて表示", new: "新規", add: "追加", - emptyValue: "—", activity: "アクティビティ", editRow: "編集", deleteRow: "削除", @@ -1001,11 +1000,6 @@ const ja = { attachmentsLoadFailed: "このレコードの添付ファイルを読み込めませんでした。", attachmentsApiUnavailable: "このオブジェクトでは添付ファイルの一覧を利用できません。", retryLoadAttachments: "再試行", - unifiedDiff: "統合差分", - sideBySideDiff: "横並び差分", - noChanges: "変更なし", - previousVersion: "前のバージョン", - currentVersion: "現在のバージョン", discussion: "ディスカッション", showDiscussion: "ディスカッションを表示 ({{count}})", hideDiscussion: "ディスカッションを非表示", @@ -1020,13 +1014,7 @@ const ja = { writeComment: "コメントを入力…", subscribedTooltip: "購読中 — クリックで解除", unsubscribedTooltip: "通知を購読", - firstRecord: "最初のレコード (Home)", - previousRecordKey: "前のレコード (←)", - nextRecordKey: "次のレコード (→)", - lastRecord: "最後のレコード (End)", noRecords: "レコードなし", - searchWhileNavigating: "ナビゲーション中に検索", - searchRecords: "レコードを検索…", allActivity: "すべてのアクティビティ", commentsOnly: "コメントのみ", fieldChangesFilter: "フィールド変更", @@ -1128,21 +1116,6 @@ const ja = { fileCount: "ファイル {{count}} 件", fileCount_one: "ファイル {{count}} 件", fileCount_other: "ファイル {{count}} 件", - // objectui#7163 — PointInTimeRestore's revision-history chrome. The file - // used no translation hook at all, so every one of these read English in - // every session; swept in one pass rather than converting the timestamps - // alone. `Cancel`, `(empty)` and the empty-value dash reuse the keys this - // namespace already has, so only these ten are new. - revisionHistory: 'リビジョン履歴', - noRevisions: 'リビジョンの記録なし', - revisionFieldsChanged: '{{count}} 件のフィールドを変更', - revisionFieldsChangedOne: '{{count}} 件のフィールドを変更', - revisionPreview: 'リビジョンのプレビュー', - revisionSnapshot: 'この時点のレコード状態', - restoreConfirm: 'レコードを {{when}} の状態に復元します。続行しますか?', - restoring: '復元中…', - confirmRestore: '復元を確認', - restoreToPoint: 'この時点に復元', }, chart: { loading: "チャート読み込み中…", diff --git a/packages/i18n/src/locales/ko.ts b/packages/i18n/src/locales/ko.ts index 1664a3bdbb..44e408d75c 100644 --- a/packages/i18n/src/locales/ko.ts +++ b/packages/i18n/src/locales/ko.ts @@ -956,7 +956,6 @@ const ko = { viewAll: "모두 보기", new: "새로 만들기", add: "추가", - emptyValue: "—", comments: "댓글", searchComments: "댓글 검색…", addCommentPlaceholder: "댓글 추가… (Ctrl+Enter로 제출)", @@ -989,11 +988,6 @@ const ko = { attachmentsLoadFailed: "이 레코드의 첨부파일을 불러오지 못했습니다.", attachmentsApiUnavailable: "이 객체에서는 첨부 파일 목록을 사용할 수 없습니다.", retryLoadAttachments: "다시 시도", - unifiedDiff: "통합 보기", - sideBySideDiff: "나란히 보기", - noChanges: "변경 없음", - previousVersion: "이전 버전", - currentVersion: "현재 버전", discussion: "토론", showDiscussion: "토론 보기 ({{count}})", hideDiscussion: "토론 숨기기", @@ -1008,13 +1002,7 @@ const ko = { writeComment: "댓글 작성…", subscribedTooltip: "구독 중 — 클릭하여 구독 취소", unsubscribedTooltip: "알림 구독", - firstRecord: "첫 번째 레코드 (Home)", - previousRecordKey: "이전 레코드 (←)", - nextRecordKey: "다음 레코드 (→)", - lastRecord: "마지막 레코드 (End)", noRecords: "레코드 없음", - searchWhileNavigating: "탐색 중 검색", - searchRecords: "레코드 검색…", allActivity: "모든 활동", commentsOnly: "댓글만", fieldChangesFilter: "필드 변경", @@ -1128,21 +1116,6 @@ const ko = { fileCount: "파일 {{count}}개", fileCount_one: "파일 {{count}}개", fileCount_other: "파일 {{count}}개", - // objectui#7163 — PointInTimeRestore's revision-history chrome. The file - // used no translation hook at all, so every one of these read English in - // every session; swept in one pass rather than converting the timestamps - // alone. `Cancel`, `(empty)` and the empty-value dash reuse the keys this - // namespace already has, so only these ten are new. - revisionHistory: '수정 기록', - noRevisions: '기록된 수정 없음', - revisionFieldsChanged: '필드 {{count}}개 변경됨', - revisionFieldsChangedOne: '필드 {{count}}개 변경됨', - revisionPreview: '수정 미리보기', - revisionSnapshot: '이 시점의 레코드 상태', - restoreConfirm: '레코드를 {{when}} 시점의 상태로 복원합니다. 계속하시겠습니까?', - restoring: '복원 중…', - confirmRestore: '복원 확인', - restoreToPoint: '이 시점으로 복원', }, chart: { loading: "차트 로딩 중…", diff --git a/packages/i18n/src/locales/pt.ts b/packages/i18n/src/locales/pt.ts index 82a2d61863..21d4b164a7 100644 --- a/packages/i18n/src/locales/pt.ts +++ b/packages/i18n/src/locales/pt.ts @@ -957,7 +957,6 @@ const pt = { viewAll: "Ver tudo", new: "Novo", add: "Adicionar", - emptyValue: "—", comments: "Comentários", searchComments: "Pesquisar comentários…", addCommentPlaceholder: "Adicionar comentário… (Ctrl+Enter para enviar)", @@ -990,11 +989,6 @@ const pt = { attachmentsLoadFailed: "Não foi possível carregar os anexos deste registro.", attachmentsApiUnavailable: "A lista de anexos não está disponível neste objeto.", retryLoadAttachments: "Tentar novamente", - unifiedDiff: "Visualização unificada", - sideBySideDiff: "Visualização lado a lado", - noChanges: "Sem alterações", - previousVersion: "Anterior", - currentVersion: "Atual", discussion: "Discussão", showDiscussion: "Mostrar discussão ({{count}})", hideDiscussion: "Ocultar discussão", @@ -1009,13 +1003,7 @@ const pt = { writeComment: "Escreva um comentário…", subscribedTooltip: "Inscrito — clique para cancelar inscrição", unsubscribedTooltip: "Inscrever-se para notificações", - firstRecord: "Primeiro registro (Home)", - previousRecordKey: "Registro anterior (←)", - nextRecordKey: "Próximo registro (→)", - lastRecord: "Último registro (End)", noRecords: "Sem registros", - searchWhileNavigating: "Pesquisar durante a navegação", - searchRecords: "Pesquisar registros…", allActivity: "Toda atividade", commentsOnly: "Apenas comentários", fieldChangesFilter: "Alterações de campo", @@ -1127,21 +1115,6 @@ const pt = { fileCount: "{{count}} arquivos", fileCount_one: "{{count}} arquivo", fileCount_other: "{{count}} arquivos", - // objectui#7163 — PointInTimeRestore's revision-history chrome. The file - // used no translation hook at all, so every one of these read English in - // every session; swept in one pass rather than converting the timestamps - // alone. `Cancel`, `(empty)` and the empty-value dash reuse the keys this - // namespace already has, so only these ten are new. - revisionHistory: 'Histórico de revisões', - noRevisions: 'Nenhuma revisão registrada', - revisionFieldsChanged: '{{count}} campos alterados', - revisionFieldsChangedOne: '{{count}} campo alterado', - revisionPreview: 'Pré-visualização da revisão', - revisionSnapshot: 'Estado do registro neste ponto', - restoreConfirm: 'Isto restaurará o registro ao seu estado de {{when}}. Continuar?', - restoring: 'Restaurando…', - confirmRestore: 'Confirmar restauração', - restoreToPoint: 'Restaurar para este ponto', }, chart: { loading: "Carregando gráfico…", diff --git a/packages/i18n/src/locales/ru.ts b/packages/i18n/src/locales/ru.ts index e7d8d5ee50..c7d15af0f6 100644 --- a/packages/i18n/src/locales/ru.ts +++ b/packages/i18n/src/locales/ru.ts @@ -971,7 +971,6 @@ const ru = { viewAll: "Показать все", new: "Создать", add: "Добавить", - emptyValue: "—", activity: "Активность", editRow: "Редактировать", deleteRow: "Удалить", @@ -1016,11 +1015,6 @@ const ru = { attachmentsLoadFailed: "Не удалось загрузить вложения этой записи.", attachmentsApiUnavailable: "Список вложений недоступен для этого объекта.", retryLoadAttachments: "Повторить", - unifiedDiff: "Единое представление", - sideBySideDiff: "Параллельное представление", - noChanges: "Нет изменений", - previousVersion: "Предыдущая", - currentVersion: "Текущая", discussion: "Обсуждение", showDiscussion: "Показать обсуждение ({{count}})", hideDiscussion: "Скрыть обсуждение", @@ -1035,13 +1029,7 @@ const ru = { writeComment: "Написать комментарий…", subscribedTooltip: "Подписаны — нажмите для отписки", unsubscribedTooltip: "Подписаться на уведомления", - firstRecord: "Первая запись (Home)", - previousRecordKey: "Предыдущая запись (←)", - nextRecordKey: "Следующая запись (→)", - lastRecord: "Последняя запись (End)", noRecords: "Нет записей", - searchWhileNavigating: "Поиск при навигации", - searchRecords: "Поиск записей…", allActivity: "Вся активность", commentsOnly: "Только комментарии", fieldChangesFilter: "Изменения полей", @@ -1145,21 +1133,6 @@ const ru = { fileCount: "Файлов: {{count}}", fileCount_one: "{{count}} файл", fileCount_other: "{{count}} файлов", - // objectui#7163 — PointInTimeRestore's revision-history chrome. The file - // used no translation hook at all, so every one of these read English in - // every session; swept in one pass rather than converting the timestamps - // alone. `Cancel`, `(empty)` and the empty-value dash reuse the keys this - // namespace already has, so only these ten are new. - revisionHistory: 'История версий', - noRevisions: 'Нет зарегистрированных версий', - revisionFieldsChanged: 'Изменено полей: {{count}}', - revisionFieldsChangedOne: 'Изменено полей: {{count}}', - revisionPreview: 'Предпросмотр версии', - revisionSnapshot: 'Состояние записи на этот момент', - restoreConfirm: 'Запись будет восстановлена до состояния на {{when}}. Продолжить?', - restoring: 'Восстановление…', - confirmRestore: 'Подтвердить восстановление', - restoreToPoint: 'Восстановить до этого момента', }, chart: { loading: "Загрузка графика…", diff --git a/packages/i18n/src/locales/zh.ts b/packages/i18n/src/locales/zh.ts index 0db2e1b49c..10e52163bd 100644 --- a/packages/i18n/src/locales/zh.ts +++ b/packages/i18n/src/locales/zh.ts @@ -1022,7 +1022,6 @@ const zh = { viewAll: '查看全部', new: '新建', add: '添加', - emptyValue: '—', activity: '活动', history: '历史', historyEmpty: '暂无历史记录', @@ -1083,11 +1082,6 @@ const zh = { attachmentsApiUnavailable: '此对象上的附件列表不可用。', retryLoadAttachments: '重试', // Diff - unifiedDiff: '统一视图', - sideBySideDiff: '并排视图', - noChanges: '无变更', - previousVersion: '旧版本', - currentVersion: '新版本', // Discussion discussion: '讨论', showDiscussion: '显示讨论 ({{count}})', @@ -1106,18 +1100,12 @@ const zh = { subscribedTooltip: '已订阅 — 点击取消订阅', unsubscribedTooltip: '订阅通知', // Navigation - firstRecord: '第一条记录 (Home)', - previousRecordKey: '上一条记录 (←)', - nextRecordKey: '下一条记录 (→)', - lastRecord: '最后一条记录 (End)', noRecords: '无记录', // objectui#3863 — base key. zh has a single plural category (`other`), so this // slot is unreachable here and equals `_other` for key-set parity. showEmptyRelated: '+ {{count}} 个为空', showEmptyRelated_one: '+ {{count}} 个为空', showEmptyRelated_other: '+ {{count}} 个为空', - searchWhileNavigating: '导航时搜索', - searchRecords: '搜索记录…', // Activity timeline allActivity: '全部动态', commentsOnly: '仅评论', @@ -1167,21 +1155,6 @@ const zh = { fileCount: '{{count}} 个文件', fileCount_one: '{{count}} 个文件', fileCount_other: '{{count}} 个文件', - // objectui#7163 — PointInTimeRestore's revision-history chrome. The file - // used no translation hook at all, so every one of these read English in - // every session; swept in one pass rather than converting the timestamps - // alone. `Cancel`, `(empty)` and the empty-value dash reuse the keys this - // namespace already has, so only these ten are new. - revisionHistory: '修订历史', - noRevisions: '暂无修订记录', - revisionFieldsChanged: '已更改 {{count}} 个字段', - revisionFieldsChangedOne: '已更改 {{count}} 个字段', - revisionPreview: '修订预览', - revisionSnapshot: '此时间点的记录状态', - restoreConfirm: '这会将记录恢复到 {{when}} 时的状态。是否继续?', - restoring: '正在恢复…', - confirmRestore: '确认恢复', - restoreToPoint: '恢复到此时间点', }, chart: { loading: '图表加载中…', diff --git a/packages/plugin-detail/src/CommentInput.tsx b/packages/plugin-detail/src/CommentInput.tsx deleted file mode 100644 index e3329c8256..0000000000 --- a/packages/plugin-detail/src/CommentInput.tsx +++ /dev/null @@ -1,81 +0,0 @@ -/** - * 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. - */ - -import * as React from 'react'; -import { cn, Button } from '@object-ui/components'; -import { Send } from 'lucide-react'; - -export interface CommentInputProps { - /** Called when a comment is submitted */ - onSubmit: (text: string) => void | Promise; - /** Placeholder text */ - placeholder?: string; - /** Whether the input is disabled */ - disabled?: boolean; - className?: string; -} - -/** - * CommentInput — Simple comment input component. - * Renders a "Leave a comment" textarea with submit button. - * Supports Ctrl+Enter to submit. - */ -export const CommentInput: React.FC = ({ - onSubmit, - placeholder = 'Leave a comment…', - disabled = false, - className, -}) => { - const [text, setText] = React.useState(''); - const [isSubmitting, setIsSubmitting] = React.useState(false); - - const handleSubmit = React.useCallback(async () => { - const value = text.trim(); - if (!value) return; - setIsSubmitting(true); - try { - await onSubmit(value); - setText(''); - } finally { - setIsSubmitting(false); - } - }, [text, onSubmit]); - - const handleKeyDown = React.useCallback( - (e: React.KeyboardEvent) => { - if (e.key === 'Enter' && (e.ctrlKey || e.metaKey)) { - e.preventDefault(); - handleSubmit(); - } - }, - [handleSubmit], - ); - - return ( -
-