Skip to content

Commit

Permalink
added dnd run reordering
Browse files Browse the repository at this point in the history
  • Loading branch information
justintucker1 committed Oct 29, 2024
1 parent 015df44 commit 281cc4d
Show file tree
Hide file tree
Showing 2 changed files with 145 additions and 21 deletions.
81 changes: 60 additions & 21 deletions webviews/src/views/RokuAutomationView/AutoRunsEditor.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<script>
import { Trash, Copy, TriangleDown } from 'svelte-codicons';
import { dropzone, draggable } from './dnd';
export let runs;
export let selectedRun;
Expand Down Expand Up @@ -63,17 +64,16 @@
const selectRun = (e) => {
const run = getRunFromEvent(e);
selectedRun = run;
console.log(`selectRun row ${run}`);
};
const copyRun = (e) => {
const run = getRunFromEvent(e);
selectedRun = run;
console.log(`copyRun row ${run}`);
showRunNameDialog(`Copy of ${run}`)
.then((runName) => {
const steps = runs.find((r) => r.name === selectedRun)?.steps ?? [];
const steps =
runs.find((r) => r.name === selectedRun)?.steps ?? [];
selectedRun = runName;
runs = [
{ name: runName, steps: structuredClone(steps) },
Expand Down Expand Up @@ -102,41 +102,61 @@
return;
}
e.stopPropagation();
confirmDialog.removeEventListener('click', confirmDialogCallback);
confirmDialog.removeEventListener(
'click',
confirmDialogCallback
);
confirmDialog.close();
})
);
confirmDialog.showModal();
}).then(() => {
runs = runs.filter((r) => r.name !== run);
}).catch(() => {
// do nothing
});
})
.then(() => {
runs = runs.filter((r) => r.name !== run);
})
.catch(() => {
// do nothing
});
};
const moveRun = (runName, index) => {
let currIndex = runs.findIndex((r) => r.name === runName);
if (currIndex < 0 || index < 0 || index > runs.length || currIndex === index) return;
const runToMove = runs[currIndex];
const newRunList = [
...runs.slice(0, index),
runToMove,
...runs.slice(index)
];
newRunList.splice(currIndex < index ? currIndex : ++currIndex, 1);
runs = newRunList;
};
const addNewRun = () => {
showRunNameDialog()
.then((runName) => {
console.log(`======== addNewRun function, name=${runName}`);
selectedRun = runName;
runs = [
{ name: runName, steps: [] },
...runs.filter((r) => r.name !== runName)
];
})
.catch((e) => {
console.log(`======== addNewRun function, do nothing`);
// do nothing
});
};
const showRunNameDialog = (defaultRunName = null) => {
runNameDialogValue = defaultRunName ?? '';
setTimeout(() => { runNameInput.setSelectionRange(0, runNameInput.value.length); }); // select text
setTimeout(() => {
runNameInput.setSelectionRange(0, runNameInput.value.length);
}); // select text
return new Promise((resolve, reject) => {
let cancelCallback, clickCallback, keyupCallback;
const closeDialog = (e, runName = null) => {
if (runName === '' || runs.find((r) => r.name === runName)) return false; // name already exists
if (runName === '' || runs.find((r) => r.name === runName))
return false; // name already exists
e.stopPropagation();
runNameDialog.close();
runNameDialog.removeEventListener('cancel', cancelCallback);
Expand All @@ -158,7 +178,10 @@
runNameDialog.addEventListener(
'keyup',
(keyupCallback = (e) => {
if (e.key === 'Enter' && closeDialog(e, runNameDialogValue)) {
if (
e.key === 'Enter' &&
closeDialog(e, runNameDialogValue)
) {
resolve(runNameDialogValue);
} else {
return;
Expand Down Expand Up @@ -200,14 +223,13 @@
}
#content-container {
background-color: var(--vscode-editor-background);
position: absolute;
z-index: 1;
width: calc(100% - 15px);
height: calc(100% - 65px);
display: flex;
color: var(--vscode-editor-foreground);
background: var(--vscode-editor-background);
background-color: var(--vscode-editor-background);
padding: 5px;
}
Expand Down Expand Up @@ -285,6 +307,11 @@
#RunNameDialog {
width: 100%;
}
.run-row > *:global(.droppable) {
outline: 0.2em dashed red;
outline-offset: -2px;
}
</style>
<div id="editor">
Expand All @@ -297,23 +324,36 @@
</div>
{#if showContent}
<div id="content-container">
<div id="run-list">
<div
id="run-list"
use:dropzone={{
onDropzone(runName) {
moveRun(runName, runs.length);
}
}}>
<table
width="100%"
cellspacing="0"
style="margin-bottom: auto;"
bind:this={runTable}>
{#each runs as run}
{#each runs as run, index}
<tr>
<td colspan="5">
<vscode-divider />
</td>
</tr>
<tr
class="run-row"
use:dropzone={{
onDropzone(runName) {
moveRun(runName, index);
}
}}
use:draggable={run.name}
on:click={selectRun}
title={run.name}
id={run.name === selectedRun ? 'selected-tr' : ''}>
<td>
<td class="run-row-name">
<span id="run-name">
{run.name}
</span>
Expand Down Expand Up @@ -357,8 +397,7 @@
bind:this={runNameInput}
placeholder="Enter run name"
style="width: 100%;"
bind:value={runNameDialogValue}
/>
bind:value={runNameDialogValue} />
</div>
<div class="button-group horizontal-container">
<vscode-button id="OK" on:click={this.click}>OK</vscode-button>
Expand Down
85 changes: 85 additions & 0 deletions webviews/src/views/RokuAutomationView/dnd.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/* eslint-disable object-shorthand */
/* eslint-disable curly */
export function draggable(node, data) {
let state = data;

node.draggable = true;
node.style.cursor = 'grab';

function handleDragstart(e) {
if (!e.dataTransfer) return;
e.dataTransfer.setData('text/plain', state);
}

node.addEventListener('dragstart', handleDragstart);

return {
update(data) {
state = data;
},

destroy() {
node.removeEventListener('dragstart', handleDragstart);
}
};
}

export function dropzone(node, options) {
let state = {
dropEffect: 'move',
dragoverClass: 'droppable',
...options
};

function handleDragenter(e) {
console.log(`handleDragenter: ${e.target}`);
if (!(e.target instanceof HTMLElement)) return;
console.log(`dragoverClass: ${state.dragoverClass}`);
e.target.classList.add(state.dragoverClass);
}

function handleDragleave(e) {
console.log(`handleDragleave: ${e.target}`);
if (!(e.target instanceof HTMLElement)) return;
e.target.classList.remove(state.dragoverClass);
}

function handleDragover(e) {
console.log(`handleDragover: ${e.target}`);
e.preventDefault();
if (!e.dataTransfer) return;
e.dataTransfer.dropEffect = state.dropEffect;
}

function handleDrop(e) {
e.preventDefault();
if (!e.dataTransfer) return;
const data = e.dataTransfer.getData('text/plain');
if (!(e.target instanceof HTMLElement)) return;
e.target.classList.remove(state.dragoverClass);
state.onDropzone(data, e);
e.stopPropagation();
}

node.addEventListener('dragenter', handleDragenter);
node.addEventListener('dragleave', handleDragleave);
node.addEventListener('dragover', handleDragover);
node.addEventListener('drop', handleDrop);

return {
update(options) {
state = {
dropEffect: 'move',
dragoverClass: 'droppable',
...options
};
},

destroy() {
node.removeEventListener('dragenter', handleDragenter);
node.removeEventListener('dragleave', handleDragleave);
node.removeEventListener('dragover', handleDragover);
node.removeEventListener('drop', handleDrop);
}
};
}

0 comments on commit 281cc4d

Please sign in to comment.