| @@ -126,12 +126,21 @@ | ||
| 126 | 126 | ); |
| 127 | 127 | |
| 128 | 128 | add_submenu_page( |
| 129 | 129 | 'fluent-boards', |
| 130 | + __('Addons', 'fluent-boards'), | |
| 131 | + __('Addons', 'fluent-boards'), | |
| 132 | + 'manage_options', | |
| 133 | + 'fluent-boards#/add-ons', | |
| 134 | + [$this, 'render'] | |
| 135 | + ); | |
| 136 | + | |
| 137 | + add_submenu_page( | |
| 138 | + 'fluent-boards', | |
| 130 | 139 | __('Settings', 'fluent-boards'), |
| 131 | 140 | __('Settings', 'fluent-boards'), |
| 132 | 141 | 'manage_options', |
| 133 | - 'fluent-boards#/settings/members-role', | |
| 142 | + 'fluent-boards#/settings/general-settings', | |
| 134 | 143 | [$this, 'render'] |
| 135 | 144 | ); |
| 136 | 145 | } |
| 137 | 146 | |
| @@ -205,25 +214,8 @@ | ||
| 205 | 214 | |
| 206 | 215 | $isAdmin = PermissionManager::isAdmin(); |
| 207 | 216 | |
| 208 | 217 | if ($isAdmin) { |
| 209 | - $menuItems['settings'] = [ | |
| 210 | - 'key' => 'settings', | |
| 211 | - 'label' => __('Settings', 'fluent-boards'), | |
| 212 | - 'permalink' => $baseUrl . 'settings/members-role' | |
| 213 | - ]; | |
| 214 | - } | |
| 215 | - | |
| 216 | - if (!defined('FLUENT_BOARDS_PRO')) { | |
| 217 | - $menuItems['get_pro'] = [ | |
| 218 | - 'key' => 'get_pro', | |
| 219 | - 'label' => __('Get Pro', 'fluent-boards'), | |
| 220 | - 'permalink' => 'https://fluentboards.com?utm_source=plugin&utm_medium=menu&utm_campaign=pro&utm_id=wp', | |
| 221 | - 'class' => 'pro_link' | |
| 222 | - ]; | |
| 223 | - } | |
| 224 | - | |
| 225 | - if ($isAdmin) { | |
| 226 | 218 | $menuItems['help'] = [ |
| 227 | 219 | 'key' => 'help', |
| 228 | 220 | 'label' => __('Community', 'fluent-boards'), |
| 229 | 221 | 'target' => '_blank', |
| @@ -233,9 +225,9 @@ | ||
| 233 | 225 | |
| 234 | 226 | if ($isDiffUrl) { |
| 235 | 227 | $menuItems['front'] = [ |
| 236 | 228 | 'key' => 'front', |
| 237 | - 'label' => __('Frontend Portal', 'fluent-boards'), | |
| 229 | + 'label' => __('Front Portal', 'fluent-boards'), | |
| 238 | 230 | 'target' => '_blank', |
| 239 | 231 | 'permalink' => fluent_boards_page_url() |
| 240 | 232 | ]; |
| 241 | 233 | } |
| @@ -312,23 +304,11 @@ | ||
| 312 | 304 | |
| 313 | 305 | // Inject Vite HMR client in dev mode |
| 314 | 306 | Vite::injectViteClient(); |
| 315 | 307 | |
| 316 | - $isRtl = is_rtl(); | |
| 317 | - $adminAppCss = $isRtl ? 'scss/admin.scss' : 'scss/admin.scss'; | |
| 318 | - Vite::enqueueStyle($slug . '_admin_app', $adminAppCss); | |
| 308 | + $isRtl = fluent_boards_is_rtl(); | |
| 309 | + Vite::enqueueStyle($slug . '_admin_app', 'scss/admin.scss'); | |
| 319 | 310 | |
| 320 | - // In production, load the RTL version if needed | |
| 321 | - if ($isRtl && !Vite::underDevelopment()) { | |
| 322 | - $assets = $app['url.assets']; | |
| 323 | - wp_enqueue_style( | |
| 324 | - $slug . '_admin_app_rtl', | |
| 325 | - $assets . 'admin/admin-rtl.css', | |
| 326 | - [$slug . '_admin_app'], | |
| 327 | - FLUENT_BOARDS_PLUGIN_VERSION | |
| 328 | - ); | |
| 329 | - } | |
| 330 | - | |
| 331 | 311 | // Enqueue merged chunk CSS (Vue SFC styles) in production |
| 332 | 312 | if (!Vite::underDevelopment()) { |
| 333 | 313 | $assets = $app['url.assets']; |
| 334 | 314 | $styleCssPath = FLUENT_BOARDS_PLUGIN_PATH . 'assets/admin/style.css'; |
| @@ -341,8 +321,23 @@ | ||
| 341 | 321 | ); |
| 342 | 322 | } |
| 343 | 323 | } |
| 344 | 324 | |
| 325 | + // RTL overrides must load after style.css so rules appended to the | |
| 326 | + // element-plus layer win by source order, not only by specificity. | |
| 327 | + if ($isRtl) { | |
| 328 | + $rtlDeps = [$slug . '_admin_app']; | |
| 329 | + if (wp_style_is($slug . '_vite_style', 'enqueued')) { | |
| 330 | + $rtlDeps[] = $slug . '_vite_style'; | |
| 331 | + } | |
| 332 | + Vite::enqueueStyle( | |
| 333 | + $slug . '_admin_app_rtl', | |
| 334 | + 'scss/admin_rtl.scss', | |
| 335 | + $rtlDeps, | |
| 336 | + FLUENT_BOARDS_PLUGIN_VERSION | |
| 337 | + ); | |
| 338 | + } | |
| 339 | + | |
| 345 | 340 | do_action('fluent-boards_loading_app'); |
| 346 | 341 | |
| 347 | 342 | Vite::enqueueScript( |
| 348 | 343 | $slug . '_admin_app', |
| @@ -375,8 +370,9 @@ | ||
| 375 | 370 | $currentUser = get_user_by('ID', get_current_user_id()); |
| 376 | 371 | $assets = $app['url.assets']; |
| 377 | 372 | $roleAndPermissions = $this->getRoleAndPermissions($currentUser->ID); |
| 378 | 373 | $onboardingValue = $this->getOnboardingValue(); |
| 374 | + $generalSettings = fluent_boards_get_option('general_settings', []); | |
| 379 | 375 | |
| 380 | 376 | return apply_filters('fluent_boards/app_vars', [ |
| 381 | 377 | 'slug' => $slug = $app->config->get('app.slug'), |
| 382 | 378 | 'nonce' => wp_create_nonce($slug), |
| @@ -384,13 +380,23 @@ | ||
| 384 | 380 | 'fluent_boards_file_upload_nonce' => wp_create_nonce('fluent_boards_file_upload_nonce'), |
| 385 | 381 | 'ajaxurl' => admin_url('admin-ajax.php'), |
| 386 | 382 | 'file_upload_limit' => $this->fileUploadLimit(), |
| 387 | 383 | 'brand_logo' => $this->getMenuIcon(), |
| 384 | + 'business_name' => sanitize_text_field(Arr::get($generalSettings, 'business_name', '')), | |
| 388 | 385 | 'asset_url' => $assets, |
| 389 | 386 | 'admin_url' => admin_url('admin.php'), |
| 390 | 387 | 'fluent_crm_exists' => !defined('FLUENTCRM') ? false : true, |
| 388 | + 'fluent_support_exists' => !!defined('FLUENT_SUPPORT_VERSION'), | |
| 389 | + 'can_manage_crm_contacts' => $this->canManageCrmContacts(), | |
| 391 | 390 | 'fluent_roadmap_exists' => !defined('FLUENT_ROADMAP') ? false : true, |
| 392 | 391 | 'has_pro' => !!defined('FLUENT_BOARDS_PRO_VERSION'), |
| 392 | + 'upgrade_url' => fluent_boards_get_upgrade_url(), | |
| 393 | + 'board_solid_colors' => Constant::BOARD_BACKGROUND_DEFAULT_SOLID_COLORS, | |
| 394 | + 'board_gradient_colors' => Constant::BOARD_BACKGROUND_DEFAULT_GRADIENT_COLORS, | |
| 395 | + 'label_color_presets' => Constant::LABEL_COLOR_PRESETS, | |
| 396 | + 'ai_features' => [ | |
| 397 | + 'enabled' => (new \FluentBoards\App\Services\AiService())->isReady(), | |
| 398 | + ], | |
| 393 | 399 | 'me' => [ |
| 394 | 400 | 'id' => $currentUser->ID, |
| 395 | 401 | 'full_name' => trim($currentUser->first_name . ' ' . $currentUser->last_name), |
| 396 | 402 | 'display_name' => $currentUser->display_name, |
| @@ -395,8 +401,9 @@ | ||
| 395 | 401 | 'full_name' => trim($currentUser->first_name . ' ' . $currentUser->last_name), |
| 396 | 402 | 'display_name' => $currentUser->display_name, |
| 397 | 403 | 'email' => $currentUser->user_email, |
| 398 | 404 | 'photo' => fluent_boards_user_avatar($currentUser->user_email, $currentUser->display_name), |
| 405 | + 'logout_url' => wp_logout_url(), | |
| 399 | 406 | 'fluent_boards_role' => $roleAndPermissions['role'], |
| 400 | 407 | 'fluent_boards_capabilities' => $roleAndPermissions['permissions'], |
| 401 | 408 | 'is_wp_admin' => user_can($currentUser->ID, 'manage_options') ? 'yes' : 'no', |
| 402 | 409 | 'can_create_board' => PermissionManager::userHasBoardCreationPermission($currentUser->ID) |
| @@ -425,15 +432,19 @@ | ||
| 425 | 432 | 'dashiconsCss' => add_query_arg( |
| 426 | 433 | 'ver', get_bloginfo('version'), |
| 427 | 434 | site_url('/wp-includes/css/dashicons.css') |
| 428 | 435 | ), |
| 429 | - 'is_rtl' => is_rtl(), | |
| 430 | - 'task_tabs' => apply_filters('fluent_boards/task_tabs', $this->getDefaultTaskTabs()), | |
| 436 | + 'is_rtl' => fluent_boards_is_rtl(), | |
| 431 | 437 | 'board_menu_items' => BoardMenuHandler::getMenuItems(), |
| 432 | 438 | 'reminder_types' => defined('FLUENT_BOARDS_PRO') ? Helper::taskReminderTypes() : [], |
| 433 | 439 | ]); |
| 434 | 440 | } |
| 435 | 441 | |
| 442 | + protected function canManageCrmContacts() | |
| 443 | + { | |
| 444 | + return defined('FLUENTCRM') && \FluentCrm\App\Services\PermissionManager::currentUserCan('fcrm_manage_contacts'); | |
| 445 | + } | |
| 446 | + | |
| 436 | 447 | private function getOnboardingValue() |
| 437 | 448 | { |
| 438 | 449 | $onboarding = Meta::where('key', Constant::FBS_ONBOARDING)->first(); |
| 439 | 450 | if ($onboarding) { |
| @@ -445,34 +456,16 @@ | ||
| 445 | 456 | // |
| 446 | 457 | // return 'no'; |
| 447 | 458 | } |
| 448 | 459 | |
| 449 | - private function getDefaultTaskTabs() | |
| 450 | - { | |
| 451 | - return [ | |
| 452 | - 'all' => [ | |
| 453 | - 'key' => 'all', | |
| 454 | - 'label' => __('All', 'fluent-boards'), | |
| 455 | - 'component' => 'task-all-comments-and-activities' | |
| 456 | - ], | |
| 457 | - 'comment' => [ | |
| 458 | - 'key' => 'comment', | |
| 459 | - 'label' => __('Comments', 'fluent-boards'), | |
| 460 | - 'component' => 'task-comments' | |
| 461 | - ], | |
| 462 | - 'activity' => [ | |
| 463 | - 'key' => 'activity', | |
| 464 | - 'label' => __('Activities', 'fluent-boards'), | |
| 465 | - 'component' => 'task-activities' | |
| 466 | - ] | |
| 467 | - ]; | |
| 468 | - } | |
| 469 | 460 | public function getDefaultPriorities() |
| 470 | 461 | { |
| 471 | 462 | return [ |
| 472 | - 'low' => __('Low', 'fluent-boards'), | |
| 463 | + '' => __('No priority', 'fluent-boards'), | |
| 464 | + 'urgent' => __('Urgent', 'fluent-boards'), | |
| 465 | + 'high' => __('High', 'fluent-boards'), | |
| 473 | 466 | 'medium' => __('Medium', 'fluent-boards'), |
| 474 | - 'high' => __('High', 'fluent-boards') | |
| 467 | + 'low' => __('Low', 'fluent-boards') | |
| 475 | 468 | ]; |
| 476 | 469 | } |
| 477 | 470 | |
| 478 | 471 | /* |
| @@ -552,25 +545,15 @@ | ||
| 552 | 545 | }); |
| 553 | 546 | } |
| 554 | 547 | |
| 555 | 548 | /** |
| 556 | - * Retrieves the maximum upload limit based on PHP and WordPress configurations. | |
| 549 | + * Retrieves the Fluent Boards upload limit exposed to the admin app. | |
| 557 | 550 | * |
| 558 | - * This method calculates and returns the minimum value among the following: | |
| 559 | - * 1. The PHP 'upload_max_filesize' configuration. | |
| 560 | - * 2. The PHP 'post_max_size' configuration. | |
| 561 | - * 3. The WordPress maximum upload size limit using the 'wp_max_upload_size' function. | |
| 562 | - * | |
| 563 | - * @return int The minimum of the mentioned upload size limits in bytes. | |
| 551 | + * @return int Upload limit in bytes. | |
| 564 | 552 | */ |
| 565 | 553 | public function fileUploadLimit() |
| 566 | 554 | { |
| 567 | - // Calculate the minimum of 'upload_max_filesize', 'post_max_size', and WordPress maximum upload size. | |
| 568 | - return min( | |
| 569 | - wp_convert_hr_to_bytes(ini_get('upload_max_filesize')), | |
| 570 | - wp_convert_hr_to_bytes(ini_get('post_max_size')), | |
| 571 | - wp_max_upload_size() | |
| 572 | - ); | |
| 555 | + return (new \FluentBoards\App\Services\UploadService())->getFileUploadLimit(); | |
| 573 | 556 | } |
| 574 | 557 | |
| 575 | 558 | public function getInlineScript() |
| 576 | 559 | { |