Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cb 3555 view byte type data decoded #2256

Merged
merged 16 commits into from
Dec 29, 2023

Conversation

sergeyteleshev
Copy link
Contributor

@sergeyteleshev sergeyteleshev commented Dec 26, 2023

Снимок экрана 2023-12-27 в 14 10 17

I removed html/xml/json tabs for blobs. it seems redundant for me cause it basically shows the same thing as the "text" tab

I also decided not to go with BinaryValue entity and use TextValue entity due to the fact base64 and hex are a texts and there are less duplicated code

@sergeyteleshev sergeyteleshev self-assigned this Dec 26, 2023
@sergeyteleshev sergeyteleshev requested review from Wroud and devnaumov and removed request for Wroud December 27, 2023 13:11
@@ -28,6 +28,8 @@ export default [
['data_viewer_presentation_value_text_html_title', 'HTML'],
['data_viewer_presentation_value_text_xml_title', 'XML'],
['data_viewer_presentation_value_text_json_title', 'JSON'],
['data_viewer_presentation_value_text_hex_title', 'HEX'],
Copy link
Member

Choose a reason for hiding this comment

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

No need to add these to locales

Copy link
Contributor Author

Choose a reason for hiding this comment

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

why? all other tabs has locales, it should be consistent, I believe

@@ -0,0 +1,20 @@
import { getMIME, isImageFormat, isValidUrl } from '@cloudbeaver/core-utils';
Copy link
Member

Choose a reason for hiding this comment

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

License text here and below

});
this.textValuePresentationService.add({
key: 'application/json',
name: 'data_viewer_presentation_value_text_json_title',
order: Number.MAX_SAFE_INTEGER,
panel: () => React.Fragment,
isHidden: (_, context) => isBlobPresentationAvailable(context),
Copy link
Member

Choose a reason for hiding this comment

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

image image

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed here:
56333d5

@@ -25,6 +28,20 @@ export function useAutoFormat() {
return value;
}
},
async formatBlob(type: string, value: IResultSetContentValue) {
Copy link
Member

Choose a reason for hiding this comment

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

seems like we dont "await" anything here

const [value, setValue] = useState<string>('');
const firstSelectedCell = selection.elements?.[0] ?? focusCell;
const autoFormat = !!firstSelectedCell && !editor.isElementEdited(firstSelectedCell);

Copy link
Member

Choose a reason for hiding this comment

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

Do wee need to use useEffect here?

 const candidate = format.get(firstSelectedCell);
 
  if (isResultSetContentValue(candidate)) {
      return formatter.formatBlob(currentContentType, candidate);
    }
    
 return formatter.format(currentContentType, format.getText(firstSelectedCell))

Also seems like a lot of initialization logic is here but its not in use until autoFormat is true

Copy link
Contributor Author

Choose a reason for hiding this comment

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

removed it, thanks!

import type { IDatabaseResultSet } from '../../DatabaseDataModel/IDatabaseResultSet';
import { useAutoFormat } from './useAutoFormat';

type Props = {
Copy link
Member

Choose a reason for hiding this comment

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

Please use interfaces

Comment on lines +9 to +17
export function base64ToHex(base64String: string): string {
const raw = atob(base64String);
let result = '';
for (let i = 0; i < raw.length; i++) {
const hex = raw.charCodeAt(i).toString(16);
result += hex.length === 2 ? hex : `0${hex}`;
}
return result.toUpperCase();
}
Copy link
Member

Choose a reason for hiding this comment

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

This function is synchronous and will lead to thread blocking and memory consumption. Please be careful with use cases for this function and verify that in the value panel it can handle max binary value without lags.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

image

I tried do upload a video and the interface shows that only limited size is allowed. On this limited size feature works just fine. I added a comment to this helper so we use it carefully. Maybe when we need it we can make worker do the calculations in its own thread so the main thread do not freeze or do some other event loop optimizations

This is the great notice, by the way, thanks!

Comment on lines 34 to 41
if (isResultSetContentValue(candidate)) {
formatter.formatBlob(currentContentType, candidate).then(data => {
data && setValue(data);
});
return;
}

setValue(formatter.format(currentContentType, format.getText(firstSelectedCell)));
Copy link
Member

Choose a reason for hiding this comment

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

This code is unstable, imagine that you selected big value and then before promise resolved you selected another one that is not content value. This will lead to set outdated data.

Also please don't use a && b() construction at all. Please don't use a && b constructions in not inline context.

const firstSelectedCell = selection.elements?.[0] ?? focusCell;
const autoFormat = !!firstSelectedCell && !editor.isElementEdited(firstSelectedCell);

useEffect(() => {
Copy link
Member

Choose a reason for hiding this comment

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

Here we probably want something like this:

const cellValue = ...;
const formattedValue = useMemo(() => format(cellValue), [cellValue]);

It's main idea you can rewrite it. The main goal here is to sync cellValue and formattedValue and prevent cases when wrong formattedValue displayed. (For example we switched cells fast or cell value updated)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

the hook is fully synchronous right now so it has more predictable behaviour excluding fast cell switching

@sergeyteleshev sergeyteleshev merged commit d6cd15c into devel Dec 29, 2023
4 checks passed
@sergeyteleshev sergeyteleshev deleted the CB-3555-view-byte-type-data-decoded branch December 29, 2023 16:34
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.

3 participants