copy column names #1119

This commit is contained in:
SPRINX0\prochazka
2025-06-11 10:34:22 +02:00
parent 95f5417761
commit 2ef7c63047
4 changed files with 91 additions and 2 deletions

View File

@@ -14,10 +14,16 @@
export let clickable = false; export let clickable = false;
export let onAddNew = null; export let onAddNew = null;
export let displayNameFieldName = null; export let displayNameFieldName = null;
export let multipleItemsActions = null;
export let filters = writable({}); export let filters = writable({});
let collapsed = false; let collapsed = false;
let activeMultipleSelection;
function handleChangeMultipleSelection(list) {
activeMultipleSelection = list;
}
</script> </script>
{#if collection?.length > 0 || showIfEmpty || emptyMessage} {#if collection?.length > 0 || showIfEmpty || emptyMessage}
@@ -35,6 +41,16 @@
{#if onAddNew} {#if onAddNew}
<Link onClick={onAddNew}><FontIcon icon="icon add" /> Add new</Link> <Link onClick={onAddNew}><FontIcon icon="icon add" /> Add new</Link>
{/if} {/if}
{#if multipleItemsActions && activeMultipleSelection && activeMultipleSelection?.length > 0}
{#each multipleItemsActions as item}
<span class="ml-2">
<Link onClick={() => item.onClick(activeMultipleSelection)}>
<FontIcon icon={item.icon} />
{item.text} ({activeMultipleSelection.length})
</Link>
</span>
{/each}
{/if}
</div> </div>
{#if (collection?.length || 0) == 0 && emptyMessage} {#if (collection?.length || 0) == 0 && emptyMessage}
<div class="body"> <div class="body">
@@ -45,6 +61,7 @@
<div class="body"> <div class="body">
<TableControl <TableControl
rows={collection || []} rows={collection || []}
allowMultiSelect={!!multipleItemsActions}
columns={_.compact([ columns={_.compact([
!hideDisplayName && { !hideDisplayName && {
fieldName: displayNameFieldName || 'displayName', fieldName: displayNameFieldName || 'displayName',
@@ -58,6 +75,7 @@
{clickable} {clickable}
{filters} {filters}
on:clickrow on:clickrow
onChangeMultipleSelection={handleChangeMultipleSelection}
> >
<svelte:fragment slot="-1" let:row let:col> <svelte:fragment slot="-1" let:row let:col>
<slot name="name" {row} {col} /> <slot name="name" {row} {col} />

View File

@@ -39,6 +39,9 @@
export let disableFocusOutline = false; export let disableFocusOutline = false;
export let emptyMessage = null; export let emptyMessage = null;
export let noCellPadding = false; export let noCellPadding = false;
export let allowMultiSelect = false;
export let selectedIndexes = [];
export let onChangeMultipleSelection = null;
export let domTable = undefined; export let domTable = undefined;
export let stickyHeader = false; export let stickyHeader = false;
@@ -53,6 +56,9 @@
const dispatch = createEventDispatcher(); const dispatch = createEventDispatcher();
let dragStartIndex = null;
let dragCurrentIndex = null;
$: columnList = _.compact(_.flatten(columns)); $: columnList = _.compact(_.flatten(columns));
onMount(() => { onMount(() => {
@@ -174,6 +180,15 @@
$: checkableFlatRowsShown = flatRowsShown.filter(x => itemSupportsCheckbox(x)); $: checkableFlatRowsShown = flatRowsShown.filter(x => itemSupportsCheckbox(x));
// $: groupedRows = computeGroupedRows(sortedRows); // $: groupedRows = computeGroupedRows(sortedRows);
$: if (onChangeMultipleSelection && flatRowsShown) {
onChangeMultipleSelection(selectedIndexes.map(index => flatRowsShown[index]));
}
$: if (flatRowsShown) {
// reset selection on items changed
selectedIndexes = [];
}
</script> </script>
<table <table
@@ -270,8 +285,9 @@
{#each gitem.rows as row} {#each gitem.rows as row}
{@const index = _.indexOf(flatRowsShown, row)} {@const index = _.indexOf(flatRowsShown, row)}
<tr <tr
class:selected={selectable && class:selected={(selectable &&
(selectionMode == 'index' ? selectedIndex == index : selectedKey == extractTableItemKey(row))} (selectionMode == 'index' ? selectedIndex == index : selectedKey == extractTableItemKey(row))) ||
(allowMultiSelect && selectedIndexes.includes(index))}
class:clickable class:clickable
bind:this={domRows[index]} bind:this={domRows[index]}
on:click={() => { on:click={() => {
@@ -287,6 +303,30 @@
dispatch('clickrow', row); dispatch('clickrow', row);
} }
}} }}
on:mousedown={event => {
if (allowMultiSelect && !event.ctrlKey && !event.metaKey) {
selectedIndexes = [];
dragStartIndex = index;
}
}}
on:mousemove={() => {
if (dragStartIndex != null && allowMultiSelect) {
dragCurrentIndex = index;
if (dragCurrentIndex != dragStartIndex || selectedIndexes.length > 0) {
if (dragCurrentIndex < dragStartIndex) {
selectedIndexes = _.range(dragCurrentIndex, dragStartIndex + 1);
} else {
selectedIndexes = _.range(dragStartIndex, dragCurrentIndex + 1);
}
} else if (selectedIndexes.length > 0) {
selectedIndexes = [dragCurrentIndex];
}
}
}}
on:mouseup={event => {
dragCurrentIndex = null;
dragStartIndex = null;
}}
data-testid={`TableControl_row_${index}`} data-testid={`TableControl_row_${index}`}
> >
{#if checkedKeys} {#if checkedKeys}

View File

@@ -159,6 +159,7 @@
'icon ai': 'mdi mdi-head-lightbulb', 'icon ai': 'mdi mdi-head-lightbulb',
'icon wait': 'mdi mdi-timer-sand', 'icon wait': 'mdi mdi-timer-sand',
'icon more': 'mdi mdi-more', 'icon more': 'mdi mdi-more',
'icon copy': 'mdi mdi-content-copy',
'icon run': 'mdi mdi-play', 'icon run': 'mdi mdi-play',
'icon chevron-down': 'mdi mdi-chevron-down', 'icon chevron-down': 'mdi mdi-chevron-down',

View File

@@ -193,6 +193,36 @@
on:clickrow={e => showModal(ColumnEditorModal, { columnInfo: e.detail, tableInfo, setTableInfo, driver })} on:clickrow={e => showModal(ColumnEditorModal, { columnInfo: e.detail, tableInfo, setTableInfo, driver })}
onAddNew={isWritable ? addColumn : null} onAddNew={isWritable ? addColumn : null}
displayNameFieldName="columnName" displayNameFieldName="columnName"
multipleItemsActions={[
{
text: 'Remove',
icon: 'icon delete',
onClick: selected => {
setTableInfo(tbl => {
const newColumns = tbl.columns.filter(x => !selected.find(y => y.columnName === x.columnName));
return { ...tbl, columns: newColumns };
});
},
},
{
text: 'Copy names',
icon: 'icon copy',
onClick: selected => {
const names = selected.map(x => x.columnName).join('\n');
navigator.clipboard.writeText(names);
},
},
{
text: 'Copy definitions',
icon: 'icon copy',
onClick: selected => {
const names = selected
.map(x => `${x.columnName} ${x.dataType}${x.notNull ? ' NOT NULL' : ''}`)
.join(',\n');
navigator.clipboard.writeText(names);
},
},
]}
columns={[ columns={[
!driver?.dialect?.specificNullabilityImplementation && { !driver?.dialect?.specificNullabilityImplementation && {
fieldName: 'notNull', fieldName: 'notNull',