Rename plugins feature to automations throughout codebase
- Update billing catalog feature codes: can_use_plugins → can_use_automations, can_create_plugins → can_create_automations - Update all backend permission checks to use new feature codes - Update API views to return automations permissions to frontend - Update frontend types and hooks to use automations terminology - Move Tasks to Extend section in Sidebar alongside Automations - Update all related tests 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -138,16 +138,6 @@ const Sidebar: React.FC<SidebarProps> = ({ business, user, isCollapsed, toggleCo
|
||||
isCollapsed={isCollapsed}
|
||||
/>
|
||||
)}
|
||||
{hasPermission('can_access_tasks') && (
|
||||
<SidebarItem
|
||||
to="/dashboard/tasks"
|
||||
icon={Clock}
|
||||
label={t('nav.tasks', 'Tasks')}
|
||||
isCollapsed={isCollapsed}
|
||||
locked={!canUse('automations') || !canUse('tasks')}
|
||||
badgeElement={<UnfinishedBadge />}
|
||||
/>
|
||||
)}
|
||||
{(isStaff && hasPermission('can_access_my_schedule')) && (
|
||||
<SidebarItem
|
||||
to="/dashboard/my-schedule"
|
||||
@@ -293,17 +283,29 @@ const Sidebar: React.FC<SidebarProps> = ({ business, user, isCollapsed, toggleCo
|
||||
</SidebarSection>
|
||||
)}
|
||||
|
||||
{/* Extend Section - Automations */}
|
||||
{hasPermission('can_access_automations') && (
|
||||
{/* Extend Section - Tasks & Automations */}
|
||||
{(hasPermission('can_access_tasks') || hasPermission('can_access_automations')) && (
|
||||
<SidebarSection title={t('nav.sections.extend', 'Extend')} isCollapsed={isCollapsed}>
|
||||
<SidebarItem
|
||||
to="/dashboard/automations/my-automations"
|
||||
icon={Plug}
|
||||
label={t('nav.automations', 'Automations')}
|
||||
isCollapsed={isCollapsed}
|
||||
locked={!canUse('automations')}
|
||||
badgeElement={<UnfinishedBadge />}
|
||||
/>
|
||||
{hasPermission('can_access_tasks') && (
|
||||
<SidebarItem
|
||||
to="/dashboard/tasks"
|
||||
icon={Clock}
|
||||
label={t('nav.tasks', 'Tasks')}
|
||||
isCollapsed={isCollapsed}
|
||||
locked={!canUse('automations') || !canUse('tasks')}
|
||||
badgeElement={<UnfinishedBadge />}
|
||||
/>
|
||||
)}
|
||||
{hasPermission('can_access_automations') && (
|
||||
<SidebarItem
|
||||
to="/dashboard/automations/my-automations"
|
||||
icon={Plug}
|
||||
label={t('nav.automations', 'Automations')}
|
||||
isCollapsed={isCollapsed}
|
||||
locked={!canUse('automations')}
|
||||
badgeElement={<UnfinishedBadge />}
|
||||
/>
|
||||
)}
|
||||
</SidebarSection>
|
||||
)}
|
||||
|
||||
|
||||
@@ -231,7 +231,8 @@ describe('usePlanFeatures', () => {
|
||||
custom_domain: true,
|
||||
white_label: true,
|
||||
custom_oauth: true,
|
||||
plugins: true,
|
||||
automations: true,
|
||||
can_create_automations: true,
|
||||
tasks: true,
|
||||
export_data: true,
|
||||
video_conferencing: true,
|
||||
@@ -259,7 +260,7 @@ describe('usePlanFeatures', () => {
|
||||
expect(result.current.canUse('custom_domain')).toBe(true);
|
||||
expect(result.current.canUse('white_label')).toBe(true);
|
||||
expect(result.current.canUse('custom_oauth')).toBe(true);
|
||||
expect(result.current.canUse('plugins')).toBe(true);
|
||||
expect(result.current.canUse('automations')).toBe(true);
|
||||
expect(result.current.canUse('tasks')).toBe(true);
|
||||
expect(result.current.canUse('export_data')).toBe(true);
|
||||
expect(result.current.canUse('video_conferencing')).toBe(true);
|
||||
@@ -780,7 +781,8 @@ describe('FEATURE_NAMES', () => {
|
||||
'custom_domain',
|
||||
'white_label',
|
||||
'custom_oauth',
|
||||
'plugins',
|
||||
'automations',
|
||||
'can_create_automations',
|
||||
'tasks',
|
||||
'export_data',
|
||||
'video_conferencing',
|
||||
@@ -805,7 +807,8 @@ describe('FEATURE_NAMES', () => {
|
||||
expect(FEATURE_NAMES.custom_domain).toBe('Custom Domain');
|
||||
expect(FEATURE_NAMES.white_label).toBe('White Label');
|
||||
expect(FEATURE_NAMES.custom_oauth).toBe('Custom OAuth');
|
||||
expect(FEATURE_NAMES.plugins).toBe('Plugins');
|
||||
expect(FEATURE_NAMES.automations).toBe('Automations');
|
||||
expect(FEATURE_NAMES.can_create_automations).toBe('Custom Automation Creation');
|
||||
expect(FEATURE_NAMES.tasks).toBe('Scheduled Tasks');
|
||||
expect(FEATURE_NAMES.export_data).toBe('Data Export');
|
||||
expect(FEATURE_NAMES.video_conferencing).toBe('Video Conferencing');
|
||||
@@ -826,7 +829,8 @@ describe('FEATURE_DESCRIPTIONS', () => {
|
||||
'custom_domain',
|
||||
'white_label',
|
||||
'custom_oauth',
|
||||
'plugins',
|
||||
'automations',
|
||||
'can_create_automations',
|
||||
'tasks',
|
||||
'export_data',
|
||||
'video_conferencing',
|
||||
@@ -851,7 +855,8 @@ describe('FEATURE_DESCRIPTIONS', () => {
|
||||
expect(FEATURE_DESCRIPTIONS.custom_domain).toContain('custom domain');
|
||||
expect(FEATURE_DESCRIPTIONS.white_label).toContain('branding');
|
||||
expect(FEATURE_DESCRIPTIONS.custom_oauth).toContain('OAuth');
|
||||
expect(FEATURE_DESCRIPTIONS.plugins).toContain('plugin');
|
||||
expect(FEATURE_DESCRIPTIONS.automations).toContain('Automate');
|
||||
expect(FEATURE_DESCRIPTIONS.can_create_automations).toContain('automations');
|
||||
expect(FEATURE_DESCRIPTIONS.tasks).toContain('task');
|
||||
expect(FEATURE_DESCRIPTIONS.export_data).toContain('Export');
|
||||
expect(FEATURE_DESCRIPTIONS.video_conferencing).toContain('video');
|
||||
|
||||
@@ -62,8 +62,8 @@ export const useCurrentBusiness = () => {
|
||||
custom_domain: false,
|
||||
white_label: false,
|
||||
custom_oauth: false,
|
||||
plugins: false,
|
||||
can_create_plugins: false,
|
||||
automations: false,
|
||||
can_create_automations: false,
|
||||
tasks: false,
|
||||
export_data: false,
|
||||
video_conferencing: false,
|
||||
|
||||
@@ -83,8 +83,8 @@ export const FEATURE_NAMES: Record<FeatureKey, string> = {
|
||||
custom_domain: 'Custom Domain',
|
||||
white_label: 'White Label',
|
||||
custom_oauth: 'Custom OAuth',
|
||||
plugins: 'Plugins',
|
||||
can_create_plugins: 'Custom Plugin Creation',
|
||||
automations: 'Automations',
|
||||
can_create_automations: 'Custom Automation Creation',
|
||||
tasks: 'Scheduled Tasks',
|
||||
export_data: 'Data Export',
|
||||
video_conferencing: 'Video Conferencing',
|
||||
@@ -106,9 +106,9 @@ export const FEATURE_DESCRIPTIONS: Record<FeatureKey, string> = {
|
||||
custom_domain: 'Use your own custom domain for your booking site',
|
||||
white_label: 'Remove SmoothSchedule branding and use your own',
|
||||
custom_oauth: 'Configure your own OAuth credentials for social login',
|
||||
plugins: 'Install and use plugins from the marketplace',
|
||||
can_create_plugins: 'Create custom plugins tailored to your business needs',
|
||||
tasks: 'Create scheduled tasks to automate plugin execution',
|
||||
automations: 'Automate repetitive tasks with custom workflows',
|
||||
can_create_automations: 'Create custom automations tailored to your business needs',
|
||||
tasks: 'Create scheduled tasks to automate execution',
|
||||
export_data: 'Export your data to CSV or other formats',
|
||||
video_conferencing: 'Add video conferencing links to appointments',
|
||||
two_factor_auth: 'Require two-factor authentication for enhanced security',
|
||||
|
||||
@@ -38,8 +38,8 @@ export interface PlanPermissions {
|
||||
custom_domain: boolean;
|
||||
white_label: boolean;
|
||||
custom_oauth: boolean;
|
||||
plugins: boolean;
|
||||
can_create_plugins: boolean;
|
||||
automations: boolean;
|
||||
can_create_automations: boolean;
|
||||
tasks: boolean;
|
||||
export_data: boolean;
|
||||
video_conferencing: boolean;
|
||||
|
||||
Reference in New Issue
Block a user