SYNC: new object button refactor + diagram accesibility

This commit is contained in:
SPRINX0\prochazka
2025-07-16 10:48:58 +02:00
committed by Diflow
parent 982098672e
commit 2cd56d5041
6 changed files with 165 additions and 80 deletions

View File

@@ -4,11 +4,15 @@
export let icon; export let icon;
export let title; export let title;
export let description; export let description;
export let enabled;
export let colorClass;
$: disabled = !enabled;
</script> </script>
<div class="new-object-button" on:click> <div class="new-object-button" on:click class:enabled class:disabled>
<div class="icon"> <div class="icon">
<FontIcon {icon} /> <FontIcon {icon} colorClass={enabled ? colorClass : null} />
</div> </div>
<span class="title">{title}</span> <span class="title">{title}</span>
{#if description} {#if description}
@@ -23,13 +27,16 @@
background-color: var(--theme-bg-1); background-color: var(--theme-bg-1);
border-radius: 4px; border-radius: 4px;
border: 1px solid var(--theme-border); border: 1px solid var(--theme-border);
cursor: pointer;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
} }
.new-object-button:hover {
.new-object-button.enabled {
cursor: pointer;
}
.new-object-button.enabled:hover {
background-color: var(--theme-bg-2); background-color: var(--theme-bg-2);
} }
.icon { .icon {
@@ -48,4 +55,18 @@
font-size: 0.9em; font-size: 0.9em;
color: var(--theme-font-2); color: var(--theme-font-2);
} }
.new-object-button.disabled .title {
color: var(--theme-font-2);
}
.new-object-button.disabled .description {
color: var(--theme-font-2);
}
.new-object-button.disabled .icon {
color: var(--theme-font-2);
}
.new-object-button.disabled {
cursor: not-allowed;
opacity: 0.5;
}
</style> </style>

View File

