Skip to content

Company Management Events and Data

The Company Management drop-in uses the event bus to emit and listen to events for communication between drop-ins and external integrations.

Version: 1.0.0

Events reference

EventDirectionDescription
company/updatedEmitsEmitted when the component state is updated.
companyStructure/updatedEmitsEmitted when the component state is updated.
companyContext/changedListensFired by Company Context (companyContext) when a change occurs.

Event details

The following sections provide detailed information about each event, including its direction, event payload, and usage examples.

company/updated (emits)

Emitted when company information is updated. This event fires after successful company profile updates, legal address changes, contact information modifications, or sales representative information updates.

Usage scenarios

  • Refresh company profile display after edits.
  • Trigger analytics tracking for profile changes.
  • Update related UI components (headers, sidebars, widgets).
  • Sync company data with external systems (CRM, ERP).
  • Show success notifications to users.
  • Update cached data and local storage.
  • Refresh company-dependent permissions.
  • Update breadcrumbs and navigation with company name.

Event payload

{ company?: unknown; message?: string; error?: unknown }
PropertyTypeDescription
companyany (optional)See type definition in source code
messagestring (optional)See type definition in source code
errorany (optional)See type definition in source code

Usage

Listen to this event in your storefront:

import { events } from '@dropins/tools/event-bus.js';
// Listen for company updates
events.on('company/updated', (payload) => {
console.log('Company updated:', payload.data);
// Update UI or trigger other actions
refreshCompanyDisplay();
});

Example 2: Update with notification and error handling

import { events } from '@dropins/tools/event-bus.js';
import { updateCompany } from '@dropins/storefront-company-management/api.js';
async function updateCompanyProfile(updates) {
try {
// Show loading state
showLoadingIndicator('Updating company profile...');
// Update the company
await updateCompany(updates);
// Listen for successful update
events.once('company/updated', (payload) => {
hideLoadingIndicator();
showSuccessNotification('Company profile updated successfully');
// Update the displayed company information
document.querySelector('.company-name').textContent = payload.data.companyName;
document.querySelector('.company-email').textContent = payload.data.email;
// Track the update in analytics
trackEvent('company_profile_updated', {
companyId: payload.data.id,
fieldsUpdated: Object.keys(updates)
});
});
} catch (error) {
hideLoadingIndicator();
showErrorNotification('Failed to update company profile: ' + error.message);
console.error('Company update error:', error);
}
}
// Usage
updateCompanyProfile({
companyName: 'Example Corporation',
email: 'info@example.com',
telephone: '+1-555-0123'
});

Example 3: Real-time multi-component sync

import { events } from '@dropins/tools/event-bus.js';
// Central company data manager
class CompanyDataManager {
constructor() {
this.subscribers = [];
// Listen for company updates
events.on('company/updated', this.handleCompanyUpdate.bind(this));
}
handleCompanyUpdate(payload) {
const companyData = payload.data;
// Update all subscribed components
this.subscribers.forEach(callback => {
try {
callback(companyData);
} catch (error) {
console.error('Error updating subscriber:', error);
}
});
// Update local storage for offline support
localStorage.setItem('companyData', JSON.stringify(companyData));
// Sync with external CRM
this.syncWithCRM(companyData);
}
subscribe(callback) {
this.subscribers.push(callback);
}
async syncWithCRM(companyData) {
try {
await fetch('/api/crm/update-company', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(companyData)
});
} catch (error) {
console.error('CRM sync failed:', error);
}
}
}
// Initialize manager
const companyManager = new CompanyDataManager();
// Subscribe components
companyManager.subscribe((data) => {
// Update header component
document.querySelector('.header-company-name').textContent = data.companyName;
});
companyManager.subscribe((data) => {
// Update sidebar widget
updateCompanySidebarWidget(data);
});

companyContext/changed (listens)

Fired by Company Context (companyContext) when a change occurs.

Event payload

string | null | undefined

Example

import { events } from '@dropins/tools/event-bus.js';
events.on('companyContext/changed', (payload) => {
console.log('companyContext/changed event received:', payload);
// Add your custom logic here
});

companyStructure/updated (emits)

Emitted when the company organizational structure changes. This event fires after creating or updating teams, deleting teams, creating or updating users, moving users between teams, or changing team hierarchy.

Event payload

{
message?: string;
action?: 'move' | 'remove' | 'add';
nodeId?: string;
newParentId?: string;
nodeIds?: string[];
nodes?: unknown[];
error?: unknown;
}

