Skip to content

Regression since 1.8.0: user "Default dashboard" + "Always fullscreen" ignored on login (user lands on first tab / Profile) #316

Description

@t0mZ4

ThingsBoard Platform Version: 4.3.1.3
Affected platforms: Both
ThingsBoard Platform Type: Self-hosted ThingsBoard
App Release Version: 1.8.1 (regression introduced in 1.8.0; works in 1.7.0)
App type: Custom build app

Steps to reproduce

  1. In the web UI, edit a user: set Default dashboard to a dashboard the user can access and check Always fullscreen (additionalInfo.defaultDashboardId / additionalInfo.defaultDashboardFullscreen).
  2. Log in with that user in app 1.8.x.
  3. Optional (reproduces the Profile landing): use a Mobile center app bundle whose layout has no visible pages.

Expected results

Same as 1.7.x. After login the app opens /fullscreenDashboard/<defaultDashboardId>. If "Always fullscreen" is off, it opens the default dashboard on top of the main screen.

Actual results

The default dashboard is ignored and the app always navigates to the first bottom-navigation page.

If the bundle layout has no visible pages, the server returns pages: [] (not null). The only nav item is then the auto-injected /profile?fullscreen=true, so the user lands on the Profile page after login.

Root cause / problematic files

  • lib/config/routes/v2/route_handlers/home_handler.dart: after login it does context.go(bottomBarPages.first.path) and never reads defaultDashboardId / defaultDashboardFullscreen.
  • lib/core/context/tb_context.dart: updateRouteState(), _defaultDashboardId() and _userForceFullscreen() still contain the 1.7.x logic but are now dead code.
  • lib/core/init/init_app.dart, lib/core/init/inti_region_app.dart: ThingsboardInitApp / ThingsboardInitRegionApp were instantiated from init_routes.dart in 1.7.0. The go_router/riverpod rewrite removed that file (CE commit 815ee13, merged into PE 1.8.0), so TbContext.onUserLoaded() → updateRouteState() never runs.
  • lib/modules/main/providers/navigation_provider.dart (secondary): when mobileLoginInfo.pages is an empty list, Profile becomes the only nav item and therefore the landing page. Suggest falling back to the default page set (same as for null) or never landing on Profile.

home_handler.dart is identical in thingsboard/flutter_thingsboard_app (CE), so CE is affected too.

Proposed fix (HomeHandler), restores 1.7.x behavior

Code
@override
void subscribe(BuildContext context, WidgetRef ref) {
  _sub = ref.listenManual(loginProvider, (prev, next) {
    final path = GoRouterState.of(context).fullPath;
    if (next.isFullyAuthenticated() &&
        prev?.isFullyAuthenticated() == false &&
        path != LoginRoutes.login + LoginRoutes.updateRequired) {
      ref.read(navigationProvider.notifier).onLoggedIn();
      final nav = ref.read(navigationProvider);
      final String? firstPath =
          nav.bottomBarPages.isNotEmpty ? nav.bottomBarPages.first.path : null;
      SchedulerBinding.instance.addPostFrameCallback((_) {
        scheduleMicrotask(() => _routeAfterLogin(context, next, firstPath));
      });
    }
  });
}

Future<void> _routeAfterLogin(
    BuildContext context, LoginState login, String? firstPath) async {
  final info = login.user?.additionalInfo;
  final String? dashboardId = info?['defaultDashboardId']?.toString();

  if (dashboardId != null &&
      dashboardId.isNotEmpty &&
      await _hasDashboardAccess(dashboardId)) {
    if (!context.mounted) return;
    final client = getIt<ITbClientService>().client;
    final bool fullscreen = client.getAuthUser()?.isPublic == true ||
        info?['defaultDashboardFullscreen'] == true;

    if (fullscreen) {
      context.go('${DashboardRoutes.fullscreenDashboard}/$dashboardId');
      return;
    }
    if (firstPath != null) context.go(firstPath);
    await Future<void>.delayed(Duration.zero);
    if (context.mounted) {
      context.push('${DashboardRoutes.dashboard}/$dashboardId');
    }
    return;
  }

  if (firstPath != null && context.mounted) context.go(firstPath);
}

Future<bool> _hasDashboardAccess(String id) async {
  try {
    final d = await getIt<ITbClientService>()
        .client
        .getDashboardService()
        .getDashboard(id);
    return d != null;
  } catch (_) {
    return false;
  }
}

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions