mirror of
https://github.com/dbeaver/cloudbeaver.git
synced 2026-10-16 14:50:15 +08:00
Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b636577a23 | ||
|
|
21c772f281 |
@@ -31,9 +31,16 @@ export function promptForFiles({ multiple = false, accept }: { multiple?: boolea
|
||||
|
||||
let settled = false;
|
||||
|
||||
const SAFETY_TIMEOUT_MS = 10 * 60 * 1000;
|
||||
const safetyTimeoutId = setTimeout(() => {
|
||||
if (!settled) {
|
||||
settleErr(new Error('File selection timed out'));
|
||||
}
|
||||
}, SAFETY_TIMEOUT_MS);
|
||||
|
||||
function cleanup() {
|
||||
window.removeEventListener('focus', onWindowFocus, true);
|
||||
document.removeEventListener('visibilitychange', onVisibilityChange, true);
|
||||
window.clearTimeout(safetyTimeoutId);
|
||||
|
||||
if (input.isConnected) {
|
||||
document.body.removeChild(input);
|
||||
}
|
||||
@@ -63,25 +70,9 @@ export function promptForFiles({ multiple = false, accept }: { multiple?: boolea
|
||||
}
|
||||
});
|
||||
|
||||
function afterPickerClosedCheck() {
|
||||
setTimeout(() => {
|
||||
if (!settled) {
|
||||
settleErr(new Error('No files selected'));
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
function onWindowFocus() {
|
||||
afterPickerClosedCheck();
|
||||
}
|
||||
function onVisibilityChange() {
|
||||
if (document.visibilityState === 'visible') {
|
||||
afterPickerClosedCheck();
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener('focus', onWindowFocus, true);
|
||||
document.addEventListener('visibilitychange', onVisibilityChange, true);
|
||||
input.addEventListener('cancel', () => {
|
||||
settleOk([]);
|
||||
});
|
||||
|
||||
document.body.appendChild(input);
|
||||
|
||||
@@ -90,12 +81,5 @@ export function promptForFiles({ multiple = false, accept }: { multiple?: boolea
|
||||
} catch (err) {
|
||||
settleErr(err instanceof Error ? err : new Error('File dialog blocked'));
|
||||
}
|
||||
|
||||
const SAFETY_TIMEOUT_MS = 10 * 60 * 1000;
|
||||
setTimeout(() => {
|
||||
if (!settled) {
|
||||
settleErr(new Error('File selection timed out'));
|
||||
}
|
||||
}, SAFETY_TIMEOUT_MS);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -68,8 +68,18 @@ export const SubMenuElement = observer<ISubMenuElementProps>(function SubMenuEle
|
||||
|
||||
const handler = subMenuData.handler;
|
||||
|
||||
// TODO: it's better to remove this expensive check to allow lazy loading of menu items
|
||||
const hidden = getComputed(() => subMenuData.items.every(item => item.hidden) || handler?.isHidden?.(subMenuData.context));
|
||||
// NOTE: some menus rely on lazy loading. When items are not loaded yet `items` may be empty,
|
||||
// but the submenu still must be rendered to allow opening it and triggering loaders.
|
||||
const hidden = getComputed(() => {
|
||||
if (handler?.isHidden?.(subMenuData.context)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const hasVisibleItems = subMenuData.items.some(item => !item.hidden);
|
||||
const canLazyLoadItems = subMenuData.loaders.length > 0;
|
||||
|
||||
return !hasVisibleItems && !canLazyLoadItems;
|
||||
});
|
||||
const IconComponent = handler?.iconComponent?.() ?? subMenu.iconComponent?.();
|
||||
const extraProps = handler?.getExtraProps?.() ?? (subMenu.getExtraProps?.() as any);
|
||||
// TODO: fix, this triggers `Cannot update a component (`SubMenuElement`) while rendering a different component`
|
||||
|
||||
+6
-2
@@ -100,12 +100,16 @@ export class DataGridContextMenuSaveContentService {
|
||||
}
|
||||
|
||||
if (action === ACTION_UPLOAD) {
|
||||
promptForFiles().then(files => {
|
||||
try {
|
||||
const files = await promptForFiles();
|
||||
const file = files?.[0] ?? undefined;
|
||||
|
||||
if (file) {
|
||||
edit.set(key, createResultSetBlobValue(file));
|
||||
}
|
||||
});
|
||||
} catch (exception: any) {
|
||||
this.notificationService.logException(exception, 'ui_upload_file_fail');
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
+9
-5
@@ -102,7 +102,7 @@ export function useValuePanelImageValue({ model, resultIndex }: Props) {
|
||||
return this.contentAction.isDownloadable(this.cellHolder);
|
||||
}
|
||||
|
||||
return this.staticSrc && !this.truncated;
|
||||
return !!this.staticSrc && !this.truncated;
|
||||
},
|
||||
get canUpload() {
|
||||
if (!this.cellHolder) {
|
||||
@@ -115,7 +115,7 @@ export function useValuePanelImageValue({ model, resultIndex }: Props) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return this.cellHolder && this.contentAction.isBlobTruncated(this.cellHolder);
|
||||
return !!this.cellHolder && this.contentAction.isBlobTruncated(this.cellHolder);
|
||||
},
|
||||
async download() {
|
||||
try {
|
||||
@@ -134,13 +134,17 @@ export function useValuePanelImageValue({ model, resultIndex }: Props) {
|
||||
this.notificationService.logException(exception, 'data_viewer_presentation_value_content_download_error');
|
||||
}
|
||||
},
|
||||
upload() {
|
||||
promptForFiles().then(files => {
|
||||
async upload() {
|
||||
try {
|
||||
const files = await promptForFiles();
|
||||
const file = files?.[0];
|
||||
|
||||
if (file && this.selectedCell) {
|
||||
this.editAction.set(this.selectedCell, createResultSetBlobValue(file));
|
||||
}
|
||||
});
|
||||
} catch (exception: any) {
|
||||
this.notificationService.logException(exception, 'ui_upload_file_fail');
|
||||
}
|
||||
},
|
||||
async loadFullImage() {
|
||||
if (!this.selectedCell) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
* Copyright (C) 2020-2025 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
||||
Reference in New Issue
Block a user