Skip to content

v0.2.0

Choose a tag to compare

@github-actions github-actions released this 30 Apr 15:38
d58eb9d
  • @lowdefy/modules-mongodb-plugins: ### Minor Changes

  • #14 1c912ee Thanks @JohannMoller! - Add ContactSelector block and wire it into the contacts module as a reusable picker (contacts.contact-selector component). Search runs against an Atlas $search + $match pipeline (search_contacts), enrichment via get_contacts_data, and add/edit go through the existing create-contact / update-contact APIs (patched to accept the picker's payload shape). The companies form now consumes the picker for linked contacts.

    Breaking — contacts module vars renamed:

    • all_contacts (module, default false, company-scoped) → per-call company_only_contacts (default false, unscoped). The default flipped: callers that relied on the old company-scoped default must now pass company_only_contacts: true explicitly.
    • verified (module enum off|trusted|untrusted) → use_verified (module boolean, default false) + per-call verified (boolean). The module flag toggles the verification UI/payload writes globally; per-call verified decides the value each picker instance writes.
    • Removed: module-level phone_label (no-op since Task 4) and the per-call payload var (deprecated by per-key var pass-through).

    Migration:

    all_contacts: false       →  company_only_contacts: true   (per-call)
    all_contacts: true        →  company_only_contacts: false  (per-call, or omit)
    verified: trusted         →  use_verified: true (module) + verified: true  (per-call)
    verified: untrusted       →  use_verified: true (module) + verified: false (per-call)
    verified: off             →  use_verified: false (module, default)
    

