diff --git a/l10n/en_US.json b/l10n/en_US.json new file mode 100644 index 00000000..34023266 --- /dev/null +++ b/l10n/en_US.json @@ -0,0 +1,235 @@ +{ + "translations": { + "OpenBuilt settings": "OpenBuilt settings", + "Configure the app settings": "Configure the app settings", + "Configuration": "Configuration", + "Completed": "Completed", + "Dashboard": "Dashboard", + "Due this week": "Due this week", + "Open items": "Open items", + "Placeholder: comment added": "Placeholder: comment added", + "Placeholder: status changed to Review": "Placeholder: status changed to Review", + "Placeholder: user opened a record": "Placeholder: user opened a record", + "Quick actions": "Quick actions", + "Recent activity": "Recent activity", + "Starter overview with sample KPIs and activity placeholders. Replace this view with your own data.": "Starter overview with sample KPIs and activity placeholders. Replace this view with your own data.", + "Team members": "Team members", + "Wire buttons here to create records, open lists, or deep links. Use the sidebar for Settings and Documentation.": "Wire buttons here to create records, open lists, or deep links. Use the sidebar for Settings and Documentation.", + "sample": "sample", + "Documentation": "Documentation", + "General": "General", + "Install OpenRegister": "Install OpenRegister", + "No settings available yet": "No settings available yet", + "OpenRegister is required": "OpenRegister is required", + "OpenRegister register ID": "OpenRegister register ID", + "Register": "Register", + "Save": "Save", + "Settings": "Settings", + "Settings saved successfully": "Settings saved successfully", + "Saving...": "Saving...", + "Saving…": "Saving…", + "This app needs OpenRegister to store and manage data. Please install OpenRegister from the app store to get started.": "This app needs OpenRegister to store and manage data. Please install OpenRegister from the app store to get started.", + "User settings will appear here in a future update.": "User settings will appear here in a future update.", + "Version Information": "Version Information", + "Information about the current OpenBuilt installation": "Information about the current OpenBuilt installation", + "Support": "Support", + "For support, contact us at": "For support, contact us at", + + "Virtual apps": "Virtual apps", + "No virtual apps yet — seed `hello-world` should appear after install.": "No virtual apps yet — seed `hello-world` should appear after install.", + "Status": "Status", + "Version": "Version", + "Integrator-only editor: edit the raw JSON manifest below. The visual editor lives in a follow-on release (openbuilt-page-editor).": "Integrator-only editor: edit the raw JSON manifest below. The visual editor lives in a follow-on release (openbuilt-page-editor).", + "Paste or edit the JSON manifest here. See @conduction/nextcloud-vue/src/schemas/app-manifest.schema.json for the canonical schema.": "Paste or edit the JSON manifest here. See @conduction/nextcloud-vue/src/schemas/app-manifest.schema.json for the canonical schema.", + "Invalid manifest": "Invalid manifest", + "Open virtual app": "Open virtual app", + "Publish": "Publish", + "Publishing…": "Publishing…", + "draft": "draft", + "published": "published", + "archived": "archived", + "modified since last publish": "modified since last publish", + "Editor": "Editor", + "Version history": "Version history", + "Diff": "Diff", + "Published version {uuid}": "Published version {uuid}", + "No versions yet — publish this app to create the first snapshot.": "No versions yet — publish this app to create the first snapshot.", + "Roll back to this version": "Roll back to this version", + "Compare with current draft": "Compare with current draft", + "Published": "Published", + "By": "By", + "Loading…": "Loading…", + "Roll back to version {version}?": "Roll back to version {version}?", + "Rolling back copies this snapshot's manifest onto the current draft. Existing history is preserved (append-only).": "Rolling back copies this snapshot's manifest onto the current draft. Existing history is preserved (append-only).", + "Roll back": "Roll back", + "Manifest diff": "Manifest diff", + "Nothing to diff — publish the app first.": "Nothing to diff — publish the app first.", + "From": "From", + "To": "To", + "Current draft": "Current draft", + "Loading diff…": "Loading diff…", + "Role": "Role", + "Owner": "Owner", + "Viewer": "Viewer", + "No access": "No access", + "No applications available — ask an owner to grant you access.": "No applications available — ask an owner to grant you access.", + "Permissions": "Permissions", + "Manage permissions": "Manage permissions", + "Configure which Nextcloud groups can view, edit, or own this virtual app. Members of any of these groups will see the app in their list; only owners may publish, archive, delete, transfer ownership, or change these permissions.": "Configure which Nextcloud groups can view, edit, or own this virtual app. Members of any of these groups will see the app in their list; only owners may publish, archive, delete, transfer ownership, or change these permissions.", + "Owners (full control)": "Owners (full control)", + "Editors (can save drafts)": "Editors (can save drafts)", + "Viewers (read-only)": "Viewers (read-only)", + "Save permissions": "Save permissions", + "Saving permissions…": "Saving permissions…", + "Cancel": "Cancel", + "At least one owner group is required — saving with no owners would orphan this application.": "At least one owner group is required — saving with no owners would orphan this application.", + "Editor or owner role required to save the manifest.": "Editor or owner role required to save the manifest.", + "Your access to this application was revoked. The list will refresh.": "Your access to this application was revoked. The list will refresh.", + "Schemas": "Schemas", + "Add schema": "Add schema", + "Delete schema": "Delete schema", + "Delete property": "Delete property", + "Schema slug": "Schema slug", + "kebab-case, e.g. customer": "kebab-case, e.g. customer", + "Slug must be kebab-case (lowercase letters, digits, hyphens) and start with a letter.": "Slug must be kebab-case (lowercase letters, digits, hyphens) and start with a letter.", + "Title": "Title", + "Title is required.": "Title is required.", + "Description": "Description", + "Optional": "Optional", + "Version (semver)": "Version (semver)", + "Version must follow semver MAJOR.MINOR.PATCH.": "Version must follow semver MAJOR.MINOR.PATCH.", + "A schema with this slug already exists in this app.": "A schema with this slug already exists in this app.", + "Failed to add schema.": "Failed to add schema.", + "No schemas yet": "No schemas yet", + "Add your first schema to start designing the data model for this app.": "Add your first schema to start designing the data model for this app.", + "v{version}": "v{version}", + "{n} property": "{n} property", + "{n} properties": "{n} properties", + "{n} lifecycle state": "{n} lifecycle state", + "{n} lifecycle states": "{n} lifecycle states", + "No lifecycle": "No lifecycle", + "Open": "Open", + "Delete": "Delete", + "You are about to remove the property {name} from this schema. Existing objects of this schema may have data in this property that will become unreachable after Save.": "You are about to remove the property {name} from this schema. Existing objects of this schema may have data in this property that will become unreachable after Save.", + "You are about to delete the schema {slug}. All objects of this schema may be affected. Type the schema slug below to confirm.": "You are about to delete the schema {slug}. All objects of this schema may be affected. Type the schema slug below to confirm.", + "Type the slug to confirm": "Type the slug to confirm", + "Back to schemas": "Back to schemas", + "Discard staged edits": "Discard staged edits", + "Schema not found": "Schema not found", + "No schema with this slug exists in the current virtual app.": "No schema with this slug exists in the current virtual app.", + "Fields": "Fields", + "Add field": "Add field", + "No fields yet. Add the first property to your schema.": "No fields yet. Add the first property to your schema.", + "Move up": "Move up", + "Move down": "Move down", + "Name": "Name", + "Name is required.": "Name is required.", + "Name must start with a letter and use letters, digits, underscores, or hyphens only.": "Name must start with a letter and use letters, digits, underscores, or hyphens only.", + "Name must be unique within the schema.": "Name must be unique within the schema.", + "Type": "Type", + "Required": "Required", + "Format (optional)": "Format (optional)", + "Pattern (regex, optional)": "Pattern (regex, optional)", + "Min length": "Min length", + "Max length": "Max length", + "Minimum": "Minimum", + "Maximum": "Maximum", + "Multiple of": "Multiple of", + "Items type": "Items type", + "Min items": "Min items", + "Max items": "Max items", + "Target schema": "Target schema", + "Cardinality": "Cardinality", + "One": "One", + "Many": "Many", + "Inverse-of property (optional)": "Inverse-of property (optional)", + "Remove field": "Remove field", + "(unnamed)": "(unnamed)", + "string": "string", + "number": "number", + "integer": "integer", + "boolean": "boolean", + "array": "array", + "object": "object", + "relation": "relation", + "Lifecycle": "Lifecycle", + "Declare states and transitions. Every action is a typed declarative record per ADR-031 — no free-text code.": "Declare states and transitions. Every action is a typed declarative record per ADR-031 — no free-text code.", + "States": "States", + "Add state": "Add state", + "No states yet.": "No states yet.", + "Initial": "Initial", + "State slug": "State slug", + "State slug must be kebab-case and unique.": "State slug must be kebab-case and unique.", + "Label": "Label", + "Exactly one initial state is required.": "Exactly one initial state is required.", + "Exactly one lifecycle state must be marked as initial before you can save.": "Exactly one lifecycle state must be marked as initial before you can save.", + "Transitions": "Transitions", + "Add transition": "Add transition", + "No transitions yet.": "No transitions yet.", + "Label (optional)": "Label (optional)", + "On-transition actions": "On-transition actions", + "Add action": "Add action", + "No actions on this transition.": "No actions on this transition.", + "Action type": "Action type", + "Payload key (declarative)": "Payload key (declarative)", + "e.g. event name, template slug": "e.g. event name, template slug", + "audit-event-emit": "audit-event-emit", + "notification-send": "notification-send", + "related-object-upsert": "related-object-upsert", + "related-object-archive": "related-object-archive", + "webhook-dispatch": "webhook-dispatch", + "Relations": "Relations", + "Add relation": "Add relation", + "No relations yet.": "No relations yet.", + "Relation name": "Relation name", + "Inverse-of (optional)": "Inverse-of (optional)", + "Widgets": "Widgets", + "Add widget": "Add widget", + "No widget catalogue registered yet — widget IDs are free-text. The page editor (chain spec #5) will narrow this to a picker once it ships.": "No widget catalogue registered yet — widget IDs are free-text. The page editor (chain spec #5) will narrow this to a picker once it ships.", + "No widgets yet.": "No widgets yet.", + "Slot": "Slot", + "Widget id": "Widget id", + "Config (JSON)": "Config (JSON)", + "Config must be valid JSON.": "Config must be valid JSON.", + "Aggregations": "Aggregations", + "The aggregation editor ships in v1.1 (see design Decision 7). Existing aggregations declared on this schema are shown read-only below.": "The aggregation editor ships in v1.1 (see design Decision 7). Existing aggregations declared on this schema are shown read-only below.", + "No aggregations declared on this schema.": "No aggregations declared on this schema.", + "Calculations": "Calculations", + "The calculation editor ships in v1.1 (see design Decision 7). Existing calculations declared on this schema are shown read-only below.": "The calculation editor ships in v1.1 (see design Decision 7). Existing calculations declared on this schema are shown read-only below.", + "No calculations declared on this schema.": "No calculations declared on this schema.", + "Notifications": "Notifications", + "The notification editor ships in v1.1 (see design Decision 7). Existing notifications declared on this schema are shown read-only below.": "The notification editor ships in v1.1 (see design Decision 7). Existing notifications declared on this schema are shown read-only below.", + "No notifications declared on this schema.": "No notifications declared on this schema.", + "Failed to load schemas: {error}": "Failed to load schemas: {error}", + "Failed to load schema: {error}": "Failed to load schema: {error}", + "Schema {slug} created.": "Schema {slug} created.", + "Schema {slug} deleted.": "Schema {slug} deleted.", + "Failed to delete schema: {error}": "Failed to delete schema: {error}", + "Schema saved.": "Schema saved.", + "Export application": "Export application", + "Target": "Target", + "ZIP download": "ZIP download", + "Push to GitHub": "Push to GitHub", + "License": "License", + "GitHub organisation": "GitHub organisation", + "Repository name": "Repository name", + "Visibility": "Visibility", + "Public": "Public", + "Private": "Private", + "GitHub personal access token": "GitHub personal access token", + "The token needs the repo scope. It is sent once over your Nextcloud session, stored encrypted via the credentials manager, and deleted automatically when the export finishes.": "The token needs the repo scope. It is sent once over your Nextcloud session, stored encrypted via the credentials manager, and deleted automatically when the export finishes.", + "Include seed data": "Include seed data", + "Start export": "Start export", + "Queued": "Queued", + "Running": "Running", + "Succeeded": "Succeeded", + "Failed": "Failed", + "Download ZIP": "Download ZIP", + "View pull request": "View pull request", + "Unknown application version.": "Unknown application version.", + "Draft versions cannot be exported.": "Draft versions cannot be exported.", + "Repository already exists in the target organisation.": "Repository already exists in the target organisation.", + "GitHub authentication failed. Please check the token scope and try again.": "GitHub authentication failed. Please check the token scope and try again." + }, + "plurals": "" +} diff --git a/src/main.js b/src/main.js index 26e6e1a2..bd68eae9 100644 --- a/src/main.js +++ b/src/main.js @@ -16,17 +16,35 @@ import './assets/app.css' Vue.mixin({ methods: { t, n } }) Vue.use(PiniaVuePlugin) -loadTranslations('openbuilt', () => { - // Create Vue instance to activate Pinia context, then initialize stores. - const app = new Vue({ - pinia, - router, - render: h => h(App), - }) - - // Mount immediately so the App renders (NC32 needs #content to be taken over). - app.$mount('#content') - - // Initialize stores after mount. - initializeStores() +// Fire-and-forget translation load. `@nextcloud/l10n`'s loadTranslations() +// fetches l10n/.json (e.g. en_US.json) and the returned promise +// rejects on a 404. The app ships en.json / en_US.json / nl.json; any other +// locale just falls back to the English source strings. Boot MUST NOT depend +// on this resolving — chaining $mount inside loadTranslations meant the whole +// app silently failed to render whenever the locale bundle was missing. +function tryLoadTranslations() { + try { + const result = loadTranslations('openbuilt', () => {}) + if (result && typeof result.then === 'function') { + result.then(() => {}, () => {}) + } + } catch { + // no-op — translations are best-effort + } +} + +tryLoadTranslations() + +// Create the Vue instance, activate Pinia, mount, then initialise stores. +const app = new Vue({ + pinia, + router, + render: h => h(App), }) + +// Mount immediately so the App renders (NC32 needs #content to be taken over). +app.$mount('#content') + +// Initialise stores after mount. (App.vue also calls this in created() — it is +// idempotent, so the two calls are safe; this one keeps the contract explicit.) +initializeStores()