@@ -24,6 +24,18 @@
onClick: () => getCurrentEditor().exportDiagram(), onClick: () => getCurrentEditor().exportDiagram(),
testEnabled: () => getCurrentEditor()?.canExport(), testEnabled: () => getCurrentEditor()?.canExport(),
}); });
registerCommand({
id: 'diagram.deleteSelectedTables',
category: 'Designer',
toolbarName: 'Remove',
name: 'Remove selected tables',
icon: 'icon delete',
toolbar: true,
isRelatedToTab: true,
onClick: () => getCurrentEditor().deleteSelectedTables(),
testEnabled: () => getCurrentEditor()?.areTablesSelected(),
});
</script> </script>
<script lang="ts"> <script lang="ts">
@@ -54,6 +66,7 @@
import createRef from '../utility/createRef'; import createRef from '../utility/createRef';
import { isProApp } from '../utility/proTools'; import { isProApp } from '../utility/proTools';
import dragScroll from '../utility/dragScroll'; import dragScroll from '../utility/dragScroll';
import FormStyledButton from '../buttons/FormStyledButton.svelte';
export let value; export let value;
export let onChange; export let onChange;
@@ -63,6 +76,7 @@
export let settings; export let settings;
export let referenceComponent; export let referenceComponent;
export let onReportCounts = undefined; export let onReportCounts = undefined;
export let allowAddTablesButton = false;
export const activator = createActivator('Designer', true); export const activator = createActivator('Designer', true);
@@ -423,6 +437,19 @@
arrange(true, false, rect ? { x: (rect.left + rect.right) / 2, y: (rect.top + rect.bottom) / 2 } : null); arrange(true, false, rect ? { x: (rect.left + rect.right) / 2, y: (rect.top + rect.bottom) / 2 } : null);
}; };
const handleAddAllTables = async () => {
const db = dbInfoExtended;
if (!db) return;
callChange(current => ({
tables: db.tables.map(table => ({
...table,
designerId: `${table.pureName}-${uuidv1()}`,
})),
references: [],
autoLayout: true,
}));
};
const handleChangeTableColor = table => { const handleChangeTableColor = table => {
showModal(ChooseColorModal, { showModal(ChooseColorModal, {
onChange: color => { onChange: color => {
@@ -966,6 +993,18 @@
filtered: _.compact(tables || []).length, filtered: _.compact(tables || []).length,
}); });
} }
export function areTablesSelected() {
return tables.some(x => x.isSelectedTable);
}
export function deleteSelectedTables() {
callChange(current => ({
...current,
tables: (current.tables || []).filter(x => !x.isSelectedTable),
}));
updateFromDbInfo();
}
</script> </script>
<div <div
@@ -977,6 +1016,12 @@
> >
{#if !(tables?.length > 0)} {#if !(tables?.length > 0)}
<div class="empty">Drag &amp; drop tables or views from left panel here</div> <div class="empty">Drag &amp; drop tables or views from left panel here</div>
{#if allowAddTablesButton}
<div class="addAllTables">
<FormStyledButton value="Add all tables" on:click={handleAddAllTables} />
</div>
{/if}
{/if} {/if}
<div <div
@@ -1091,6 +1136,14 @@
font-size: 20px; font-size: 20px;
position: absolute; position: absolute;
} }
.addAllTables {
margin: 50px;
margin-top: 100px;
font-size: 20px;
position: absolute;
z-index: 100;
}
.canvas { .canvas {
position: relative; position: relative;
} }

View File

@@ -23,4 +23,5 @@
referenceComponent={DiagramDesignerReference} referenceComponent={DiagramDesignerReference}
showColumnFilter={false} showColumnFilter={false}
{columnFilter} {columnFilter}
allowAddTablesButton
/> />

View File

@@ -31,6 +31,7 @@
export let padLeft = false; export let padLeft = false;
export let padRight = false; export let padRight = false;
export let style = null; export let style = null;
export let colorClass = null;
const iconNames = { const iconNames = {
'icon minus-box': 'mdi mdi-minus-box-outline', 'icon minus-box': 'mdi mdi-minus-box-outline',
@@ -143,6 +144,7 @@
'icon markdown': 'mdi mdi-application', 'icon markdown': 'mdi mdi-application',
'icon preview': 'mdi mdi-file-find', 'icon preview': 'mdi mdi-file-find',
'icon eye': 'mdi mdi-eye', 'icon eye': 'mdi mdi-eye',
'icon perspective': 'mdi mdi-eye',
'icon auditlog': 'mdi mdi-eye', 'icon auditlog': 'mdi mdi-eye',
'icon check-all': 'mdi mdi-check-all', 'icon check-all': 'mdi mdi-check-all',
'icon checkbox-blank': 'mdi mdi-checkbox-blank-outline', 'icon checkbox-blank': 'mdi mdi-checkbox-blank-outline',
@@ -235,6 +237,8 @@
'icon limit': 'mdi mdi-car-speed-limiter', 'icon limit': 'mdi mdi-car-speed-limiter',
'icon chart': 'mdi mdi-chart-bar', 'icon chart': 'mdi mdi-chart-bar',
'icon cloud-connection': 'mdi mdi-cloud-lock',
'icon diagram': 'mdi mdi-graph',
'img ok': 'mdi mdi-check-circle color-icon-green', 'img ok': 'mdi mdi-check-circle color-icon-green',
'img ok-inv': 'mdi mdi-check-circle color-icon-inv-green', 'img ok-inv': 'mdi mdi-check-circle color-icon-inv-green',
@@ -334,14 +338,11 @@
'img db-restore': 'mdi mdi-database-import color-icon-red', 'img db-restore': 'mdi mdi-database-import color-icon-red',
'img settings': 'mdi mdi-cog color-icon-blue', 'img settings': 'mdi mdi-cog color-icon-blue',
'img data-deploy': 'mdi mdi-database-settings color-icon-green', 'img data-deploy': 'mdi mdi-database-settings color-icon-green',
'img new-sql-file': 'mdi mdi-file color-icon-blue',
'img new-connection': 'mdi mdi-connection color-icon-yellow',
}; };
</script> </script>
<span <span
class={iconNames[icon] || icon} class={`${iconNames[icon] || icon} ${colorClass || ''}`}
{title} {title}
class:padLeft class:padLeft
class:padRight class:padRight

View File

@@ -7,88 +7,96 @@
import { closeCurrentModal } from './modalTools'; import { closeCurrentModal } from './modalTools';
export let multiTabIndex = undefined; export let multiTabIndex = undefined;
let NEW_ITEMS = [
{
icon: 'icon sql-file',
colorClass: 'color-icon-blue',
title: 'Query',
description: 'SQL query editor',
action: () => {
newQuery({ multiTabIndex });
},
},
{
icon: 'icon connection',
colorClass: 'color-icon-yellow',
title: 'Connection',
description: 'Database connection stored locally',
command: 'new.connection',
changeWidget: 'database',
},
{
icon: 'icon cloud-connection',
colorClass: 'color-icon-blue',
title: 'Connection on Cloud',
description: 'Database connection stored on DbGate Cloud',
command: 'new.connectionOnCloud',
changeWidget: 'cloud-private',
},
{
icon: 'icon query-design',
colorClass: 'color-icon-red',
title: 'Query Designer',
description: 'Design SQL queries visually',
command: 'new.queryDesign',
},
{
icon: 'icon diagram',
colorClass: 'color-icon-blue',
title: 'ER Diagram',
description: 'Visualize database structure',
command: 'new.diagram',
},
{
icon: 'icon perspective',
colorClass: 'color-icon-yellow',
title: 'Perspective',
description: 'Join complex data from multiple databases',
command: 'new.perspective',
},
{
icon: 'icon table',
colorClass: 'color-icon-blue',
title: 'Table',
description: 'Create table in the current database',
command: 'new.table',
},
{
icon: 'icon sql-generator',
colorClass: 'color-icon-green',
title: 'SQL Generator',
description: 'Generate SQL scripts for database objects',
command: 'sql.generator',
},
];
</script> </script>
<ModalBase simplefix {...$$restProps}> <ModalBase simplefix {...$$restProps}>
<div class="create-header">Create new</div> <div class="create-header">Create new</div>
<div class="wrapper"> <div class="wrapper">
<NewObjectButton {#each NEW_ITEMS as item}
icon="img new-sql-file" {@const enabled = item.command ? $commandsCustomized[item.command]?.enabled : true}
title="Query"
description="SQL query editor"
on:click={() => {
newQuery({ multiTabIndex });
closeCurrentModal();
}}
/>
{#if $commandsCustomized['new.connection']?.enabled}
<NewObjectButton <NewObjectButton
icon="img new-connection" icon={item.icon}
title="Connection" title={item.title}
description="Database connection stored locally" description={item.description}
{enabled}
colorClass={item.colorClass}
on:click={() => { on:click={() => {
$selectedWidget = 'database'; if (!enabled) return;
runCommand('new.connection'); if (item.action) {
item.action();
} else if (item.command) {
runCommand(item.command);
}
if (item.changeWidget) {
$selectedWidget = item.changeWidget;
}
closeCurrentModal(); closeCurrentModal();
}} }}
/> />
{/if} {/each}
{#if $commandsCustomized['new.connectionOnCloud']?.enabled}
<NewObjectButton
icon="img cloud-connection"
title="Connection on Cloud"
description="Database connection stored on DbGate Cloud"
on:click={() => {
$selectedWidget = 'cloud-private';
runCommand('new.connectionOnCloud');
closeCurrentModal();
}}
/>
{/if}
{#if $commandsCustomized['new.queryDesign']?.enabled}
<NewObjectButton
icon="img query-design"
title="Query Designer"
description="Design SQL queries visually"
on:click={() => {
runCommand('new.queryDesign');
closeCurrentModal();
}}
/>
{/if}
{#if $commandsCustomized['new.diagram']?.enabled}
<NewObjectButton
icon="img diagram"
title="ER Diagram"
description="Visualize database structure"
on:click={() => {
runCommand('new.diagram');
closeCurrentModal();
}}
/>
{/if}
{#if $commandsCustomized['new.perspective']?.enabled}
<NewObjectButton
icon="img perspective"
title="Perspective"
description="Join complex data from multiple databases"
on:click={() => {
runCommand('new.perspective');
closeCurrentModal();
}}
/>
{/if}
{#if $commandsCustomized['new.table']?.enabled}
<NewObjectButton
icon="img table"
title="Table"
description="Create table in the current database"
on:click={() => {
runCommand('new.table');
closeCurrentModal();
}}
/>
{/if}
</div> </div>
</ModalBase> </ModalBase>

View File

@@ -162,6 +162,7 @@
<ToolStripCommandButton command="diagram.export" /> <ToolStripCommandButton command="diagram.export" />
<ToolStripCommandButton command="diagram.undo" /> <ToolStripCommandButton command="diagram.undo" />
<ToolStripCommandButton command="diagram.redo" /> <ToolStripCommandButton command="diagram.redo" />
<ToolStripCommandButton command="diagram.deleteSelectedTables" />
{#if isProApp()} {#if isProApp()}
<ToolStripButton <ToolStripButton
icon="icon settings" icon="icon settings"