Patch Changes

  • #25 ac1d28a Thanks @Yianni99! - Bump @lowdefy/block-utils, @lowdefy/blocks-antd, @lowdefy/blocks-basic, @lowdefy/helpers, and @lowdefy/nunjucks peer-dep pins from 0.0.0-experimental-20260421070726 to 0.0.0-experimental-20260429140004.

  • #27 4d3eff1 Thanks @Yianni99! - Improve the EventsTimeline block and events-timeline component:

    • New block properties: compact (boolean, default false) renders smaller avatars and tighter padding, and applies an events-timeline-compact class on the root for additional dense styling; contactPageUrl (string) is a URL template for linking each user avatar and timestamp to a contact page, supporting {id} substitution and falling back to appending ?_id=<userId>; disableContactLink (boolean, default false) opts out of the contact-page wrapping per call. Avatars are also wrapped in a Popover showing the user's name on hover.
    • Component vars: the events-timeline component exposes the new properties via contact_page_url module var and per-call _var overrides (contact_page_url, disable_contact_link, compact). All defaults are off, so existing consumers see no change.
    • Fix: get-events request never fired because the component declared the request but had no onMount Request action to trigger it. Added the trigger.
    • Fix: Avatar didn't render for events without a description — the React EventTimelineItem only included <Avatar> inside the EventDescription branch. Restructured so the title-only branch also renders the avatar.
  • #19 46234e1 Thanks @JohannMoller! - Rewrite the two linked-record sidebar tiles — contacts on company-detail and companies on contact-detail — from a broken antd-style List (properties.dataSource + properties.renderItem) to a plain Html block. Both tiles previously rendered blank; both now list the linked records with name + email / display name and link through to the record's detail page using _module.pageId.

    Adds an optional { label, value } extension slot per tile under each module's components var group:

    • components.contact_card_extra_fields on the companies module — appends rows under each contact's name/email on the company-detail tile.
    • components.company_card_extra_fields on the contacts module — appends rows under each company's display name on the contact-detail tile.

    value must be a top-level key on the document as projected by get_company_contacts / get_contact_companies. Falsy primitives (0, false, "") render; only null/undefined are skipped.

    Plugin housekeeping: declare @lowdefy/nunjucks as a peer dependency of @lowdefy/modules-mongodb-plugins. The plugin's parseNunjucks.js imports it but the package wasn't declared anywhere — Turbopack failed to resolve it on fresh installs.

  • #29 cd7e574 Thanks @SamTolmay! - Remove the unused DataDescriptions block from @lowdefy/modules-mongodb-plugins. The block was exported by the plugin but not referenced by any module or app in this repo; SmartDescriptions covers the in-repo use cases. Consumers still importing DataDescriptions from this plugin should switch to SmartDescriptions or pin to ^0.1.1.

  • #28 2c4aa70 Thanks @Yianni99! - Rename module pages from entity-prefixed IDs to semantic verbs to remove the redundant URL prefix (e.g. /companies/companies/companies/all). Module pages now use all, view, edit, new consistently. Cross-module references via _module.pageId: and hardcoded scoped page IDs ({entry-id}/{page-id}) must be updated to the new IDs.

    Page ID changes per module:

    • companies: companiesall, company-detailview, company-editedit, company-newnew
    • contacts: contactsall, contact-detailview, contact-editedit, contact-newnew
    • user-admin: usersall, users-viewview, users-editedit, users-invitenew, check-invite-emailcheck
    • user-account: profileview, edit-profileedit, create-profilenew (login/logout/verify-email-request unchanged)
    • release-notes: release-notesview
    • notifications: inboxall (link/invalid unchanged)

    Plugin defaults updated to match: SmartDescriptions now defaults contactDetailPageId to contacts/view and companyDetailPageId to companies/view; EventsTimeline schema example updated.

    Also includes two fixes to the contacts new page: removed a duplicate avatar render (the avatar block was included both directly and via form_profile), and fixed the post-create redirect that was navigating with a null _id because CallAPI return values are accessed at _actions: <id>.response.response.<field>, not .response.<field>. Same redirect fix applied to the companies new page.

  • #31 fcd328b Thanks @Yianni99! - Small UX fixes across modules and the EventsTimeline block:

    • release-notes: Empty-state fallback now triggers when content is null OR an empty/whitespace-only string. The previous _if_none only caught null, so consumers with an empty CHANGELOG.md saw a blank Card instead of the "No release notes available yet" message.
    • companies / contacts / user-admin table components: Added a conditional overlayNoRowsTemplate that renders "Loading…" while the get_all_* request is in flight and "No rows" once the request completes empty. Previously AG Grid's default "No Rows To Show" appeared during the initial load, indistinguishable from a genuinely empty result.
    • EventsTimeline (plugin): Avatar hover swapped from <Popover> to <Tooltip> so it matches the timestamp's TimeAgo style — same name-on-hover, lighter dark-tooltip styling.
  • @lowdefy/modules-mongodb-companies: ### Minor Changes

  • #29 f9a4078 Thanks @SamTolmay! - Remove the collection var from the companies, events, and files modules. Each module's MongoDB collection name is now hardcoded in its connection file (companies, log-events, files respectively). Consumers can no longer rename the underlying collection through vars.collection — to point a module at a different collection, remap its connection (companies-collection, events-collection, files-collection) via the module entry's connections mapping in lowdefy.yaml.

    Breaking: apps that previously set vars.collection on any of these modules must remove it. If a non-default collection name was in use, switch to a connections remap on the module entry.

  • #29 2855113 Thanks @SamTolmay! - Remove the data-upload module. The module has been deleted from the repo along with its pages, components, requests, connections, menus, and event-type enums. Consumers using data-upload should pin to the previous release tag or vendor the module locally. Cross-references from modules/shared/enums/event_types.yaml, apps/demo/modules.yaml, the root README.md, docs/idioms.md, and the demo .claude/guides/*.md have been removed. The SYNC_S3_* secrets are no longer documented.

  • #28 2c4aa70 Thanks @Yianni99! - Rename module pages from entity-prefixed IDs to semantic verbs to remove the redundant URL prefix (e.g. /companies/companies/companies/all). Module pages now use all, view, edit, new consistently. Cross-module references via _module.pageId: and hardcoded scoped page IDs ({entry-id}/{page-id}) must be updated to the new IDs.

    Page ID changes per module:

    • companies: companiesall, company-detailview, company-editedit, company-newnew
    • contacts: contactsall, contact-detailview, contact-editedit, contact-newnew
    • user-admin: usersall, users-viewview, users-editedit, users-invitenew, check-invite-emailcheck
    • user-account: profileview, edit-profileedit, create-profilenew (login/logout/verify-email-request unchanged)
    • release-notes: release-notesview
    • notifications: inboxall (link/invalid unchanged)

    Plugin defaults updated to match: SmartDescriptions now defaults contactDetailPageId to contacts/view and companyDetailPageId to companies/view; EventsTimeline schema example updated.

    Also includes two fixes to the contacts new page: removed a duplicate avatar render (the avatar block was included both directly and via form_profile), and fixed the post-create redirect that was navigating with a null _id because CallAPI return values are accessed at _actions: <id>.response.response.<field>, not .response.<field>. Same redirect fix applied to the companies new page.

Patch Changes

  • #14 1c912ee Thanks @JohannMoller! - Add ContactSelector block and wire it into the contacts module as a reusable picker (contacts.contact-selector component). Search runs against an Atlas $search + $match pipeline (search_contacts), enrichment via get_contacts_data, and add/edit go through the existing create-contact / update-contact APIs (patched to accept the picker's payload shape). The companies form now consumes the picker for linked contacts.

    Breaking — contacts module vars renamed:

    • all_contacts (module, default false, company-scoped) → per-call company_only_contacts (default false, unscoped). The default flipped: callers that relied on the old company-scoped default must now pass company_only_contacts: true explicitly.
    • verified (module enum off|trusted|untrusted) → use_verified (module boolean, default false) + per-call verified (boolean). The module flag toggles the verification UI/payload writes globally; per-call verified decides the value each picker instance writes.
    • Removed: module-level phone_label (no-op since Task 4) and the per-call payload var (deprecated by per-key var pass-through).

    Migration:

    all_contacts: false       →  company_only_contacts: true   (per-call)
    all_contacts: true        →  company_only_contacts: false  (per-call, or omit)
    verified: trusted         →  use_verified: true (module) + verified: true  (per-call)
    verified: untrusted       →  use_verified: true (module) + verified: false (per-call)
    verified: off             →  use_verified: false (module, default)
    
  • #27 24b8dd1 Thanks @Yianni99! - Fix silent empty display payload on every event-emitting endpoint. The _build.array.map callback that builds per-app event display titles returned {key, value} objects, which _build.object.fromEntries (native Object.fromEntries) silently rejected as {} — so events landed in MongoDB without title or description. Switched callback bodies to a 2-element [key, value] array tuple to match the spec, and quoted "0.0" so YAML parses it as a path string instead of the float 0. Affects 9 endpoints: contacts/api/{create,update}-contact, companies/api/{create,update}-company, user-admin/api/{invite,update}-user, user-admin/api/resend-invite, user-account/api/{create,update}-profile. Also fixed two latent typos (_result_step) in user-account/api/{create,update}-profile.yaml that were hidden by the silent failure.

  • #19 46234e1 Thanks @JohannMoller! - Rewrite the two linked-record sidebar tiles — contacts on company-detail and companies on contact-detail — from a broken antd-style List (properties.dataSource + properties.renderItem) to a plain Html block. Both tiles previously rendered blank; both now list the linked records with name + email / display name and link through to the record's detail page using _module.pageId.

    Adds an optional { label, value } extension slot per tile under each module's components var group:

    • components.contact_card_extra_fields on the companies module — appends rows under each contact's name/email on the company-detail tile.
    • components.company_card_extra_fields on the contacts module — appends rows under each company's display name on the contact-detail tile.

    value must be a top-level key on the document as projected by get_company_contacts / get_contact_companies. Falsy primitives (0, false, "") render; only null/undefined are skipped.

    Plugin housekeeping: declare @lowdefy/nunjucks as a peer dependency of @lowdefy/modules-mongodb-plugins. The plugin's parseNunjucks.js imports it but the package wasn't declared anywhere — Turbopack failed to resolve it on fresh installs.

  • #31 fcd328b Thanks @Yianni99! - Small UX fixes across modules and the EventsTimeline block:

    • release-notes: Empty-state fallback now triggers when content is null OR an empty/whitespace-only string. The previous _if_none only caught null, so consumers with an empty CHANGELOG.md saw a blank Card instead of the "No release notes available yet" message.
    • companies / contacts / user-admin table components: Added a conditional overlayNoRowsTemplate that renders "Loading…" while the get_all_* request is in flight and "No rows" once the request completes empty. Previously AG Grid's default "No Rows To Show" appeared during the initial load, indistinguishable from a genuinely empty result.
    • EventsTimeline (plugin): Avatar hover swapped from <Popover> to <Tooltip> so it matches the timestamp's TimeAgo style — same name-on-hover, lighter dark-tooltip styling.
  • @lowdefy/modules-mongodb-contacts: ### Minor Changes

  • #14 1c912ee Thanks @JohannMoller! - Add ContactSelector block and wire it into the contacts module as a reusable picker (contacts.contact-selector component). Search runs against an Atlas $search + $match pipeline (search_contacts), enrichment via get_contacts_data, and add/edit go through the existing create-contact / update-contact APIs (patched to accept the picker's payload shape). The companies form now consumes the picker for linked contacts.

    Breaking — contacts module vars renamed:

    • all_contacts (module, default false, company-scoped) → per-call company_only_contacts (default false, unscoped). The default flipped: callers that relied on the old company-scoped default must now pass company_only_contacts: true explicitly.
    • verified (module enum off|trusted|untrusted) → use_verified (module boolean, default false) + per-call verified (boolean). The module flag toggles the verification UI/payload writes globally; per-call verified decides the value each picker instance writes.
    • Removed: module-level phone_label (no-op since Task 4) and the per-call payload var (deprecated by per-key var pass-through).

    Migration:

    all_contacts: false       →  company_only_contacts: true   (per-call)
    all_contacts: true        →  company_only_contacts: false  (per-call, or omit)
    verified: trusted         →  use_verified: true (module) + verified: true  (per-call)
    verified: untrusted       →  use_verified: true (module) + verified: false (per-call)
    verified: off             →  use_verified: false (module, default)
    
  • #28 2c4aa70 Thanks @Yianni99! - Rename module pages from entity-prefixed IDs to semantic verbs to remove the redundant URL prefix (e.g. /companies/companies/companies/all). Module pages now use all, view, edit, new consistently. Cross-module references via _module.pageId: and hardcoded scoped page IDs ({entry-id}/{page-id}) must be updated to the new IDs.

    Page ID changes per module:

    • companies: companiesall, company-detailview, company-editedit, company-newnew
    • contacts: contactsall, contact-detailview, contact-editedit, contact-newnew
    • user-admin: usersall, users-viewview, users-editedit, users-invitenew, check-invite-emailcheck
    • user-account: profileview, edit-profileedit, create-profilenew (login/logout/verify-email-request unchanged)
    • release-notes: release-notesview
    • notifications: inboxall (link/invalid unchanged)

    Plugin defaults updated to match: SmartDescriptions now defaults contactDetailPageId to contacts/view and companyDetailPageId to companies/view; EventsTimeline schema example updated.

    Also includes two fixes to the contacts new page: removed a duplicate avatar render (the avatar block was included both directly and via form_profile), and fixed the post-create redirect that was navigating with a null _id because CallAPI return values are accessed at _actions: <id>.response.response.<field>, not .response.<field>. Same redirect fix applied to the companies new page.

Patch Changes

  • #27 24b8dd1 Thanks @Yianni99! - Fix silent empty display payload on every event-emitting endpoint. The _build.array.map callback that builds per-app event display titles returned {key, value} objects, which _build.object.fromEntries (native Object.fromEntries) silently rejected as {} — so events landed in MongoDB without title or description. Switched callback bodies to a 2-element [key, value] array tuple to match the spec, and quoted "0.0" so YAML parses it as a path string instead of the float 0. Affects 9 endpoints: contacts/api/{create,update}-contact, companies/api/{create,update}-company, user-admin/api/{invite,update}-user, user-admin/api/resend-invite, user-account/api/{create,update}-profile. Also fixed two latent typos (_result_step) in user-account/api/{create,update}-profile.yaml that were hidden by the silent failure.

  • #19 46234e1 Thanks @JohannMoller! - Rewrite the two linked-record sidebar tiles — contacts on company-detail and companies on contact-detail — from a broken antd-style List (properties.dataSource + properties.renderItem) to a plain Html block. Both tiles previously rendered blank; both now list the linked records with name + email / display name and link through to the record's detail page using _module.pageId.

    Adds an optional { label, value } extension slot per tile under each module's components var group:

    • components.contact_card_extra_fields on the companies module — appends rows under each contact's name/email on the company-detail tile.
    • components.company_card_extra_fields on the contacts module — appends rows under each company's display name on the contact-detail tile.

    value must be a top-level key on the document as projected by get_company_contacts / get_contact_companies. Falsy primitives (0, false, "") render; only null/undefined are skipped.

    Plugin housekeeping: declare @lowdefy/nunjucks as a peer dependency of @lowdefy/modules-mongodb-plugins. The plugin's parseNunjucks.js imports it but the package wasn't declared anywhere — Turbopack failed to resolve it on fresh installs.

  • #31 fcd328b Thanks @Yianni99! - Small UX fixes across modules and the EventsTimeline block:

    • release-notes: Empty-state fallback now triggers when content is null OR an empty/whitespace-only string. The previous _if_none only caught null, so consumers with an empty CHANGELOG.md saw a blank Card instead of the "No release notes available yet" message.
    • companies / contacts / user-admin table components: Added a conditional overlayNoRowsTemplate that renders "Loading…" while the get_all_* request is in flight and "No rows" once the request completes empty. Previously AG Grid's default "No Rows To Show" appeared during the initial load, indistinguishable from a genuinely empty result.
    • EventsTimeline (plugin): Avatar hover swapped from <Popover> to <Tooltip> so it matches the timestamp's TimeAgo style — same name-on-hover, lighter dark-tooltip styling.
  • @lowdefy/modules-mongodb-events: ### Minor Changes

  • #29 f9a4078 Thanks @SamTolmay! - Remove the collection var from the companies, events, and files modules. Each module's MongoDB collection name is now hardcoded in its connection file (companies, log-events, files respectively). Consumers can no longer rename the underlying collection through vars.collection — to point a module at a different collection, remap its connection (companies-collection, events-collection, files-collection) via the module entry's connections mapping in lowdefy.yaml.

    Breaking: apps that previously set vars.collection on any of these modules must remove it. If a non-default collection name was in use, switch to a connections remap on the module entry.

