Skip to content

Conversation

@artemmufazalov
Copy link
Member

@artemmufazalov artemmufazalov commented Nov 19, 2025

Part of #2892

Currently it can be checked with table columns width.
Stand (without meta): https://nda.ya.ru/t/BEIjuuLI7N8Qd7

Sync all values within api onQueryStarted instead of useEffects.

This approach proved itself good with and without meta api. Without meta api there is only 1 failed test (against 100-200 before): #3054

greptile-review

CI Results

Test Status: ⚠️ FLAKY

📊 Full Report

Total Passed Failed Flaky Skipped
378 375 0 1 2
Test Changes Summary ⏭️2

⏭️ Skipped Tests (2)

  1. Scroll to row, get shareable link, navigate to URL and verify row is scrolled into view (tenant/diagnostics/tabs/queries.test.ts)
  2. Copy result button copies to clipboard (tenant/queryEditor/queryEditor.test.ts)

Bundle Size: ✅

Current: 62.34 MB | Main: 62.34 MB
Diff: 1.76 KB (-0.00%)

✅ Bundle size unchanged.

ℹ️ CI Information
  • Test recordings for failed tests are available in the full report.
  • Bundle size is measured for the entire 'dist' directory.
  • 📊 indicates links to detailed reports.
  • 🔺 indicates increase, 🔽 decrease, and ✅ no change in bundle size.

@artemmufazalov artemmufazalov changed the title feat(useSetting); sync values with LS and store in api feat(useSetting): sync values with LS and store in api Nov 19, 2025
Copilot finished reviewing on behalf of artemmufazalov November 19, 2025 17:39
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR refactors the settings synchronization architecture by moving the sync logic from useEffect hooks in useSetting.ts to RTK Query's onQueryStarted lifecycle hooks in the API layer. The main goal is to centralize settings synchronization between localStorage, Redux store, and the meta settings API.

Key Changes:

  • Consolidates all settings sync logic into the settingsApi endpoints' onQueryStarted hooks
  • Simplifies useSetting hook by removing multiple useEffect dependencies
  • Handles localStorage and API settings synchronization at the API layer instead of component layer

Reviewed Changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
src/store/reducers/settings/utils.ts Adds helper functions getSettingDefault and shouldSyncSettingToLS to support centralized settings sync logic
src/store/reducers/settings/useSetting.ts Removes all useEffect-based sync logic and simplifies hook to only trigger API queries and mutations
src/store/reducers/settings/constants.ts Updates SETTINGS_OPTIONS type to explicitly allow undefined values for better type safety
src/store/reducers/settings/api.ts Implements comprehensive sync logic in onQueryStarted hooks for both query and mutation endpoints, handling localStorage and store updates
src/services/api/metaSettings.ts Updates return type to allow undefined for settings that don't exist in the backend

@artemmufazalov artemmufazalov marked this pull request as ready for review November 19, 2025 20:11
@Raubzeug
Copy link
Contributor

@greptile-review

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

8 files reviewed, 2 comments

Edit Code Review Agent Settings | Greptile


return {data};
} catch (error) {
console.error('Cannot get settings:', error);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can it be that error is "Cannot get setting" - but the real situation is that one of patches failed ?

@astandrik
Copy link
Collaborator

astandrik commented Nov 20, 2025

Now as I see we have three sources of truth:

  • LS
  • Backend
  • Redux Store

And we struggle to keep all of them in sync
Is my assumption correct?

@artemmufazalov
Copy link
Member Author

Now as I see we have three sources of truth:

  • LS
  • Backend
  • Redux Store

And we struggle to keep all of them in sync Is my assumption correct?

Yes, everything is to keep them in sync

@astandrik
Copy link
Collaborator

Now as I see we have three sources of truth:

  • LS
  • Backend
  • Redux Store

And we struggle to keep all of them in sync Is my assumption correct?

Yes, everything is to keep them in sync

Is it a goal or temporary state?

@artemmufazalov
Copy link
Member Author

Is it a goal or temporary state?

It's a goal

const newValue = data ?? {name, user};

// Try to sync local value if there is no backend value
syncLocalValueToMetaIfNoData(newValue, dispatch);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it possible that null/undefined on backend is intentional?
i mean we removed some setting for example

but LS has some old value (in another browser for example) and pushes this setting to backend?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a current limitation, yes. We cannot have null or undefined as backend value, there should be at least something, otherwise defined localStorage value will be loaded to backend. Without this it's unclear, when we should sync local value to backend

return;
}

const localValue = localStorage.getItem(params.name);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we use localStorage directly here but there are already functions for this like

readSettingValueFromLS / shouldSyncSettingToLS

these functions as I may suppose were created to make work with LS somehow guarded

@astandrik
Copy link
Collaborator

astandrik commented Nov 20, 2025

Now as I see we have three sources of truth:

  • LS
  • Backend
  • Redux Store

And we struggle to keep all of them in sync Is my assumption correct?

Yes, everything is to keep them in sync

I thought this over again and came to a conclusion that actually there is one source of truth (backend) while LS and rtq storage are used as caches for interface rensponsiveness so actually its not "three sources of truth" but "one with two caches"

Does it make sense?

@artemmufazalov
Copy link
Member Author

I thought this over again and came to a conclusion that actually there is one source of truth (backend) while LS and rtq storage are used as caches for interface rensponsiveness so actually its not "three sources of truth" but "one with two caches"

Does it make sense?

In general, you are right. But it depends on app installation. There are 3 cases.

  1. No meta (embedded single cluster version). LS is used as source of truth, meta is not used at all, we read and load value to redux to use it in the app without a need to read it from LS.

  2. There is meta service with settings. In this case value from LS is used as temporary initial value while setting from meta is not loaded. When value is loaded, it is used.

So, preload data from LS to store, load actual value from meta when request is finished.

  1. There is meta service, but there is no meta setting value. It is possible case in migration period - users have all their setting in LS now. It is similar to case 2, but when we receive undefined value from backend, we load value from LS there

In all cases redux is used as sync cache for data.

@astandrik
Copy link
Collaborator

astandrik commented Nov 20, 2025

So there are two main scenarios with mainly opposite mechanics

  1. with meta
  2. without meta

It appears we try to handle both at once with one handler and therefore it looks a bit complex

I'm trying to imagine if we could explicitly split these scenarios for clarity and maintainability

its possible to postpone this and separate to some tech issue but would be great if we could handle it at once

@artemmufazalov artemmufazalov marked this pull request as draft December 5, 2025 08:30
@artemmufazalov artemmufazalov force-pushed the settings-sync-values-in-api branch from 29a9e3d to 759ba53 Compare December 5, 2025 08:30
Comment on lines +109 to +110
isFetching={isFetching}
isLoading={isLoading}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Table loading changes are needed to synchronize settings and data loading states, without it tests somehow fail to find table container

proxyMeta: undefined | boolean;
// this setting allows to use schema object path relative to database in api requests
useRelativePath: undefined | boolean;
useMetaSettings: undefined | boolean;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved useMetaSettings from uiFactory to api setup. The reason is that uiFactory property requires api and uiFactory to be inited in the specific order: first we need to configureUIFactory and only after setup api. Otherwise we need two settings - for uiFactory and to api.

So this help to reduce it to only one setting without any additional requirements

isAuthenticated: true,
user: undefined,
id: undefined,
metaUser: undefined,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did not figured out how to properly receive metaUser value yet, so I decided to test everything with some hardcoded user and to do all metaUser code separately - there are additional user points in issue checklist.

What are the problems with metaUser:

  1. The logic may be different in different installations
  2. It should not break current authentication cases
  3. We need somehow to tackle the case, when user do not have access to meta cluster

@artemmufazalov artemmufazalov changed the title feat(useSetting): sync values with LS and store in api feat(settings): simplify hook, split meta and LS cases Dec 5, 2025
@artemmufazalov artemmufazalov marked this pull request as ready for review December 5, 2025 09:05
Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additional Comments (1)

  1. src/store/reducers/capabilities/capabilities.ts, line 19 (link)

    style: inconsistent error handling - one catch block uses serializeError while the other returns raw error. Should both error handlers use the same serialization approach for consistency?

    Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

17 files reviewed, 4 comments

Edit Code Review Agent Settings | Greptile

Copilot finished reviewing on behalf of artemmufazalov December 5, 2025 09:08
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 17 out of 17 changed files in this pull request and generated 5 comments.

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

17 files reviewed, 2 comments

Edit Code Review Agent Settings | Greptile

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants