Skip to content

Commit

Permalink
Merge pull request #492 from NeurodataWithoutBorders/edit-list-order
Browse files Browse the repository at this point in the history
Edit list order + values
  • Loading branch information
CodyCBakerPhD authored Nov 1, 2023
2 parents 1c48784 + d1c19cd commit b2b80df
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 27 deletions.
1 change: 0 additions & 1 deletion src/renderer/src/stories/JSONSchemaInput.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,6 @@ export class JSONSchemaInput extends LitElement {
// onValidate = () => {}

updateData(value, forceValidation = false) {

if (this.value === value && !forceValidation) return false;

const { path: fullPath } = this;
Expand Down
120 changes: 106 additions & 14 deletions src/renderer/src/stories/List.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ export class List extends LitElement {
text-overflow: ellipsis
}
:host(:not([unordered])) li {
cursor: move;
}
:host([unordered]) ol {
list-style-type: none;
display: flex;
Expand All @@ -69,6 +73,15 @@ export class List extends LitElement {
align-items: center;
}
[contenteditable] {
cursor: text;
}
[data-idx]{
background: #f0f0f0;
height: 25px;
}
`;
}

Expand Down Expand Up @@ -121,6 +134,45 @@ export class List extends LitElement {

declare listStyles: any

allowDrop = (ev) => ev.preventDefault();


#dragged?: number
#placeholder = document.createElement('div')

drag = (ev, i) => this.#dragged = i

dragEnter = (ev, i) => {
ev.preventDefault();
if (this.#dragged !== i) {
const item = this.shadowRoot.getElementById(`item-${i}`)
this.#placeholder.setAttribute('data-idx', i)
item?.insertAdjacentElement('beforebegin', this.#placeholder)
} else {
this.#removePlaceholder()
}
}

dragExit = (ev, i) => {
ev.preventDefault();
if (this.#placeholder && i.toString() !== this.#placeholder.getAttribute('data-idx')){
this.#removePlaceholder()
}
}

drop = (ev, i) => {

ev.preventDefault();
const draggedIdx = this.#dragged as number
this.#dragged = undefined

const movedItem = this.items[draggedIdx]
this.items.splice(draggedIdx, 1)
this.items.splice(i, 0, movedItem)

this.items = [...this.items]
}


constructor(props: ListProps = {}) {
super();
Expand All @@ -139,21 +191,49 @@ export class List extends LitElement {
this.items = [...this.items, item]
}

#removePlaceholder = () => {
this.#placeholder.removeAttribute('data-idx')
this.#placeholder.remove()
}

#renderListItem = (item: ListItemType, i: number) => {
const { key, value, content = value } = item;
const li = document.createElement("li");
li.id = `item-${i}`;

if (!this.unordered) {
li.draggable = true;
li.ondragstart = (ev) => this.drag(ev, i);

li.ondragend = (ev) => {
if (this.#dragged !== undefined) {
const idx = this.#placeholder.getAttribute('data-idx')
if (idx !== null) this.drop(ev, parseInt(idx))
this.#removePlaceholder()
}
}

li.ondrop = (ev) => this.drop(ev, i);

li.ondragover = (ev) => this.dragEnter(ev, i);
// li.ondragenter = (ev) => this.dragEnter(ev, i);
li.ondragleave = (ev) => this.dragExit(ev, i);
}


const outerDiv = document.createElement('div')
const div = document.createElement('div')
li.append(outerDiv)
outerDiv.append(div)

const keyEl = document.createElement("span");
let editableElement = document.createElement("span");

let resolvedKey = key;
const originalValue = resolvedKey;

if (key) {
const isUnordered = !!key

if (isUnordered) {

this.setAttribute('unordered', '')

Expand All @@ -164,23 +244,28 @@ export class List extends LitElement {
resolvedKey = `${originalValue}_${i}`;
}

const keyEl = editableElement

keyEl.innerText = resolvedKey;
keyEl.contentEditable = true;
keyEl.style.cursor = "text";

const sepEl = document.createElement("span");
sepEl.innerHTML = " - ";
div.append(keyEl, sepEl);

this.object[resolvedKey] = value;
} else this.object[i] = value;
}

else {
this.object[i] = value;
}

if (typeof content === 'string') {
const valueEl = document.createElement("span");
const valueEl = editableElement = document.createElement("span");
valueEl.innerText = content;
div.appendChild(valueEl);
}
else li.append(content)
else li.append(editableElement = content)



Expand All @@ -197,23 +282,30 @@ export class List extends LitElement {

outerDiv.appendChild(button);

editableElement.contentEditable = true;

// Stop enter key from creating new line
keyEl.addEventListener("keydown", function (e) {
editableElement.addEventListener("keydown", (e) => {
if (e.keyCode === 13) {
keyEl.blur();
editableElement.blur();
return false;
}
});

const deleteListItem = () => this.delete(i);

keyEl.addEventListener("blur", () => {
const newKey = keyEl.innerText;
if (newKey === "") keyEl.innerText = resolvedKey; // Reset to original value
editableElement.addEventListener("blur", () => {
const newKey = editableElement.innerText;
if (newKey === "") this.delete(i); // Delete if empty
else {
delete this.object[resolvedKey];
resolvedKey = newKey;
this.object[resolvedKey] = value;
const oKey = isUnordered ? resolvedKey : i;
delete this.object[oKey];
this.object[newKey] = value;

if (!isUnordered) {
this.items[i].value = newKey
this.items = [...this.items]
}
}
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -194,8 +194,7 @@ export class GuidedPathExpansionPage extends Page {

if (!sesRef) delete globalResults[sub][ses]; // Delete removed sessions
else {

const globalSesRef = globalResults[sub][ses]
const globalSesRef = globalResults[sub][ses];

for (let name in globalSesRef.source_data) {
if (!sesRef.source_data[name]) delete globalSesRef.source_data[name]; // Delete removed interfaces
Expand Down Expand Up @@ -258,7 +257,10 @@ export class GuidedPathExpansionPage extends Page {
// altContent: this.altForm,
});

const structureState = (this.localState = merge(this.info.globalState.structure, { results: {}, keep_existing_data: true }));
const structureState = (this.localState = merge(this.info.globalState.structure, {
results: {},
keep_existing_data: true,
}));

const state = structureState.state;

Expand All @@ -280,12 +282,11 @@ export class GuidedPathExpansionPage extends Page {

// NOTE: These are custom coupled form inputs
onUpdate: (path, value) => {

this.unsavedUpdates = true
this.unsavedUpdates = true;

const parentPath = [...path]
const parentPath = [...path];
const name = parentPath.pop();

if (name === "base_directory") {
form.getInput([...parentPath, "base_directory"]).value = value; // Update value pre-emptively
const input = form.getInput([...parentPath, "format_string_path"]);
Expand All @@ -296,19 +297,17 @@ export class GuidedPathExpansionPage extends Page {
const value = parent[name];

if (fs) {
const baseDir = form.getInput([...parentPath, "base_directory"])
if (name === "format_string_path") {

const baseDir = form.getInput([...parentPath, "base_directory"]);
if (name === "format_string_path") {
if (value && !baseDir.value) {
return [
{
message: html`A base directory must be provided to locate your files.`,
type: "error",
},
]
];
}


const base_directory = [...parentPath, "base_directory"].reduce(
(acc, key) => acc[key],
this.form.resolved
Expand Down

0 comments on commit b2b80df

Please sign in to comment.