Patch Changes

  • #27 4d3eff1 Thanks @Yianni99! - Improve the EventsTimeline block and events-timeline component:

    • New block properties: compact (boolean, default false) renders smaller avatars and tighter padding, and applies an events-timeline-compact class on the root for additional dense styling; contactPageUrl (string) is a URL template for linking each user avatar and timestamp to a contact page, supporting {id} substitution and falling back to appending ?_id=<userId>; disableContactLink (boolean, default false) opts out of the contact-page wrapping per call. Avatars are also wrapped in a Popover showing the user's name on hover.
    • Component vars: the events-timeline component exposes the new properties via contact_page_url module var and per-call _var overrides (contact_page_url, disable_contact_link, compact). All defaults are off, so existing consumers see no change.
    • Fix: get-events request never fired because the component declared the request but had no onMount Request action to trigger it. Added the trigger.
    • Fix: Avatar didn't render for events without a description — the React EventTimelineItem only included <Avatar> inside the EventDescription branch. Restructured so the title-only branch also renders the avatar.
  • @lowdefy/modules-mongodb-files: ### Minor Changes

  • #29 f9a4078 Thanks @SamTolmay! - Remove the collection var from the companies, events, and files modules. Each module's MongoDB collection name is now hardcoded in its connection file (companies, log-events, files respectively). Consumers can no longer rename the underlying collection through vars.collection — to point a module at a different collection, remap its connection (companies-collection, events-collection, files-collection) via the module entry's connections mapping in lowdefy.yaml.

    Breaking: apps that previously set vars.collection on any of these modules must remove it. If a non-default collection name was in use, switch to a connections remap on the module entry.

  • #29 24580bc Thanks @SamTolmay! - Make s3_region a required var on the files module. Previously files.s3_region had a default of ca-central-1 (later briefly us-east-1). The module now requires the consumer to set s3_region on the module entry — there is no default, and the build will fail if the var is missing.

    Breaking: apps using files must add s3_region to the module's vars block in lowdefy.yaml. Example: vars: { s3_region: us-east-1 }.

Patch Changes

  • #25 a6b13ce Thanks @Yianni99! - Stamp S3 uploads with x-amz-meta-uploaded-by-{id,name,url} metadata so file uploads carry uploader id, display name, and originating page at the bucket level. The files module gains the full set of fields and switches its presigned-post conditions to the array-of-arrays form. Uses _if_none "unknown" fallbacks so unauthenticated uploads still succeed.

  • @lowdefy/modules-mongodb-notifications: ### Minor Changes

  • #28 2c4aa70 Thanks @Yianni99! - Rename module pages from entity-prefixed IDs to semantic verbs to remove the redundant URL prefix (e.g. /companies/companies/companies/all). Module pages now use all, view, edit, new consistently. Cross-module references via _module.pageId: and hardcoded scoped page IDs ({entry-id}/{page-id}) must be updated to the new IDs.

    Page ID changes per module:

    • companies: companiesall, company-detailview, company-editedit, company-newnew
    • contacts: contactsall, contact-detailview, contact-editedit, contact-newnew
    • user-admin: usersall, users-viewview, users-editedit, users-invitenew, check-invite-emailcheck
    • user-account: profileview, edit-profileedit, create-profilenew (login/logout/verify-email-request unchanged)
    • release-notes: release-notesview
    • notifications: inboxall (link/invalid unchanged)

    Plugin defaults updated to match: SmartDescriptions now defaults contactDetailPageId to contacts/view and companyDetailPageId to companies/view; EventsTimeline schema example updated.

    Also includes two fixes to the contacts new page: removed a duplicate avatar render (the avatar block was included both directly and via form_profile), and fixed the post-create redirect that was navigating with a null _id because CallAPI return values are accessed at _actions: <id>.response.response.<field>, not .response.<field>. Same redirect fix applied to the companies new page.

  • @lowdefy/modules-mongodb-release-notes: ### Minor Changes

  • #28 2c4aa70 Thanks @Yianni99! - Rename module pages from entity-prefixed IDs to semantic verbs to remove the redundant URL prefix (e.g. /companies/companies/companies/all). Module pages now use all, view, edit, new consistently. Cross-module references via _module.pageId: and hardcoded scoped page IDs ({entry-id}/{page-id}) must be updated to the new IDs.

    Page ID changes per module:

    • companies: companiesall, company-detailview, company-editedit, company-newnew
    • contacts: contactsall, contact-detailview, contact-editedit, contact-newnew
    • user-admin: usersall, users-viewview, users-editedit, users-invitenew, check-invite-emailcheck
    • user-account: profileview, edit-profileedit, create-profilenew (login/logout/verify-email-request unchanged)
    • release-notes: release-notesview
    • notifications: inboxall (link/invalid unchanged)

    Plugin defaults updated to match: SmartDescriptions now defaults contactDetailPageId to contacts/view and companyDetailPageId to companies/view; EventsTimeline schema example updated.

    Also includes two fixes to the contacts new page: removed a duplicate avatar render (the avatar block was included both directly and via form_profile), and fixed the post-create redirect that was navigating with a null _id because CallAPI return values are accessed at _actions: <id>.response.response.<field>, not .response.<field>. Same redirect fix applied to the companies new page.

Patch Changes

  • #31 fcd328b Thanks @Yianni99! - Small UX fixes across modules and the EventsTimeline block:

    • release-notes: Empty-state fallback now triggers when content is null OR an empty/whitespace-only string. The previous _if_none only caught null, so consumers with an empty CHANGELOG.md saw a blank Card instead of the "No release notes available yet" message.
    • companies / contacts / user-admin table components: Added a conditional overlayNoRowsTemplate that renders "Loading…" while the get_all_* request is in flight and "No rows" once the request completes empty. Previously AG Grid's default "No Rows To Show" appeared during the initial load, indistinguishable from a genuinely empty result.
    • EventsTimeline (plugin): Avatar hover swapped from <Popover> to <Tooltip> so it matches the timestamp's TimeAgo style — same name-on-hover, lighter dark-tooltip styling.
  • @lowdefy/modules-mongodb-user-account: ### Minor Changes

  • #28 2c4aa70 Thanks @Yianni99! - Rename module pages from entity-prefixed IDs to semantic verbs to remove the redundant URL prefix (e.g. /companies/companies/companies/all). Module pages now use all, view, edit, new consistently. Cross-module references via _module.pageId: and hardcoded scoped page IDs ({entry-id}/{page-id}) must be updated to the new IDs.

    Page ID changes per module:

    • companies: companiesall, company-detailview, company-editedit, company-newnew
    • contacts: contactsall, contact-detailview, contact-editedit, contact-newnew
    • user-admin: usersall, users-viewview, users-editedit, users-invitenew, check-invite-emailcheck
    • user-account: profileview, edit-profileedit, create-profilenew (login/logout/verify-email-request unchanged)
    • release-notes: release-notesview
    • notifications: inboxall (link/invalid unchanged)

    Plugin defaults updated to match: SmartDescriptions now defaults contactDetailPageId to contacts/view and companyDetailPageId to companies/view; EventsTimeline schema example updated.

    Also includes two fixes to the contacts new page: removed a duplicate avatar render (the avatar block was included both directly and via form_profile), and fixed the post-create redirect that was navigating with a null _id because CallAPI return values are accessed at _actions: <id>.response.response.<field>, not .response.<field>. Same redirect fix applied to the companies new page.

