this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

edit values

alice f2789eca fe36b56e

+113 -19
+92 -19
index.ts
··· 16 16 // In part 4, user can add final statements for each core value (by card id) 17 17 finalStatements: { [cardId: number]: string }; 18 18 valueSet: 'limited' | 'all'; // Add state for current value set 19 + editingDescriptionCardId: number | null; // ID of card whose description is being edited 19 20 } 20 21 21 22 // Import the UndoManager from its own file ··· 58 59 if (!initialState.valueSet) { 59 60 initialState.valueSet = 'limited'; 60 61 } 61 - // Initialize nextCustomCardId based on saved custom cards 62 + // Ensure editing state is null initially 63 + initialState.editingDescriptionCardId = null; 62 64 const minId = Math.min(0, ...initialState.cards.filter(c => c.isCustom).map(c => c.id)); 63 65 this.nextCustomCardId = minId - 1; 64 66 } catch { ··· 85 87 name: definition.name, // Use name from definition 86 88 column: "unassigned", 87 89 order: index, 90 + description: undefined, // Ensure built-in cards start with no override 91 + isCustom: false 88 92 })); 89 93 return { 90 94 currentPart: "part1", 91 95 cards: sampleCards, 92 96 finalStatements: {}, 93 97 valueSet: valueSet, // Store the set used 98 + editingDescriptionCardId: null, // Start with no editing 94 99 }; 95 100 } 96 101 ··· 181 186 this.hideAddValueForm(); 182 187 } 183 188 189 + // --- Description Edit Logic --- 190 + private startEditingDescription(cardId: number) { 191 + const newState = this.undoManager.getState(); 192 + newState.editingDescriptionCardId = cardId; 193 + this.updateState(newState); // Re-render to show the textarea 194 + } 195 + 196 + private saveDescriptionEdit(cardId: number, newDescription: string) { 197 + const newState = this.undoManager.getState(); 198 + const cardToUpdate = newState.cards.find(c => c.id === cardId); 199 + if (cardToUpdate) { 200 + cardToUpdate.description = newDescription.trim(); // Save trimmed description 201 + } 202 + newState.editingDescriptionCardId = null; // Stop editing 203 + this.updateState(newState); 204 + } 205 + 206 + private cancelDescriptionEdit() { 207 + const newState = this.undoManager.getState(); 208 + newState.editingDescriptionCardId = null; // Just stop editing, don't save 209 + this.updateState(newState); 210 + } 211 + 184 212 // Bind event listeners for UI interactions. 185 213 private bindEventListeners() { 186 214 const appInstance = this; // Capture the App instance ··· 361 389 } 362 390 } 363 391 364 - // Creates a draggable card element, now including the description. 392 + // Creates a draggable card element, handles description editing UI. 365 393 private createCardElement(card: ValueCard): HTMLElement { 366 394 const cardElem = document.createElement("div"); 367 395 cardElem.className = "card"; 368 396 cardElem.draggable = true; 369 397 cardElem.dataset.cardId = card.id.toString(); 370 398 371 - // Create elements for name and description 372 399 const nameElem = document.createElement("span"); 373 400 nameElem.className = "card-name"; 374 401 nameElem.textContent = card.name; 402 + cardElem.appendChild(nameElem); 375 403 376 - const descriptionElem = document.createElement("span"); 377 - descriptionElem.className = "card-description"; 378 - // Prioritize card.description, fall back to map for built-in values 379 - descriptionElem.textContent = card.description || valueDefinitionsMap.get(card.name) || ""; 404 + // Container for description/edit area 405 + const descriptionContainer = document.createElement("div"); 406 + descriptionContainer.className = "card-description-container"; 407 + 408 + if (this.state.editingDescriptionCardId === card.id) { 409 + // RENDER EDIT TEXTAREA 410 + const textarea = document.createElement('textarea'); 411 + textarea.className = 'card-description-edit'; 412 + textarea.value = card.description || valueDefinitionsMap.get(card.name) || ""; 413 + textarea.rows = 3; 414 + 415 + textarea.addEventListener('blur', () => { 416 + this.saveDescriptionEdit(card.id, textarea.value); 417 + }); 418 + 419 + textarea.addEventListener('keydown', (e) => { 420 + if (e.key === 'Enter' && !e.shiftKey) { 421 + e.preventDefault(); // Prevent newline 422 + this.saveDescriptionEdit(card.id, textarea.value); 423 + } else if (e.key === 'Escape') { 424 + this.cancelDescriptionEdit(); 425 + } 426 + }); 427 + 428 + descriptionContainer.appendChild(textarea); 429 + // Auto-focus the textarea after it's rendered 430 + setTimeout(() => textarea.focus(), 0); 380 431 381 - cardElem.appendChild(nameElem); 382 - cardElem.appendChild(descriptionElem); 432 + } else { 433 + // RENDER DESCRIPTION TEXT (Clickable) 434 + const descriptionElem = document.createElement("span"); 435 + descriptionElem.className = "card-description clickable"; // Add clickable class 436 + descriptionElem.textContent = card.description || valueDefinitionsMap.get(card.name) || "(Click to add description)"; 437 + descriptionElem.title = "Click to edit description"; // Tooltip 438 + 439 + descriptionElem.addEventListener('click', (e) => { 440 + e.stopPropagation(); // Prevent card drag start if clicking text 441 + this.startEditingDescription(card.id); 442 + }); 443 + descriptionContainer.appendChild(descriptionElem); 444 + } 445 + 446 + cardElem.appendChild(descriptionContainer); 383 447 384 448 cardElem.addEventListener("dragstart", (e) => { 385 - e.dataTransfer?.setData("text/plain", card.id.toString()); 449 + // Only allow drag if not editing description 450 + if (this.state.editingDescriptionCardId === null) { 451 + e.dataTransfer?.setData("text/plain", card.id.toString()); 452 + } else { 453 + e.preventDefault(); // Prevent drag while editing 454 + } 386 455 }); 456 + 387 457 return cardElem; 388 458 } 389 459 ··· 556 626 title.textContent = category.title; 557 627 section.appendChild(title); 558 628 559 - const values = this.state.cards 560 - .filter(c => c.column === category.column) 561 - .map(c => c.name); // Keep getting just the names for this list 629 + // Get the actual card objects, not just names 630 + const cardsInCategory = this.state.cards 631 + .filter(c => c.column === category.column); 632 + // Sort them alphabetically by name for consistent display 633 + cardsInCategory.sort((a, b) => a.name.localeCompare(b.name)); 562 634 563 - if (values.length > 0) { 635 + if (cardsInCategory.length > 0) { 564 636 const list = document.createElement("ul"); 565 - values.forEach(value => { 637 + // Iterate over the card objects 638 + cardsInCategory.forEach(card => { 566 639 const li = document.createElement("li"); 567 - // Create spans for name and description 568 640 const nameSpan = document.createElement('span'); 569 641 nameSpan.className = 'review-value-name'; 570 - nameSpan.textContent = value; 571 - 642 + nameSpan.textContent = card.name; // Use name from card object 643 + 572 644 const descSpan = document.createElement('span'); 573 645 descSpan.className = 'review-value-description'; 574 - descSpan.textContent = valueDefinitionsMap.get(value) || "(Description not found)"; 646 + // Prioritize card.description, fall back to map 647 + descSpan.textContent = card.description || valueDefinitionsMap.get(card.name) || "(Description missing)"; 575 648 576 649 li.appendChild(nameSpan); 577 650 li.appendChild(descSpan);
+21
styles.css
··· 77 77 padding-right: 4px; 78 78 } 79 79 80 + /* Make description clickable */ 81 + .card-description.clickable { 82 + cursor: pointer; 83 + transition: background-color 0.2s ease; 84 + } 85 + .card-description.clickable:hover { 86 + background-color: #f0f0f0; /* Subtle hover effect */ 87 + } 88 + 89 + /* Textarea for editing description */ 90 + .card-description-edit { 91 + width: 90%; /* Adjust as needed */ 92 + margin: 4px auto; /* Center and add vertical space */ 93 + font-size: 0.85em; 94 + font-family: inherit; 95 + border: 1px solid #aaa; 96 + border-radius: 3px; 97 + resize: vertical; /* Allow vertical resize */ 98 + box-sizing: border-box; 99 + } 100 + 80 101 .values-grid { 81 102 display: grid; 82 103 grid-template-columns: repeat(2, 1fr);