@lv-x-software-house/x_view 1.2.2-dev.14 → 1.2.2-dev.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +116 -21
- package/dist/index.mjs +118 -23
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3216,8 +3216,8 @@ function CustomPropertyDisplay({
|
|
|
3216
3216
|
const availableOptions = [
|
|
3217
3217
|
{ value: "links", label: "Links", unique: true },
|
|
3218
3218
|
{ value: "images", label: "Images", unique: true },
|
|
3219
|
-
{ value: "documents", label: "Documents", unique: true },
|
|
3220
3219
|
{ value: "date", label: "Data", unique: true },
|
|
3220
|
+
{ value: "documents", label: "Documents", unique: true },
|
|
3221
3221
|
{ value: "text", label: "Texto", unique: false },
|
|
3222
3222
|
{ value: "number", label: "N\xFAmero", unique: false },
|
|
3223
3223
|
{ value: "list", label: "Lista", unique: false }
|
|
@@ -4080,6 +4080,24 @@ function DescriptionEditModal({
|
|
|
4080
4080
|
},
|
|
4081
4081
|
/* @__PURE__ */ import_react6.default.createElement(import_fi4.FiList, { size: 12 }),
|
|
4082
4082
|
" Lista"
|
|
4083
|
+
), /* @__PURE__ */ import_react6.default.createElement(
|
|
4084
|
+
"button",
|
|
4085
|
+
{
|
|
4086
|
+
onClick: () => insertAtCursor("1. "),
|
|
4087
|
+
className: "flex items-center gap-1 px-3 py-1.5 rounded bg-slate-800 hover:bg-slate-700 border border-white/10 text-xs font-medium transition-colors whitespace-nowrap",
|
|
4088
|
+
title: "Lista Numerada"
|
|
4089
|
+
},
|
|
4090
|
+
/* @__PURE__ */ import_react6.default.createElement("span", { className: "text-[10px] font-bold" }, "1."),
|
|
4091
|
+
" Numerada"
|
|
4092
|
+
), /* @__PURE__ */ import_react6.default.createElement(
|
|
4093
|
+
"button",
|
|
4094
|
+
{
|
|
4095
|
+
onClick: () => insertAtCursor("- [ ] "),
|
|
4096
|
+
className: "flex items-center gap-1 px-3 py-1.5 rounded bg-slate-800 hover:bg-slate-700 border border-white/10 text-xs font-medium transition-colors whitespace-nowrap",
|
|
4097
|
+
title: "Checklist (Checkbox)"
|
|
4098
|
+
},
|
|
4099
|
+
/* @__PURE__ */ import_react6.default.createElement(import_fi4.FiCheckSquare, { size: 12 }),
|
|
4100
|
+
" Checklist"
|
|
4083
4101
|
), /* @__PURE__ */ import_react6.default.createElement(
|
|
4084
4102
|
"button",
|
|
4085
4103
|
{
|
|
@@ -4386,7 +4404,7 @@ var renderTextWithMentions = (text, availableNodes, onMentionClick, activeMentio
|
|
|
4386
4404
|
);
|
|
4387
4405
|
});
|
|
4388
4406
|
};
|
|
4389
|
-
var formatLineContent2 = (line, availableNodes, onMentionClick, activeMentionIndex, mentionCounterRef, setRef, onImageClick) => {
|
|
4407
|
+
var formatLineContent2 = (line, availableNodes, onMentionClick, activeMentionIndex, mentionCounterRef, setRef, onImageClick, onToggleCheckbox, globalCheckboxCounterRef) => {
|
|
4390
4408
|
const trimmedLine = line.replace(/\r$/, "");
|
|
4391
4409
|
const processContent = (content) => renderTextWithMentions(content, availableNodes, onMentionClick, activeMentionIndex, mentionCounterRef, setRef, onImageClick);
|
|
4392
4410
|
if (line.startsWith("# ")) {
|
|
@@ -4397,9 +4415,46 @@ var formatLineContent2 = (line, availableNodes, onMentionClick, activeMentionInd
|
|
|
4397
4415
|
const content = line.replace("## ", "");
|
|
4398
4416
|
return /* @__PURE__ */ import_react7.default.createElement("span", { className: "text-sm sm:text-base font-semibold text-indigo-200 leading-tight break-words" }, processContent(content));
|
|
4399
4417
|
}
|
|
4418
|
+
const checkboxMatch = trimmedLine.match(/^(\s*)- \[([ xX])\]\s+(.*)/);
|
|
4419
|
+
if (checkboxMatch) {
|
|
4420
|
+
const [_, space, state, content] = checkboxMatch;
|
|
4421
|
+
const isChecked = state.toLowerCase() === "x";
|
|
4422
|
+
const currentIdx = globalCheckboxCounterRef.current;
|
|
4423
|
+
globalCheckboxCounterRef.current += 1;
|
|
4424
|
+
return /* @__PURE__ */ import_react7.default.createElement("span", { className: "flex items-start gap-2.5 my-1 break-words ml-1 group/checkbox" }, /* @__PURE__ */ import_react7.default.createElement(
|
|
4425
|
+
"div",
|
|
4426
|
+
{
|
|
4427
|
+
onClick: (e) => {
|
|
4428
|
+
e.stopPropagation();
|
|
4429
|
+
if (onToggleCheckbox) onToggleCheckbox(currentIdx);
|
|
4430
|
+
},
|
|
4431
|
+
className: `mt-1 cursor-pointer w-4 h-4 rounded border flex-shrink-0 flex items-center justify-center transition-all duration-200
|
|
4432
|
+
${isChecked ? "bg-indigo-500 border-indigo-500 shadow-[0_0_8px_rgba(99,102,241,0.4)]" : "border-slate-500 bg-slate-900/50 hover:border-slate-400 group-hover/checkbox:border-slate-400"}
|
|
4433
|
+
`
|
|
4434
|
+
},
|
|
4435
|
+
isChecked && /* @__PURE__ */ import_react7.default.createElement(import_fi5.FiCheck, { size: 12, className: "text-white" })
|
|
4436
|
+
), /* @__PURE__ */ import_react7.default.createElement(
|
|
4437
|
+
"span",
|
|
4438
|
+
{
|
|
4439
|
+
className: `transition-all duration-200 cursor-pointer pt-[1px]
|
|
4440
|
+
${isChecked ? "line-through text-slate-500" : "text-slate-200 group-hover/checkbox:text-white"}
|
|
4441
|
+
`,
|
|
4442
|
+
onClick: (e) => {
|
|
4443
|
+
e.stopPropagation();
|
|
4444
|
+
if (onToggleCheckbox) onToggleCheckbox(currentIdx);
|
|
4445
|
+
}
|
|
4446
|
+
},
|
|
4447
|
+
processContent(content)
|
|
4448
|
+
));
|
|
4449
|
+
}
|
|
4450
|
+
const numberMatch = trimmedLine.match(/^(\s*)(\d+\.)\s+(.*)/);
|
|
4451
|
+
if (numberMatch) {
|
|
4452
|
+
const [_, space, numberStr, content] = numberMatch;
|
|
4453
|
+
return /* @__PURE__ */ import_react7.default.createElement("span", { className: "flex items-start gap-2 my-0.5 break-words ml-1" }, /* @__PURE__ */ import_react7.default.createElement("span", { className: "text-indigo-400 font-mono font-bold text-xs mt-[3px] shrink-0" }, numberStr), /* @__PURE__ */ import_react7.default.createElement("span", { className: "text-slate-200" }, processContent(content)));
|
|
4454
|
+
}
|
|
4400
4455
|
if (trimmedLine.trim().startsWith("- ") || trimmedLine.trim().startsWith("* ")) {
|
|
4401
4456
|
const content = trimmedLine.trim().substring(2);
|
|
4402
|
-
return /* @__PURE__ */ import_react7.default.createElement("span", { className: "
|
|
4457
|
+
return /* @__PURE__ */ import_react7.default.createElement("span", { className: "flex items-start gap-2 my-0.5 break-words ml-1 text-slate-200" }, /* @__PURE__ */ import_react7.default.createElement("span", { className: "text-indigo-400 font-bold shrink-0 mt-[2px] text-xs" }, "\u2022"), /* @__PURE__ */ import_react7.default.createElement("span", null, processContent(content)));
|
|
4403
4458
|
}
|
|
4404
4459
|
return /* @__PURE__ */ import_react7.default.createElement("span", { className: "break-words" }, processContent(line));
|
|
4405
4460
|
};
|
|
@@ -4411,14 +4466,31 @@ function DescriptionDisplay({
|
|
|
4411
4466
|
onOpenReference,
|
|
4412
4467
|
onMentionClick,
|
|
4413
4468
|
onImageClick,
|
|
4414
|
-
// <--- NOVA PROP RECEBIDA
|
|
4415
4469
|
onSectionChange,
|
|
4416
4470
|
onBranchNav,
|
|
4417
4471
|
onHighlightNode,
|
|
4418
4472
|
initialSectionId,
|
|
4419
|
-
currentBranchDirection = null
|
|
4473
|
+
currentBranchDirection = null,
|
|
4474
|
+
onSaveDescription
|
|
4420
4475
|
}) {
|
|
4421
|
-
const
|
|
4476
|
+
const [localDescription, setLocalDescription] = (0, import_react7.useState)(description || "");
|
|
4477
|
+
(0, import_react7.useEffect)(() => {
|
|
4478
|
+
setLocalDescription(description || "");
|
|
4479
|
+
}, [description]);
|
|
4480
|
+
const sections = (0, import_react7.useMemo)(() => parseDescriptionSections(localDescription, savedSections), [localDescription, savedSections]);
|
|
4481
|
+
const globalCheckboxCounterRef = (0, import_react7.useRef)(0);
|
|
4482
|
+
const handleToggleCheckbox = (targetIndex) => {
|
|
4483
|
+
let currentIndex = 0;
|
|
4484
|
+
const newDesc = localDescription.replace(/^(\s*)- \[([ xX])\]/gm, (match, space, state) => {
|
|
4485
|
+
if (currentIndex === targetIndex) {
|
|
4486
|
+
currentIndex++;
|
|
4487
|
+
return state === " " ? `${space}- [x]` : `${space}- [ ]`;
|
|
4488
|
+
}
|
|
4489
|
+
currentIndex++;
|
|
4490
|
+
return match;
|
|
4491
|
+
});
|
|
4492
|
+
setLocalDescription(newDesc);
|
|
4493
|
+
};
|
|
4422
4494
|
const flatNavigation = (0, import_react7.useMemo)(() => {
|
|
4423
4495
|
const navItems = [];
|
|
4424
4496
|
sections.forEach((section, sIdx) => {
|
|
@@ -4559,26 +4631,27 @@ function DescriptionDisplay({
|
|
|
4559
4631
|
}
|
|
4560
4632
|
const lines = part.replace(/\n$/, "").split("\n");
|
|
4561
4633
|
return /* @__PURE__ */ import_react7.default.createElement(import_react7.default.Fragment, { key: `text-${parentIndex}-${partIndex}` }, lines.map((line, lineIndex) => {
|
|
4562
|
-
const isLastLine = lineIndex === lines.length - 1;
|
|
4563
4634
|
const isEmptyLine = line.trim() === "";
|
|
4564
4635
|
if (isEmptyLine) {
|
|
4565
4636
|
return /* @__PURE__ */ import_react7.default.createElement(import_react7.default.Fragment, { key: `${parentIndex}-${partIndex}-${lineIndex}` }, /* @__PURE__ */ import_react7.default.createElement("br", null));
|
|
4566
4637
|
}
|
|
4567
4638
|
return /* @__PURE__ */ import_react7.default.createElement(import_react7.default.Fragment, { key: `${parentIndex}-${partIndex}-${lineIndex}` }, /* @__PURE__ */ import_react7.default.createElement(
|
|
4568
|
-
"
|
|
4639
|
+
"div",
|
|
4569
4640
|
{
|
|
4570
4641
|
ref: isActiveSection && activeMentionIndex === -1 && partIndex === 0 && lineIndex === 0 ? setRef : null,
|
|
4571
|
-
onClick: () => {
|
|
4572
|
-
|
|
4573
|
-
|
|
4642
|
+
onClick: (e) => {
|
|
4643
|
+
if (e.target.type !== "checkbox") {
|
|
4644
|
+
const idx = flatNavigation.findIndex((item) => item.type === "section" && item.sectionIndex === parentIndex);
|
|
4645
|
+
if (idx !== -1) setCurrentStepIndex(idx);
|
|
4646
|
+
}
|
|
4574
4647
|
},
|
|
4575
4648
|
className: `
|
|
4576
|
-
transition-colors duration-200 cursor-pointer rounded-md px-1 py-0.5 -mx-1 box-decoration-clone
|
|
4577
|
-
${isActiveSection ? "bg-indigo-500/
|
|
4649
|
+
transition-colors duration-200 cursor-pointer rounded-md px-1 py-0.5 -mx-1 box-decoration-clone inline-block w-full
|
|
4650
|
+
${isActiveSection ? "bg-indigo-500/10 text-white ring-1 ring-indigo-500/30" : "hover:bg-white/5 hover:text-slate-200"}
|
|
4578
4651
|
`
|
|
4579
4652
|
},
|
|
4580
|
-
formatLineContent2(line, availableNodes, onMentionClick, isActiveSection ? activeMentionIndex : -1, mentionCounterRef, setRef, onImageClick)
|
|
4581
|
-
)
|
|
4653
|
+
formatLineContent2(line, availableNodes, onMentionClick, isActiveSection ? activeMentionIndex : -1, mentionCounterRef, setRef, onImageClick, handleToggleCheckbox, globalCheckboxCounterRef)
|
|
4654
|
+
));
|
|
4582
4655
|
}));
|
|
4583
4656
|
});
|
|
4584
4657
|
};
|
|
@@ -4606,7 +4679,9 @@ function DescriptionDisplay({
|
|
|
4606
4679
|
${isActiveSection ? "opacity-100" : "opacity-90"}
|
|
4607
4680
|
` }, renderMixedContent(resolved.content, index, isActiveSection, -1, setRef)));
|
|
4608
4681
|
};
|
|
4609
|
-
|
|
4682
|
+
globalCheckboxCounterRef.current = 0;
|
|
4683
|
+
const hasUnsavedChanges = localDescription !== (description || "");
|
|
4684
|
+
return /* @__PURE__ */ import_react7.default.createElement("div", { className: "relative w-full h-full min-h-[100px]" }, /* @__PURE__ */ import_react7.default.createElement("div", { className: "w-full text-sm leading-relaxed text-slate-300 break-words whitespace-pre-wrap px-3 pt-1 pb-16 pr-9" }, sections.map((section, index) => {
|
|
4610
4685
|
const currentNavItem = flatNavigation[currentStepIndex];
|
|
4611
4686
|
const isSectionContextActive = currentNavItem && currentNavItem.sectionIndex === index;
|
|
4612
4687
|
const activeMentionIndex = isSectionContextActive && currentNavItem.type === "mention" ? currentNavItem.mentionIndex : -1;
|
|
@@ -4622,7 +4697,18 @@ function DescriptionDisplay({
|
|
|
4622
4697
|
if (index === 0) leadingSpace = "";
|
|
4623
4698
|
const isRef = bodyText.trim().match(/^\[\[REF:(node|ancestry):([a-zA-Z0-9\-_]+):([a-zA-Z0-9\-_]+)\]\]$/);
|
|
4624
4699
|
return /* @__PURE__ */ import_react7.default.createElement(import_react7.default.Fragment, { key: index }, /* @__PURE__ */ import_react7.default.createElement("span", null, leadingSpace), isRef ? renderReferenceSection(bodyText, index, isSectionContextActive, setRef) : renderMixedContent(bodyText, index, isSectionContextActive, activeMentionIndex, setRef), /* @__PURE__ */ import_react7.default.createElement("span", null, trailingSpace));
|
|
4625
|
-
}))
|
|
4700
|
+
})), hasUnsavedChanges && onSaveDescription && /* @__PURE__ */ import_react7.default.createElement("div", { className: "absolute bottom-2 left-2 z-[100] animate-in slide-in-from-bottom-2 fade-in duration-300" }, /* @__PURE__ */ import_react7.default.createElement(
|
|
4701
|
+
"button",
|
|
4702
|
+
{
|
|
4703
|
+
onClick: (e) => {
|
|
4704
|
+
e.stopPropagation();
|
|
4705
|
+
onSaveDescription(localDescription);
|
|
4706
|
+
},
|
|
4707
|
+
className: "flex items-center gap-1.5 px-3 py-1.5 bg-emerald-600/90 hover:bg-emerald-500 text-white rounded-md shadow-[0_4px_12px_rgba(5,150,105,0.3)] text-xs font-medium transition-all hover:scale-105 active:scale-95 border border-emerald-400/20 backdrop-blur-sm"
|
|
4708
|
+
},
|
|
4709
|
+
/* @__PURE__ */ import_react7.default.createElement(import_fi5.FiSave, { size: 12 }),
|
|
4710
|
+
" Salvar Checklist"
|
|
4711
|
+
)));
|
|
4626
4712
|
}
|
|
4627
4713
|
|
|
4628
4714
|
// src/components/DescriptionReadModePanel.jsx
|
|
@@ -4712,7 +4798,8 @@ function DescriptionReadModePanel({
|
|
|
4712
4798
|
userRole,
|
|
4713
4799
|
abstractionTree = null,
|
|
4714
4800
|
onRenderAbstractionTree = null,
|
|
4715
|
-
initialShowAbstraction = false
|
|
4801
|
+
initialShowAbstraction = false,
|
|
4802
|
+
onSaveDescription
|
|
4716
4803
|
}) {
|
|
4717
4804
|
const [showProperties, setShowProperties] = (0, import_react8.useState)(false);
|
|
4718
4805
|
const [showAbstraction, setShowAbstraction] = (0, import_react8.useState)(false);
|
|
@@ -4930,7 +5017,8 @@ function DescriptionReadModePanel({
|
|
|
4930
5017
|
onHighlightNode,
|
|
4931
5018
|
initialSectionId,
|
|
4932
5019
|
currentBranchDirection,
|
|
4933
|
-
onImageClick
|
|
5020
|
+
onImageClick,
|
|
5021
|
+
onSaveDescription
|
|
4934
5022
|
}
|
|
4935
5023
|
)),
|
|
4936
5024
|
leftAction && !showAbstraction && !showProperties && /* @__PURE__ */ import_react8.default.createElement(
|
|
@@ -7712,6 +7800,11 @@ function NodeDetailsPanel({
|
|
|
7712
7800
|
textureImageUrl: url
|
|
7713
7801
|
});
|
|
7714
7802
|
};
|
|
7803
|
+
const handleSaveDescriptionInline = (newDescription) => {
|
|
7804
|
+
setDescription(newDescription);
|
|
7805
|
+
onDataUpdate({ ...node, description: newDescription });
|
|
7806
|
+
triggerAutoSave({ description: newDescription });
|
|
7807
|
+
};
|
|
7715
7808
|
const handleSave = async (keepOpen = false, overrides = {}) => {
|
|
7716
7809
|
const currentName = overrides.name !== void 0 ? overrides.name : name;
|
|
7717
7810
|
const currentTypes = overrides.types !== void 0 ? overrides.types : types;
|
|
@@ -7806,7 +7899,8 @@ function NodeDetailsPanel({
|
|
|
7806
7899
|
availableAncestries,
|
|
7807
7900
|
onOpenReference,
|
|
7808
7901
|
onMentionClick,
|
|
7809
|
-
onImageClick: handleImageClickFromText
|
|
7902
|
+
onImageClick: handleImageClickFromText,
|
|
7903
|
+
onSaveDescription: handleSaveDescriptionInline
|
|
7810
7904
|
}
|
|
7811
7905
|
) : /* @__PURE__ */ import_react16.default.createElement(import_react16.default.Fragment, null, /* @__PURE__ */ import_react16.default.createElement("div", { className: "h-[2px] bg-gradient-to-r from-indigo-400/0 via-indigo-400/70 to-indigo-400/0" }), /* @__PURE__ */ import_react16.default.createElement("div", { className: "px-6 pt-5 pb-3 flex items-start justify-between gap-4" }, /* @__PURE__ */ import_react16.default.createElement("div", null, /* @__PURE__ */ import_react16.default.createElement("div", { className: "flex items-center gap-2 mb-1" }, /* @__PURE__ */ import_react16.default.createElement("span", { className: "inline-flex h-2.5 w-2.5 rounded-full bg-indigo-400/80 shadow-[0_0_18px_2px_rgba(99,102,241,0.55)]" }), /* @__PURE__ */ import_react16.default.createElement("p", { className: "text-xs/relaxed text-slate-300" }, "Detalhes do Node"), /* @__PURE__ */ import_react16.default.createElement(
|
|
7812
7906
|
"button",
|
|
@@ -7874,7 +7968,8 @@ function NodeDetailsPanel({
|
|
|
7874
7968
|
availableAncestries,
|
|
7875
7969
|
onOpenReference,
|
|
7876
7970
|
onMentionClick,
|
|
7877
|
-
onImageClick: handleImageClickFromText
|
|
7971
|
+
onImageClick: handleImageClickFromText,
|
|
7972
|
+
onSaveDescription: handleSaveDescriptionInline
|
|
7878
7973
|
}
|
|
7879
7974
|
), /* @__PURE__ */ import_react16.default.createElement("div", { className: "absolute top-0 right-0 flex bg-slate-900/50 rounded-bl-lg backdrop-blur-sm opacity-0 group-hover:opacity-100 focus-within:opacity-100 transition-opacity overflow-hidden border-b border-l border-white/5" }, /* @__PURE__ */ import_react16.default.createElement(
|
|
7880
7975
|
"button",
|
package/dist/index.mjs
CHANGED
|
@@ -3172,8 +3172,8 @@ function CustomPropertyDisplay({
|
|
|
3172
3172
|
const availableOptions = [
|
|
3173
3173
|
{ value: "links", label: "Links", unique: true },
|
|
3174
3174
|
{ value: "images", label: "Images", unique: true },
|
|
3175
|
-
{ value: "documents", label: "Documents", unique: true },
|
|
3176
3175
|
{ value: "date", label: "Data", unique: true },
|
|
3176
|
+
{ value: "documents", label: "Documents", unique: true },
|
|
3177
3177
|
{ value: "text", label: "Texto", unique: false },
|
|
3178
3178
|
{ value: "number", label: "N\xFAmero", unique: false },
|
|
3179
3179
|
{ value: "list", label: "Lista", unique: false }
|
|
@@ -3396,7 +3396,7 @@ import { FiPlus, FiEdit2 as FiEdit22, FiBookOpen } from "react-icons/fi";
|
|
|
3396
3396
|
|
|
3397
3397
|
// src/components/DescriptionEditModal.jsx
|
|
3398
3398
|
import React5, { useState as useState6, useEffect as useEffect5, useRef as useRef5, useMemo as useMemo4 } from "react";
|
|
3399
|
-
import { FiType, FiList, FiCode, FiLink as FiLink2, FiAtSign, FiSearch as FiSearch2, FiHexagon as FiHexagon2, FiGlobe, FiImage } from "react-icons/fi";
|
|
3399
|
+
import { FiType, FiList, FiCode, FiLink as FiLink2, FiAtSign, FiSearch as FiSearch2, FiHexagon as FiHexagon2, FiGlobe, FiImage, FiCheckSquare } from "react-icons/fi";
|
|
3400
3400
|
|
|
3401
3401
|
// src/components/SectionImportModal.jsx
|
|
3402
3402
|
import React4, { useState as useState5, useMemo as useMemo3, useRef as useRef4, useEffect as useEffect4 } from "react";
|
|
@@ -4036,6 +4036,24 @@ function DescriptionEditModal({
|
|
|
4036
4036
|
},
|
|
4037
4037
|
/* @__PURE__ */ React5.createElement(FiList, { size: 12 }),
|
|
4038
4038
|
" Lista"
|
|
4039
|
+
), /* @__PURE__ */ React5.createElement(
|
|
4040
|
+
"button",
|
|
4041
|
+
{
|
|
4042
|
+
onClick: () => insertAtCursor("1. "),
|
|
4043
|
+
className: "flex items-center gap-1 px-3 py-1.5 rounded bg-slate-800 hover:bg-slate-700 border border-white/10 text-xs font-medium transition-colors whitespace-nowrap",
|
|
4044
|
+
title: "Lista Numerada"
|
|
4045
|
+
},
|
|
4046
|
+
/* @__PURE__ */ React5.createElement("span", { className: "text-[10px] font-bold" }, "1."),
|
|
4047
|
+
" Numerada"
|
|
4048
|
+
), /* @__PURE__ */ React5.createElement(
|
|
4049
|
+
"button",
|
|
4050
|
+
{
|
|
4051
|
+
onClick: () => insertAtCursor("- [ ] "),
|
|
4052
|
+
className: "flex items-center gap-1 px-3 py-1.5 rounded bg-slate-800 hover:bg-slate-700 border border-white/10 text-xs font-medium transition-colors whitespace-nowrap",
|
|
4053
|
+
title: "Checklist (Checkbox)"
|
|
4054
|
+
},
|
|
4055
|
+
/* @__PURE__ */ React5.createElement(FiCheckSquare, { size: 12 }),
|
|
4056
|
+
" Checklist"
|
|
4039
4057
|
), /* @__PURE__ */ React5.createElement(
|
|
4040
4058
|
"button",
|
|
4041
4059
|
{
|
|
@@ -4199,7 +4217,7 @@ function DescriptionEditModal({
|
|
|
4199
4217
|
|
|
4200
4218
|
// src/components/DescriptionDisplay.jsx
|
|
4201
4219
|
import React6, { useMemo as useMemo5, useState as useState7, useEffect as useEffect6, useRef as useRef6 } from "react";
|
|
4202
|
-
import { FiCopy as FiCopy2, FiCheck as FiCheck3, FiChevronDown as FiChevronDown3, FiChevronRight as FiChevronRight2, FiTerminal as FiTerminal2, FiCornerDownRight, FiExternalLink as FiExternalLink2, FiImage as FiImage2 } from "react-icons/fi";
|
|
4220
|
+
import { FiCopy as FiCopy2, FiCheck as FiCheck3, FiChevronDown as FiChevronDown3, FiChevronRight as FiChevronRight2, FiTerminal as FiTerminal2, FiCornerDownRight, FiExternalLink as FiExternalLink2, FiImage as FiImage2, FiSave } from "react-icons/fi";
|
|
4203
4221
|
var CodeBlock2 = ({ content, isActive, onClick }) => {
|
|
4204
4222
|
const [isExpanded, setIsExpanded] = useState7(false);
|
|
4205
4223
|
const [copied, setCopied] = useState7(false);
|
|
@@ -4342,7 +4360,7 @@ var renderTextWithMentions = (text, availableNodes, onMentionClick, activeMentio
|
|
|
4342
4360
|
);
|
|
4343
4361
|
});
|
|
4344
4362
|
};
|
|
4345
|
-
var formatLineContent2 = (line, availableNodes, onMentionClick, activeMentionIndex, mentionCounterRef, setRef, onImageClick) => {
|
|
4363
|
+
var formatLineContent2 = (line, availableNodes, onMentionClick, activeMentionIndex, mentionCounterRef, setRef, onImageClick, onToggleCheckbox, globalCheckboxCounterRef) => {
|
|
4346
4364
|
const trimmedLine = line.replace(/\r$/, "");
|
|
4347
4365
|
const processContent = (content) => renderTextWithMentions(content, availableNodes, onMentionClick, activeMentionIndex, mentionCounterRef, setRef, onImageClick);
|
|
4348
4366
|
if (line.startsWith("# ")) {
|
|
@@ -4353,9 +4371,46 @@ var formatLineContent2 = (line, availableNodes, onMentionClick, activeMentionInd
|
|
|
4353
4371
|
const content = line.replace("## ", "");
|
|
4354
4372
|
return /* @__PURE__ */ React6.createElement("span", { className: "text-sm sm:text-base font-semibold text-indigo-200 leading-tight break-words" }, processContent(content));
|
|
4355
4373
|
}
|
|
4374
|
+
const checkboxMatch = trimmedLine.match(/^(\s*)- \[([ xX])\]\s+(.*)/);
|
|
4375
|
+
if (checkboxMatch) {
|
|
4376
|
+
const [_, space, state, content] = checkboxMatch;
|
|
4377
|
+
const isChecked = state.toLowerCase() === "x";
|
|
4378
|
+
const currentIdx = globalCheckboxCounterRef.current;
|
|
4379
|
+
globalCheckboxCounterRef.current += 1;
|
|
4380
|
+
return /* @__PURE__ */ React6.createElement("span", { className: "flex items-start gap-2.5 my-1 break-words ml-1 group/checkbox" }, /* @__PURE__ */ React6.createElement(
|
|
4381
|
+
"div",
|
|
4382
|
+
{
|
|
4383
|
+
onClick: (e) => {
|
|
4384
|
+
e.stopPropagation();
|
|
4385
|
+
if (onToggleCheckbox) onToggleCheckbox(currentIdx);
|
|
4386
|
+
},
|
|
4387
|
+
className: `mt-1 cursor-pointer w-4 h-4 rounded border flex-shrink-0 flex items-center justify-center transition-all duration-200
|
|
4388
|
+
${isChecked ? "bg-indigo-500 border-indigo-500 shadow-[0_0_8px_rgba(99,102,241,0.4)]" : "border-slate-500 bg-slate-900/50 hover:border-slate-400 group-hover/checkbox:border-slate-400"}
|
|
4389
|
+
`
|
|
4390
|
+
},
|
|
4391
|
+
isChecked && /* @__PURE__ */ React6.createElement(FiCheck3, { size: 12, className: "text-white" })
|
|
4392
|
+
), /* @__PURE__ */ React6.createElement(
|
|
4393
|
+
"span",
|
|
4394
|
+
{
|
|
4395
|
+
className: `transition-all duration-200 cursor-pointer pt-[1px]
|
|
4396
|
+
${isChecked ? "line-through text-slate-500" : "text-slate-200 group-hover/checkbox:text-white"}
|
|
4397
|
+
`,
|
|
4398
|
+
onClick: (e) => {
|
|
4399
|
+
e.stopPropagation();
|
|
4400
|
+
if (onToggleCheckbox) onToggleCheckbox(currentIdx);
|
|
4401
|
+
}
|
|
4402
|
+
},
|
|
4403
|
+
processContent(content)
|
|
4404
|
+
));
|
|
4405
|
+
}
|
|
4406
|
+
const numberMatch = trimmedLine.match(/^(\s*)(\d+\.)\s+(.*)/);
|
|
4407
|
+
if (numberMatch) {
|
|
4408
|
+
const [_, space, numberStr, content] = numberMatch;
|
|
4409
|
+
return /* @__PURE__ */ React6.createElement("span", { className: "flex items-start gap-2 my-0.5 break-words ml-1" }, /* @__PURE__ */ React6.createElement("span", { className: "text-indigo-400 font-mono font-bold text-xs mt-[3px] shrink-0" }, numberStr), /* @__PURE__ */ React6.createElement("span", { className: "text-slate-200" }, processContent(content)));
|
|
4410
|
+
}
|
|
4356
4411
|
if (trimmedLine.trim().startsWith("- ") || trimmedLine.trim().startsWith("* ")) {
|
|
4357
4412
|
const content = trimmedLine.trim().substring(2);
|
|
4358
|
-
return /* @__PURE__ */ React6.createElement("span", { className: "
|
|
4413
|
+
return /* @__PURE__ */ React6.createElement("span", { className: "flex items-start gap-2 my-0.5 break-words ml-1 text-slate-200" }, /* @__PURE__ */ React6.createElement("span", { className: "text-indigo-400 font-bold shrink-0 mt-[2px] text-xs" }, "\u2022"), /* @__PURE__ */ React6.createElement("span", null, processContent(content)));
|
|
4359
4414
|
}
|
|
4360
4415
|
return /* @__PURE__ */ React6.createElement("span", { className: "break-words" }, processContent(line));
|
|
4361
4416
|
};
|
|
@@ -4367,14 +4422,31 @@ function DescriptionDisplay({
|
|
|
4367
4422
|
onOpenReference,
|
|
4368
4423
|
onMentionClick,
|
|
4369
4424
|
onImageClick,
|
|
4370
|
-
// <--- NOVA PROP RECEBIDA
|
|
4371
4425
|
onSectionChange,
|
|
4372
4426
|
onBranchNav,
|
|
4373
4427
|
onHighlightNode,
|
|
4374
4428
|
initialSectionId,
|
|
4375
|
-
currentBranchDirection = null
|
|
4429
|
+
currentBranchDirection = null,
|
|
4430
|
+
onSaveDescription
|
|
4376
4431
|
}) {
|
|
4377
|
-
const
|
|
4432
|
+
const [localDescription, setLocalDescription] = useState7(description || "");
|
|
4433
|
+
useEffect6(() => {
|
|
4434
|
+
setLocalDescription(description || "");
|
|
4435
|
+
}, [description]);
|
|
4436
|
+
const sections = useMemo5(() => parseDescriptionSections(localDescription, savedSections), [localDescription, savedSections]);
|
|
4437
|
+
const globalCheckboxCounterRef = useRef6(0);
|
|
4438
|
+
const handleToggleCheckbox = (targetIndex) => {
|
|
4439
|
+
let currentIndex = 0;
|
|
4440
|
+
const newDesc = localDescription.replace(/^(\s*)- \[([ xX])\]/gm, (match, space, state) => {
|
|
4441
|
+
if (currentIndex === targetIndex) {
|
|
4442
|
+
currentIndex++;
|
|
4443
|
+
return state === " " ? `${space}- [x]` : `${space}- [ ]`;
|
|
4444
|
+
}
|
|
4445
|
+
currentIndex++;
|
|
4446
|
+
return match;
|
|
4447
|
+
});
|
|
4448
|
+
setLocalDescription(newDesc);
|
|
4449
|
+
};
|
|
4378
4450
|
const flatNavigation = useMemo5(() => {
|
|
4379
4451
|
const navItems = [];
|
|
4380
4452
|
sections.forEach((section, sIdx) => {
|
|
@@ -4515,26 +4587,27 @@ function DescriptionDisplay({
|
|
|
4515
4587
|
}
|
|
4516
4588
|
const lines = part.replace(/\n$/, "").split("\n");
|
|
4517
4589
|
return /* @__PURE__ */ React6.createElement(React6.Fragment, { key: `text-${parentIndex}-${partIndex}` }, lines.map((line, lineIndex) => {
|
|
4518
|
-
const isLastLine = lineIndex === lines.length - 1;
|
|
4519
4590
|
const isEmptyLine = line.trim() === "";
|
|
4520
4591
|
if (isEmptyLine) {
|
|
4521
4592
|
return /* @__PURE__ */ React6.createElement(React6.Fragment, { key: `${parentIndex}-${partIndex}-${lineIndex}` }, /* @__PURE__ */ React6.createElement("br", null));
|
|
4522
4593
|
}
|
|
4523
4594
|
return /* @__PURE__ */ React6.createElement(React6.Fragment, { key: `${parentIndex}-${partIndex}-${lineIndex}` }, /* @__PURE__ */ React6.createElement(
|
|
4524
|
-
"
|
|
4595
|
+
"div",
|
|
4525
4596
|
{
|
|
4526
4597
|
ref: isActiveSection && activeMentionIndex === -1 && partIndex === 0 && lineIndex === 0 ? setRef : null,
|
|
4527
|
-
onClick: () => {
|
|
4528
|
-
|
|
4529
|
-
|
|
4598
|
+
onClick: (e) => {
|
|
4599
|
+
if (e.target.type !== "checkbox") {
|
|
4600
|
+
const idx = flatNavigation.findIndex((item) => item.type === "section" && item.sectionIndex === parentIndex);
|
|
4601
|
+
if (idx !== -1) setCurrentStepIndex(idx);
|
|
4602
|
+
}
|
|
4530
4603
|
},
|
|
4531
4604
|
className: `
|
|
4532
|
-
transition-colors duration-200 cursor-pointer rounded-md px-1 py-0.5 -mx-1 box-decoration-clone
|
|
4533
|
-
${isActiveSection ? "bg-indigo-500/
|
|
4605
|
+
transition-colors duration-200 cursor-pointer rounded-md px-1 py-0.5 -mx-1 box-decoration-clone inline-block w-full
|
|
4606
|
+
${isActiveSection ? "bg-indigo-500/10 text-white ring-1 ring-indigo-500/30" : "hover:bg-white/5 hover:text-slate-200"}
|
|
4534
4607
|
`
|
|
4535
4608
|
},
|
|
4536
|
-
formatLineContent2(line, availableNodes, onMentionClick, isActiveSection ? activeMentionIndex : -1, mentionCounterRef, setRef, onImageClick)
|
|
4537
|
-
)
|
|
4609
|
+
formatLineContent2(line, availableNodes, onMentionClick, isActiveSection ? activeMentionIndex : -1, mentionCounterRef, setRef, onImageClick, handleToggleCheckbox, globalCheckboxCounterRef)
|
|
4610
|
+
));
|
|
4538
4611
|
}));
|
|
4539
4612
|
});
|
|
4540
4613
|
};
|
|
@@ -4562,7 +4635,9 @@ function DescriptionDisplay({
|
|
|
4562
4635
|
${isActiveSection ? "opacity-100" : "opacity-90"}
|
|
4563
4636
|
` }, renderMixedContent(resolved.content, index, isActiveSection, -1, setRef)));
|
|
4564
4637
|
};
|
|
4565
|
-
|
|
4638
|
+
globalCheckboxCounterRef.current = 0;
|
|
4639
|
+
const hasUnsavedChanges = localDescription !== (description || "");
|
|
4640
|
+
return /* @__PURE__ */ React6.createElement("div", { className: "relative w-full h-full min-h-[100px]" }, /* @__PURE__ */ React6.createElement("div", { className: "w-full text-sm leading-relaxed text-slate-300 break-words whitespace-pre-wrap px-3 pt-1 pb-16 pr-9" }, sections.map((section, index) => {
|
|
4566
4641
|
const currentNavItem = flatNavigation[currentStepIndex];
|
|
4567
4642
|
const isSectionContextActive = currentNavItem && currentNavItem.sectionIndex === index;
|
|
4568
4643
|
const activeMentionIndex = isSectionContextActive && currentNavItem.type === "mention" ? currentNavItem.mentionIndex : -1;
|
|
@@ -4578,7 +4653,18 @@ function DescriptionDisplay({
|
|
|
4578
4653
|
if (index === 0) leadingSpace = "";
|
|
4579
4654
|
const isRef = bodyText.trim().match(/^\[\[REF:(node|ancestry):([a-zA-Z0-9\-_]+):([a-zA-Z0-9\-_]+)\]\]$/);
|
|
4580
4655
|
return /* @__PURE__ */ React6.createElement(React6.Fragment, { key: index }, /* @__PURE__ */ React6.createElement("span", null, leadingSpace), isRef ? renderReferenceSection(bodyText, index, isSectionContextActive, setRef) : renderMixedContent(bodyText, index, isSectionContextActive, activeMentionIndex, setRef), /* @__PURE__ */ React6.createElement("span", null, trailingSpace));
|
|
4581
|
-
}))
|
|
4656
|
+
})), hasUnsavedChanges && onSaveDescription && /* @__PURE__ */ React6.createElement("div", { className: "absolute bottom-2 left-2 z-[100] animate-in slide-in-from-bottom-2 fade-in duration-300" }, /* @__PURE__ */ React6.createElement(
|
|
4657
|
+
"button",
|
|
4658
|
+
{
|
|
4659
|
+
onClick: (e) => {
|
|
4660
|
+
e.stopPropagation();
|
|
4661
|
+
onSaveDescription(localDescription);
|
|
4662
|
+
},
|
|
4663
|
+
className: "flex items-center gap-1.5 px-3 py-1.5 bg-emerald-600/90 hover:bg-emerald-500 text-white rounded-md shadow-[0_4px_12px_rgba(5,150,105,0.3)] text-xs font-medium transition-all hover:scale-105 active:scale-95 border border-emerald-400/20 backdrop-blur-sm"
|
|
4664
|
+
},
|
|
4665
|
+
/* @__PURE__ */ React6.createElement(FiSave, { size: 12 }),
|
|
4666
|
+
" Salvar Checklist"
|
|
4667
|
+
)));
|
|
4582
4668
|
}
|
|
4583
4669
|
|
|
4584
4670
|
// src/components/DescriptionReadModePanel.jsx
|
|
@@ -4682,7 +4768,8 @@ function DescriptionReadModePanel({
|
|
|
4682
4768
|
userRole,
|
|
4683
4769
|
abstractionTree = null,
|
|
4684
4770
|
onRenderAbstractionTree = null,
|
|
4685
|
-
initialShowAbstraction = false
|
|
4771
|
+
initialShowAbstraction = false,
|
|
4772
|
+
onSaveDescription
|
|
4686
4773
|
}) {
|
|
4687
4774
|
const [showProperties, setShowProperties] = useState8(false);
|
|
4688
4775
|
const [showAbstraction, setShowAbstraction] = useState8(false);
|
|
@@ -4900,7 +4987,8 @@ function DescriptionReadModePanel({
|
|
|
4900
4987
|
onHighlightNode,
|
|
4901
4988
|
initialSectionId,
|
|
4902
4989
|
currentBranchDirection,
|
|
4903
|
-
onImageClick
|
|
4990
|
+
onImageClick,
|
|
4991
|
+
onSaveDescription
|
|
4904
4992
|
}
|
|
4905
4993
|
)),
|
|
4906
4994
|
leftAction && !showAbstraction && !showProperties && /* @__PURE__ */ React7.createElement(
|
|
@@ -7698,6 +7786,11 @@ function NodeDetailsPanel({
|
|
|
7698
7786
|
textureImageUrl: url
|
|
7699
7787
|
});
|
|
7700
7788
|
};
|
|
7789
|
+
const handleSaveDescriptionInline = (newDescription) => {
|
|
7790
|
+
setDescription(newDescription);
|
|
7791
|
+
onDataUpdate({ ...node, description: newDescription });
|
|
7792
|
+
triggerAutoSave({ description: newDescription });
|
|
7793
|
+
};
|
|
7701
7794
|
const handleSave = async (keepOpen = false, overrides = {}) => {
|
|
7702
7795
|
const currentName = overrides.name !== void 0 ? overrides.name : name;
|
|
7703
7796
|
const currentTypes = overrides.types !== void 0 ? overrides.types : types;
|
|
@@ -7792,7 +7885,8 @@ function NodeDetailsPanel({
|
|
|
7792
7885
|
availableAncestries,
|
|
7793
7886
|
onOpenReference,
|
|
7794
7887
|
onMentionClick,
|
|
7795
|
-
onImageClick: handleImageClickFromText
|
|
7888
|
+
onImageClick: handleImageClickFromText,
|
|
7889
|
+
onSaveDescription: handleSaveDescriptionInline
|
|
7796
7890
|
}
|
|
7797
7891
|
) : /* @__PURE__ */ React15.createElement(React15.Fragment, null, /* @__PURE__ */ React15.createElement("div", { className: "h-[2px] bg-gradient-to-r from-indigo-400/0 via-indigo-400/70 to-indigo-400/0" }), /* @__PURE__ */ React15.createElement("div", { className: "px-6 pt-5 pb-3 flex items-start justify-between gap-4" }, /* @__PURE__ */ React15.createElement("div", null, /* @__PURE__ */ React15.createElement("div", { className: "flex items-center gap-2 mb-1" }, /* @__PURE__ */ React15.createElement("span", { className: "inline-flex h-2.5 w-2.5 rounded-full bg-indigo-400/80 shadow-[0_0_18px_2px_rgba(99,102,241,0.55)]" }), /* @__PURE__ */ React15.createElement("p", { className: "text-xs/relaxed text-slate-300" }, "Detalhes do Node"), /* @__PURE__ */ React15.createElement(
|
|
7798
7892
|
"button",
|
|
@@ -7860,7 +7954,8 @@ function NodeDetailsPanel({
|
|
|
7860
7954
|
availableAncestries,
|
|
7861
7955
|
onOpenReference,
|
|
7862
7956
|
onMentionClick,
|
|
7863
|
-
onImageClick: handleImageClickFromText
|
|
7957
|
+
onImageClick: handleImageClickFromText,
|
|
7958
|
+
onSaveDescription: handleSaveDescriptionInline
|
|
7864
7959
|
}
|
|
7865
7960
|
), /* @__PURE__ */ React15.createElement("div", { className: "absolute top-0 right-0 flex bg-slate-900/50 rounded-bl-lg backdrop-blur-sm opacity-0 group-hover:opacity-100 focus-within:opacity-100 transition-opacity overflow-hidden border-b border-l border-white/5" }, /* @__PURE__ */ React15.createElement(
|
|
7866
7961
|
"button",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lv-x-software-house/x_view",
|
|
3
|
-
"version": "1.2.2-dev.
|
|
3
|
+
"version": "1.2.2-dev.18",
|
|
4
4
|
"description": "Pacote privado contendo os componentes e lógica de renderização 3D do X View.",
|
|
5
5
|
"author": "iv.x - Engenharia de Software - ivxsoftwarehouse@gmail.com",
|
|
6
6
|
"license": "UNLICENSED",
|