Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Edit list order + values #492

Merged
merged 7 commits into from
Nov 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading