Skip to content

Commit

Permalink
Merge branch 'devel' into CB-5133-tree-expand-focus
Browse files Browse the repository at this point in the history
  • Loading branch information
dariamarutkina authored May 20, 2024
2 parents 496e6d4 + 0dddeb7 commit c111bf0
Show file tree
Hide file tree
Showing 21 changed files with 234 additions and 108 deletions.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,16 @@ You can see live demo of CloudBeaver here: https://demo.cloudbeaver.io

## Changelog

### 24.0.5. 2024-05-20
- The process of application update was improved - you can track the application update process now;
- All popup dialogs became available for screen readers, including JAWS, to improve the experience for users with disabilities;
- Data Editor:
- Large text values (more than 100 Kb) are now automatically opened in the Value panel;
- DuckDB:
- Spatial data visualization support was added;
- The driver has been updated to version 0.10.2;
- Different bug fixes and enhancements have been made.

### 24.0.4. 2024-05-06
- Added the ability to stop the process of file upload in the table;
- Row count calculation in the grid can be cancelled for Data Editor and SQL Editor;
Expand Down
10 changes: 0 additions & 10 deletions deploy/supervisor/cloudbeaver.conf

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import org.jkiss.dbeaver.model.auth.SMCredentialsProvider;
import org.jkiss.dbeaver.model.auth.SMSessionContext;
import org.jkiss.dbeaver.model.data.json.JSONUtils;
import org.jkiss.dbeaver.model.impl.app.ApplicationRegistry;
import org.jkiss.dbeaver.model.rm.RMController;
import org.jkiss.dbeaver.model.rm.RMProject;
import org.jkiss.dbeaver.model.secret.DBSSecretController;
Expand Down Expand Up @@ -248,8 +249,13 @@ public synchronized String getApplicationInstanceId() throws DBException {
if (instanceId == null) {
try {
byte[] macAddress = RuntimeUtils.getLocalMacAddress();
// workspace id from is read from property file
instanceId = BaseWorkspaceImpl.readWorkspaceIdProperty() + "_" + CommonUtils.toHexString(macAddress);
instanceId = String.join(
"_",
ApplicationRegistry.getInstance().getApplication().getId(),
BaseWorkspaceImpl.readWorkspaceIdProperty(), // workspace id is read from property file
CommonUtils.toHexString(macAddress),
CommonUtils.toString(getServerPort())
);
} catch (Exception e) {
throw new DBException("Error during generation instance id generation", e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public void handleEvent(@NotNull EVENT event) {
break;
case USER_DELETED:
if (event instanceof WSUserDeletedEvent userDeletedEvent) {
sessionManager.closeUserSession(userDeletedEvent.getUserId());
sessionManager.closeUserSession(userDeletedEvent.getDeletedUserId());
}
break;
default:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.jkiss.dbeaver.model.sql.SQLDialect;
import org.jkiss.dbeaver.model.sql.translate.SQLQueryTranslator;
import org.jkiss.dbeaver.runtime.DBWorkbench;
import org.jkiss.dbeaver.utils.GeneralUtils;
import org.junit.Assert;
import org.junit.Test;

Expand Down Expand Up @@ -191,10 +192,15 @@ private static void translateAndValidateQueries(
);
Assert.assertEquals(
entry.getKey().getDialectId() + " has invalid syntax " + translated,
entry.getValue().toLowerCase(),
translated.toLowerCase()
normalizeScript(entry.getValue()),
normalizeScript(translated)
);
}
}

private static String normalizeScript(String script) {
// Unify for tests
return script.toLowerCase().replace(GeneralUtils.getDefaultLineSeparator(), "\n");
}

}
4 changes: 2 additions & 2 deletions webapp/packages/core-app/src/Body.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,10 @@ export const Body = observer(function Body() {
<Loader className={s(styles, { loader: true })} suspense>
{Screen && <Screen {...screenService.routerService.params} />}
</Loader>
<Loader className={s(styles, { loader: true })} suspense>
<Loader suspense overlay>
<DialogsPortal />
</Loader>
<Loader className={s(styles, { loader: true })} suspense>
<Loader suspense overlay>
<Notifications />
</Loader>
</div>
Expand Down
31 changes: 31 additions & 0 deletions webapp/packages/core-blocks/src/ErrorBoundary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@ import { ErrorContext, IExceptionContext } from './ErrorContext';
import { ExceptionMessage } from './ExceptionMessage';

interface Props {
simple?: boolean;
icon?: boolean;
root?: boolean;
inline?: boolean;
remount?: boolean;
className?: string;
fallback?: React.ReactElement;
onClose?: () => any;
onRefresh?: () => any;
}
Expand Down Expand Up @@ -71,6 +73,35 @@ export class ErrorBoundary extends React.Component<React.PropsWithChildren<Props
const { root, inline, icon, children, className, onClose } = this.props;

for (const errorData of this.state.exceptions) {
if (this.props.simple) {
const stack = errorData.errorInfo?.componentStack || errorData.error.stack;
return (
<div>
<p>Something went wrong.</p>
{onClose && (
<div className={style.action}>
<button type="button" onClick={onClose}>
Close
</button>
</div>
)}
{this.canRefresh && (
<div className={style.action}>
<button type="button" onClick={this.refresh}>
Refresh
</button>
</div>
)}
<div>
{errorData.error.toString()}
{stack && <br />}
{stack}
</div>
{this.props.fallback}
</div>
);
}

if (root) {
return (
<DisplayError className={className} root={root} error={errorData.error} errorInfo={errorData.errorInfo}>
Expand Down
1 change: 1 addition & 0 deletions webapp/packages/core-blocks/src/Loader/Loader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ export const Loader = observer<Props>(function Loader({
small={small}
inline={inline}
fullSize={fullSize}
overlay={overlay}
className={className}
inlineException={inlineException}
/>
Expand Down
19 changes: 11 additions & 8 deletions webapp/packages/core-blocks/src/ResourcesHooks/useResource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,10 @@ export interface ResourceKeyWithIncludes<TKey, TIncludes> {
readonly includes: TIncludes;
}

type ResourceData<TResource extends IResource<any, any, any, any>, TKey, TIncludes> = TResource extends CachedDataResource<any, any, any, any>
? CachedResourceData<TResource>
: CachedMapResourceLoader<TKey, CachedResourceKey<TResource>, CachedResourceData<TResource> extends Map<any, infer I> ? I : never, TIncludes>;
type ResourceData<TResource extends IResource<any, any, any, any>, TKey, TIncludes> =
TResource extends CachedDataResource<any, any, any, any>
? CachedResourceData<TResource>
: CachedMapResourceLoader<TKey, CachedResourceKey<TResource>, CachedResourceData<TResource> extends Map<any, infer I> ? I : never, TIncludes>;

interface IActions<TResource extends IResource<any, any, any, any>, TKey, TIncludes> {
active?: boolean;
Expand Down Expand Up @@ -91,11 +92,12 @@ interface IDataResourceResult<TResource, TIncludes> extends IMapResourceState<TR
exception: Error | null;
}

type TResult<TResource, TKey, TIncludes> = TResource extends CachedDataResource<any, any, any>
? IDataResourceResult<TResource, TIncludes>
: TKey extends ResourceKeyList<any> | ResourceKeyListAlias<any, any>
? IMapResourceListResult<TResource, TIncludes>
: IMapResourceResult<TResource, TIncludes>;
type TResult<TResource, TKey, TIncludes> =
TResource extends CachedDataResource<any, any, any>
? IDataResourceResult<TResource, TIncludes>
: TKey extends ResourceKeyList<any> | ResourceKeyListAlias<any, any>
? IMapResourceListResult<TResource, TIncludes>
: IMapResourceResult<TResource, TIncludes>;

/**
* Accepts resource class or instance and returns resource state.
Expand Down Expand Up @@ -244,6 +246,7 @@ export function useResource<
}
this.exception = null;
} catch (exception: any) {
console.error(exception);
if (this.loadingPromise !== loadingPromise) {
return;
}
Expand Down
32 changes: 18 additions & 14 deletions webapp/packages/core-blocks/src/useS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,18 +46,20 @@ export function useS<T extends ComponentStyle[]>(...componentStyles: [...T]): Ex
const stylesRef = useRef<ComponentStyle[]>([]);
const [patch, forceUpdate] = useState(0);
const loadedStyles = useRef<BaseStyles[]>([]);
const themeService = useService(ThemeService);
const [currentThemeId, setCurrentThemeId] = useState(() => themeService.themeId);
const lastThemeRef = useRef<string>(currentThemeId);
// @ts-ignore
const filteredStyles = themeService.mapStyles(componentStyles.flat(Infinity).filter(Boolean) as Style[], context);
const themeService = useService(ThemeService, true);
const [currentThemeId, setCurrentThemeId] = useState(() => themeService?.themeId);
const lastThemeRef = useRef<string | undefined>(currentThemeId);
const filteredStyles = themeService
? // @ts-ignore
themeService.mapStyles(componentStyles.flat(Infinity).filter(Boolean) as Style[], context)
: (componentStyles.flat(Infinity).filter(Boolean) as Style[]);
const trackTheme = filteredStyles.some(style => typeof style === 'function');

useExecutor({
executor: themeService.onChange,
executor: themeService?.onChange,
handlers: [
function updateThemeId(theme) {
if (currentThemeId !== themeService.themeId && trackTheme) {
if (currentThemeId !== themeService?.themeId && trackTheme) {
setCurrentThemeId(theme.id);
}
},
Expand All @@ -76,22 +78,24 @@ export function useS<T extends ComponentStyle[]>(...componentStyles: [...T]): Ex
lastThemeRef.current = currentThemeId;

for (const style of filteredStyles) {
let data: ClassCollection<Record<string, string>> | Promise<undefined | BaseStyles | BaseStyles[]>;
let data: ClassCollection<Record<string, string>> | Promise<undefined | BaseStyles | BaseStyles[]> | undefined;

if (typeof style === 'object') {
data = style;
} else {
if (!stylesCache.get(currentThemeId).has(style)) {
data = style(currentThemeId);
stylesCache.get(currentThemeId).set(style, style(currentThemeId));
} else {
data = stylesCache.get(currentThemeId).get(style)!;
if (currentThemeId !== undefined) {
if (!stylesCache.get(currentThemeId).has(style)) {
data = style(currentThemeId);
stylesCache.get(currentThemeId).set(style, style(currentThemeId));
} else {
data = stylesCache.get(currentThemeId).get(style)!;
}
}
}

if (data instanceof Promise) {
themedStyles.push(data);
} else {
} else if (data !== undefined) {
staticStyles.push(data);
}
}
Expand Down
2 changes: 0 additions & 2 deletions webapp/packages/core-bootstrap/src/bootstrap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,11 @@ export async function bootstrap(plugins: PluginManifest[]): Promise<App> {
const exception = context.getContext(executionExceptionContext);

if (exception.exception) {
console.error(exception.exception);
render.renderError(exception.exception);
}
});

if (exception) {
console.error(exception);
render.renderError(exception);
} else {
render.renderApp();
Expand Down
31 changes: 19 additions & 12 deletions webapp/packages/core-bootstrap/src/renderLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,22 +47,29 @@ export function renderLayout(serviceInjector: IServiceInjector): IRender {
},
renderApp() {
this.initRoot().render(
<AppContext app={serviceInjector}>
<ErrorBoundary root>
<Suspense fallback={<Loader className={s(styles, { loader: true })} />}>
<BodyLazy />
<HideAppLoadingScreen />
</Suspense>
</ErrorBoundary>
</AppContext>,
<ErrorBoundary fallback={<HideAppLoadingScreen />} simple>
<AppContext app={serviceInjector}>
<ErrorBoundary fallback={<HideAppLoadingScreen />} root>
<Suspense fallback={<Loader className={s(styles, { loader: true })} />}>
<BodyLazy />
<HideAppLoadingScreen />
</Suspense>
</ErrorBoundary>
</AppContext>
</ErrorBoundary>,
);
},
renderError(exception?: any) {
if (exception) {
console.error(exception);
}
this.initRoot().render(
<AppContext app={serviceInjector}>
<DisplayError error={exception} root />
<HideAppLoadingScreen />
</AppContext>,
<ErrorBoundary fallback={<HideAppLoadingScreen />} simple>
<AppContext app={serviceInjector}>
<DisplayError error={exception} root />
<HideAppLoadingScreen />
</AppContext>
</ErrorBoundary>,
);
},
};
Expand Down
56 changes: 32 additions & 24 deletions webapp/packages/core-browser/src/ServiceWorkerService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,39 +44,47 @@ export class ServiceWorkerService extends Disposable {
return;
}

if (process.env.NODE_ENV === 'development') {
const registration = await navigator.serviceWorker.getRegistration(this.workerURL);
registration?.unregister();
} else {
this.workbox = new Workbox(this.workerURL);
this.registration = (await this.workbox.register()) || null;
// should be after registration
this.registerEventListeners();

if (this.registration?.active) {
this.isUpdating = true;
try {
if (process.env.NODE_ENV === 'development') {
const registration = await navigator.serviceWorker.getRegistration(this.workerURL);
registration?.unregister();
} else {
this.workbox = new Workbox(this.workerURL);
this.registration = (await this.workbox.register()) || null;
// should be after registration
this.registerEventListeners();

if (this.registration?.active) {
this.isUpdating = true;
}
}
} catch (exception: any) {
console.error(exception);
}
}

async load(): Promise<void> {
if (this.registration?.installing || this.registration?.waiting) {
this.onUpdate.execute({
type: this.isUpdating ? 'updating' : 'installing',
});
}
try {
if (this.registration?.installing || this.registration?.waiting) {
this.onUpdate.execute({
type: this.isUpdating ? 'updating' : 'installing',
});
}

await this.workbox?.update();
await this.workbox?.update();

if (this.registration?.active) {
// wait for update only for active service worker
if (this.registration.installing || this.registration.waiting) {
// handled by refresh at 'controlling' event
await new Promise(() => {});
if (this.registration?.active) {
// wait for update only for active service worker
if (this.registration.installing || this.registration.waiting) {
// handled by refresh at 'controlling' event
await new Promise(() => {});
}
}
}

this.updateIntervalId = setInterval(() => this.workbox?.update(), 1000 * 60 * 60 * 24);
this.updateIntervalId = setInterval(() => this.workbox?.update(), 1000 * 60 * 60 * 24);
} catch (exception: any) {
console.error(exception);
}
}

dispose(): void {
Expand Down
4 changes: 4 additions & 0 deletions webapp/packages/core-cli/configs/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ module.exports = (env, argv) => {
/\.tsbuildinfo$/,
/\.DS_Store$/,
/\.svg$/,
/\.png$/,
/\.jpg$/,
/\.gif$/,
/\.jpeg$/,
/.woff2?$/,
/.eot$/,
/.ttf$/,
Expand Down
Loading

0 comments on commit c111bf0

Please sign in to comment.