Patch Changes

  • #31 a167d18 Thanks @Yianni99! - Fix Activity tile missing user-related events on contact-detail. user-account and user-admin events tagged the same shared user-contacts record under references.user_ids, while the Activity tile filters on contact_ids — so events like update-profile, invite-user, update-user, resend-invite, and create-profile never surfaced on the contact's timeline. Since contacts and users live in one collection with one _id space, a user IS a contact. Renamed the reference field on those 5 events from user_ids to contact_ids so the existing single-field timeline match returns them. Event semantics (user vs. plain contact) stay encoded in the event type. Migration for existing event docs is the consuming app's responsibility — db.log-events.updateMany({ user_ids: { $exists: true } }, [{ $set: { contact_ids: '$user_ids' } }, { $unset: 'user_ids' }]).

  • #27 24b8dd1 Thanks @Yianni99! - Fix silent empty display payload on every event-emitting endpoint. The _build.array.map callback that builds per-app event display titles returned {key, value} objects, which _build.object.fromEntries (native Object.fromEntries) silently rejected as {} — so events landed in MongoDB without title or description. Switched callback bodies to a 2-element [key, value] array tuple to match the spec, and quoted "0.0" so YAML parses it as a path string instead of the float 0. Affects 9 endpoints: contacts/api/{create,update}-contact, companies/api/{create,update}-company, user-admin/api/{invite,update}-user, user-admin/api/resend-invite, user-account/api/{create,update}-profile. Also fixed two latent typos (_result_step) in user-account/api/{create,update}-profile.yaml that were hidden by the silent failure.

  • @lowdefy/modules-mongodb-user-admin: ### Minor Changes

  • #28 2c4aa70 Thanks @Yianni99! - Rename module pages from entity-prefixed IDs to semantic verbs to remove the redundant URL prefix (e.g. /companies/companies/companies/all). Module pages now use all, view, edit, new consistently. Cross-module references via _module.pageId: and hardcoded scoped page IDs ({entry-id}/{page-id}) must be updated to the new IDs.

    Page ID changes per module:

    • companies: companiesall, company-detailview, company-editedit, company-newnew
    • contacts: contactsall, contact-detailview, contact-editedit, contact-newnew
    • user-admin: usersall, users-viewview, users-editedit, users-invitenew, check-invite-emailcheck
    • user-account: profileview, edit-profileedit, create-profilenew (login/logout/verify-email-request unchanged)
    • release-notes: release-notesview
    • notifications: inboxall (link/invalid unchanged)

    Plugin defaults updated to match: SmartDescriptions now defaults contactDetailPageId to contacts/view and companyDetailPageId to companies/view; EventsTimeline schema example updated.

    Also includes two fixes to the contacts new page: removed a duplicate avatar render (the avatar block was included both directly and via form_profile), and fixed the post-create redirect that was navigating with a null _id because CallAPI return values are accessed at _actions: <id>.response.response.<field>, not .response.<field>. Same redirect fix applied to the companies new page.

Patch Changes

  • #31 a167d18 Thanks @Yianni99! - Fix Activity tile missing user-related events on contact-detail. user-account and user-admin events tagged the same shared user-contacts record under references.user_ids, while the Activity tile filters on contact_ids — so events like update-profile, invite-user, update-user, resend-invite, and create-profile never surfaced on the contact's timeline. Since contacts and users live in one collection with one _id space, a user IS a contact. Renamed the reference field on those 5 events from user_ids to contact_ids so the existing single-field timeline match returns them. Event semantics (user vs. plain contact) stay encoded in the event type. Migration for existing event docs is the consuming app's responsibility — db.log-events.updateMany({ user_ids: { $exists: true } }, [{ $set: { contact_ids: '$user_ids' } }, { $unset: 'user_ids' }]).

  • #27 24b8dd1 Thanks @Yianni99! - Fix silent empty display payload on every event-emitting endpoint. The _build.array.map callback that builds per-app event display titles returned {key, value} objects, which _build.object.fromEntries (native Object.fromEntries) silently rejected as {} — so events landed in MongoDB without title or description. Switched callback bodies to a 2-element [key, value] array tuple to match the spec, and quoted "0.0" so YAML parses it as a path string instead of the float 0. Affects 9 endpoints: contacts/api/{create,update}-contact, companies/api/{create,update}-company, user-admin/api/{invite,update}-user, user-admin/api/resend-invite, user-account/api/{create,update}-profile. Also fixed two latent typos (_result_step) in user-account/api/{create,update}-profile.yaml that were hidden by the silent failure.

  • #31 fcd328b Thanks @Yianni99! - Small UX fixes across modules and the EventsTimeline block:

    • release-notes: Empty-state fallback now triggers when content is null OR an empty/whitespace-only string. The previous _if_none only caught null, so consumers with an empty CHANGELOG.md saw a blank Card instead of the "No release notes available yet" message.
    • companies / contacts / user-admin table components: Added a conditional overlayNoRowsTemplate that renders "Loading…" while the get_all_* request is in flight and "No rows" once the request completes empty. Previously AG Grid's default "No Rows To Show" appeared during the initial load, indistinguishable from a genuinely empty result.
    • EventsTimeline (plugin): Avatar hover swapped from <Popover> to <Tooltip> so it matches the timestamp's TimeAgo style — same name-on-hover, lighter dark-tooltip styling.