Usage scenarios

  • Refresh the company structure tree display in real-time.
  • Update user access controls based on new hierarchy.
  • Trigger notifications to affected team members.
  • Log organizational changes for audit and compliance.
  • Update cached structure data and local storage.
  • Refresh team-based dropdowns and filters.
  • Update permission matrices after reassignments.
  • Highlight changes in the structure visualization.
  • Trigger workflow updates (approval chains, and so on).
  • Sync organizational structure with external HR systems.

Example 1: Interactive structure tree with live updates

import { events } from '@dropins/tools/event-bus.js';
import { getCompanyStructure } from '@dropins/storefront-company-management/api.js';
class CompanyStructureTree {
constructor(containerElement) {
this.container = containerElement;
this.structureData = null;
// Listen for structure updates
events.on('companyStructure/updated', this.handleUpdate.bind(this));
// Initial load
this.loadStructure();
}
async loadStructure() {
try {
this.showLoading();
this.structureData = await getCompanyStructure();
this.render();
} catch (error) {
this.showError('Failed to load company structure');
console.error(error);
}
}
async handleUpdate(payload) {
console.log('Structure updated:', payload.data);
// Highlight the updated section
const updatedNodeId = payload.data.updatedNodeId;
if (updatedNodeId) {
this.highlightNode(updatedNodeId);
}
// Reload the full structure
await this.loadStructure();
// Show success message
this.showNotification('Organization structure updated', 'success');
// Refresh permissions for all users in the tree
await this.refreshPermissions();
}
highlightNode(nodeId) {
const nodeElement = this.container.querySelector(`[data-node-id="${nodeId}"]`);
if (nodeElement) {
nodeElement.classList.add('highlight-update');
setTimeout(() => nodeElement.classList.remove('highlight-update'), 2000);
}
}
render() {
// Render the structure tree
this.container.innerHTML = this.buildTreeHTML(this.structureData);
this.attachEventListeners();
}
buildTreeHTML(structure) {
// Build hierarchical HTML for the structure
return `<div class="structure-tree">...</div>`;
}
async refreshPermissions() {
// Refresh permissions after structure change
events.emit('permissions/refresh-needed');
}
showLoading() {
this.container.innerHTML = '<div class="loading">Loading structure...</div>';
}
showError(message) {
this.container.innerHTML = `<div class="error">${message}</div>`;
}
showNotification(message, type) {
// Show toast notification
const notification = document.createElement('div');
notification.className = `notification notification-${type}`;
notification.textContent = message;
document.body.appendChild(notification);
setTimeout(() => notification.remove(), 3000);
}
attachEventListeners() {
// Add drag-and-drop, expand/collapse, etc.
}
}
// Initialize the tree
const tree = new CompanyStructureTree(document.querySelector('#company-structure'));

Example 2: Team-based notification system

import { events } from '@dropins/tools/event-bus.js';
// Track structure changes and notify affected users
events.on('companyStructure/updated', async (payload) => {
const { data } = payload;
// Determine what changed
const changeType = determineChangeType(data);
switch (changeType) {
case 'team-created':
notifyTeamCreation(data.newTeam);
break;
case 'team-deleted':
notifyTeamDeletion(data.deletedTeam);
break;
case 'user-moved':
notifyUserReassignment(data.user, data.oldTeam, data.newTeam);
break;
case 'hierarchy-changed':
notifyHierarchyChange(data.affectedTeams);
break;
}
// Update all team-based UI components
updateTeamSelectors();
updateUserFilters();
refreshTeamDashboards();
// Log for audit trail
logStructureChange({
timestamp: new Date(),
changeType,
userId: getCurrentUserId(),
details: data
});
});
function determineChangeType(data) {
// Logic to determine what type of change occurred
if (data.newTeam) return 'team-created';
if (data.deletedTeam) return 'team-deleted';
if (data.userMoved) return 'user-moved';
return 'hierarchy-changed';
}
async function notifyUserReassignment(user, oldTeam, newTeam) {
const message = `${user.name} has been moved from ${oldTeam.name} to ${newTeam.name}`;
// Notify team managers
await sendNotification([oldTeam.managerId, newTeam.managerId], message);
// Notify the user
await sendNotification([user.id], `You have been assigned to ${newTeam.name}`);
// Update UI
showToast(message, 'info');
}
function logStructureChange(logEntry) {
// Send to audit log
fetch('/api/audit/log', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(logEntry)
});
}

Listening to events

All Company Management events are emitted through the centralized event bus. Subscribe to events using the events.on() method:

import { events } from '@dropins/tools/event-bus.js';
// Single event listener
events.on('company/updated', (payload) => {
// Handle company update
});
// Multiple event listeners
events.on('company/updated', handleCompanyUpdate);
events.on('companyStructure/updated', handleStructureUpdate);
// Remove listeners when no longer needed
events.off('company/updated', handleCompanyUpdate);