@lv-x-software-house/x_view 1.2.5-dev.31 → 1.2.5-dev.33
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 +136 -19
- package/dist/index.mjs +141 -24
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -9724,12 +9724,16 @@ var EVENT_ICONS = {
|
|
|
9724
9724
|
function QuestTimeline({
|
|
9725
9725
|
timeline = [],
|
|
9726
9726
|
viewMembers = [],
|
|
9727
|
-
onOpenImageViewer
|
|
9727
|
+
onOpenImageViewer,
|
|
9728
|
+
onAddNote,
|
|
9729
|
+
// Nova prop para adicionar nota a uma etapa específica
|
|
9730
|
+
canEdit = true
|
|
9728
9731
|
}) {
|
|
9729
9732
|
const sortedTimeline = [...timeline].sort((a, b) => b.timestamp - a.timestamp);
|
|
9730
9733
|
const getMemberName = (userId) => {
|
|
9731
|
-
|
|
9732
|
-
|
|
9734
|
+
if (!userId) return "Sistema";
|
|
9735
|
+
const member = viewMembers.find((m) => String(m.id) === String(userId));
|
|
9736
|
+
return (member == null ? void 0 : member.name) || (member == null ? void 0 : member.email) || userId;
|
|
9733
9737
|
};
|
|
9734
9738
|
const formatDate = (timestamp) => {
|
|
9735
9739
|
const date = new Date(timestamp);
|
|
@@ -9743,11 +9747,23 @@ function QuestTimeline({
|
|
|
9743
9747
|
if (timeline.length === 0) {
|
|
9744
9748
|
return /* @__PURE__ */ import_react19.default.createElement("div", { className: "py-6 flex flex-col items-center justify-center gap-2 border border-white/5 bg-white/5 rounded-xl" }, /* @__PURE__ */ import_react19.default.createElement(import_fi17.FiAlertCircle, { className: "text-slate-600", size: 16 }), /* @__PURE__ */ import_react19.default.createElement("p", { className: "text-[10px] text-slate-500 font-light uppercase tracking-widest" }, "Nenhum hist\xF3rico dispon\xEDvel"));
|
|
9745
9749
|
}
|
|
9746
|
-
return /* @__PURE__ */ import_react19.default.createElement("div", { className: "space-y-4" }, /* @__PURE__ */ import_react19.default.createElement("h3", { className: "text-xs text-slate-400 font-medium uppercase tracking-wider flex items-center gap-2" }, "Hist\xF3rico (Timeline)"), /* @__PURE__ */ import_react19.default.createElement("div", { className: "relative pl-
|
|
9750
|
+
return /* @__PURE__ */ import_react19.default.createElement("div", { className: "space-y-4" }, /* @__PURE__ */ import_react19.default.createElement("h3", { className: "text-xs text-slate-400 font-medium uppercase tracking-wider flex items-center gap-2" }, "Hist\xF3rico (Timeline)"), /* @__PURE__ */ import_react19.default.createElement("div", { className: "relative pl-10 space-y-6 before:content-[''] before:absolute before:left-[21px] before:top-2 before:bottom-2 before:w-[2px] before:bg-white/5" }, sortedTimeline.map((event, index) => {
|
|
9747
9751
|
const config = EVENT_ICONS[event.type] || EVENT_ICONS.default;
|
|
9748
9752
|
const Icon = config.icon;
|
|
9749
9753
|
const actorName = getMemberName(event.actorId);
|
|
9750
|
-
return /* @__PURE__ */ import_react19.default.createElement("div", { key: index, className: "relative animate-in fade-in slide-in-from-left-2 duration-300", style: { animationDelay: `${index * 50}ms` } }, /* @__PURE__ */ import_react19.default.createElement("div", { className: `absolute -left-[
|
|
9754
|
+
return /* @__PURE__ */ import_react19.default.createElement("div", { key: event.id || index, className: "relative animate-in fade-in slide-in-from-left-2 duration-300", style: { animationDelay: `${index * 50}ms` } }, /* @__PURE__ */ import_react19.default.createElement("div", { className: `absolute -left-[35px] top-0 w-8 h-8 rounded-full ${config.bg} flex items-center justify-center ring-4 ring-slate-950 border border-white/5` }, /* @__PURE__ */ import_react19.default.createElement(Icon, { className: config.iconColor || config.color, size: 14 })), /* @__PURE__ */ import_react19.default.createElement("div", { className: "group space-y-1" }, /* @__PURE__ */ import_react19.default.createElement("div", { className: "flex items-center justify-between gap-4" }, /* @__PURE__ */ import_react19.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ import_react19.default.createElement("span", { className: "text-xs font-semibold text-slate-200" }, actorName), canEdit && onAddNote && /* @__PURE__ */ import_react19.default.createElement(
|
|
9755
|
+
"button",
|
|
9756
|
+
{
|
|
9757
|
+
onClick: () => onAddNote(event),
|
|
9758
|
+
className: "opacity-0 group-hover:opacity-100 p-1 rounded-md hover:bg-white/5 text-slate-500 hover:text-indigo-400 transition-all",
|
|
9759
|
+
title: "Adicionar detalhe/anexo a esta etapa"
|
|
9760
|
+
},
|
|
9761
|
+
/* @__PURE__ */ import_react19.default.createElement(import_fi17.FiPlusCircle, { size: 12 })
|
|
9762
|
+
)), /* @__PURE__ */ import_react19.default.createElement("span", { className: "text-[10px] text-slate-500 tabular-nums" }, formatDate(event.timestamp))), /* @__PURE__ */ import_react19.default.createElement("p", { className: "text-sm text-slate-400 leading-relaxed" }, event.description), event.notes && /* @__PURE__ */ import_react19.default.createElement("div", { className: "mt-1 py-1 px-2 rounded bg-indigo-500/5 border-l-2 border-indigo-500/30" }, /* @__PURE__ */ import_react19.default.createElement("p", { className: "text-[11px] text-slate-300 italic whitespace-pre-wrap" }, event.notes)), (event.from_status || event.to_status) && /* @__PURE__ */ import_react19.default.createElement("div", { className: "flex items-center gap-1.5 py-1 px-2 rounded-md bg-white/5 border border-white/5 w-fit mt-2" }, /* @__PURE__ */ import_react19.default.createElement("span", { className: "text-[10px] text-slate-500" }, event.from_status || "?"), /* @__PURE__ */ import_react19.default.createElement(import_fi17.FiArrowRight, { size: 10, className: "text-slate-600" }), /* @__PURE__ */ import_react19.default.createElement("span", { className: "text-[10px] text-indigo-300 font-bold" }, event.to_status || "?")), event.metadata && Object.keys(event.metadata).length > 0 && /* @__PURE__ */ import_react19.default.createElement("div", { className: "mt-2 text-[10px] grid grid-cols-2 gap-2 p-2 bg-slate-900/50 rounded border border-white/5" }, Object.entries(event.metadata).map(([key, value]) => {
|
|
9763
|
+
const isAssigneeId = key.toLowerCase().includes("assignee_id") || key.toLowerCase().includes("respons\xE1vel") || key.toLowerCase().includes("assignee id");
|
|
9764
|
+
const displayValue = isAssigneeId && typeof value === "string" ? getMemberName(value) : typeof value === "string" ? value : JSON.stringify(value);
|
|
9765
|
+
return /* @__PURE__ */ import_react19.default.createElement("div", { key, className: "flex flex-col gap-0.5" }, /* @__PURE__ */ import_react19.default.createElement("span", { className: "text-slate-500 capitalize" }, key.replace(/_/g, " ")), /* @__PURE__ */ import_react19.default.createElement("span", { className: `${isAssigneeId ? "text-indigo-300 font-medium" : "text-slate-300"} truncate font-mono` }, displayValue));
|
|
9766
|
+
})), event.links && event.links.length > 0 && /* @__PURE__ */ import_react19.default.createElement("div", { className: "flex flex-wrap gap-2 mt-2" }, event.links.map((link, lIdx) => /* @__PURE__ */ import_react19.default.createElement(
|
|
9751
9767
|
"a",
|
|
9752
9768
|
{
|
|
9753
9769
|
key: lIdx,
|
|
@@ -9764,10 +9780,10 @@ function QuestTimeline({
|
|
|
9764
9780
|
key: iIdx,
|
|
9765
9781
|
type: "button",
|
|
9766
9782
|
onClick: () => onOpenImageViewer == null ? void 0 : onOpenImageViewer(event.images, iIdx),
|
|
9767
|
-
className: "relative w-12 h-12 rounded border border-white/10 overflow-hidden hover:border-sky-500/50 transition-colors group"
|
|
9783
|
+
className: "relative w-12 h-12 rounded border border-white/10 overflow-hidden hover:border-sky-500/50 transition-colors group/img"
|
|
9768
9784
|
},
|
|
9769
9785
|
/* @__PURE__ */ import_react19.default.createElement("img", { src: img.value, alt: img.name, className: "w-full h-full object-cover" }),
|
|
9770
|
-
/* @__PURE__ */ import_react19.default.createElement("div", { className: "absolute inset-0 bg-slate-900/40 opacity-0 group-hover:opacity-100 flex items-center justify-center transition-opacity" }, /* @__PURE__ */ import_react19.default.createElement(import_fi17.FiSearch, { size: 12, className: "text-white" }))
|
|
9786
|
+
/* @__PURE__ */ import_react19.default.createElement("div", { className: "absolute inset-0 bg-slate-900/40 opacity-0 group-hover/img:opacity-100 flex items-center justify-center transition-opacity" }, /* @__PURE__ */ import_react19.default.createElement(import_fi17.FiSearch, { size: 12, className: "text-white" }))
|
|
9771
9787
|
)))));
|
|
9772
9788
|
})));
|
|
9773
9789
|
}
|
|
@@ -9830,7 +9846,11 @@ function QuestDetailsPanel({
|
|
|
9830
9846
|
const [isLinkCopied, setIsLinkCopied] = (0, import_react20.useState)(false);
|
|
9831
9847
|
const [hasUnsavedChanges, setHasUnsavedChanges] = (0, import_react20.useState)(false);
|
|
9832
9848
|
const [noteText, setNoteText] = (0, import_react20.useState)("");
|
|
9849
|
+
const [noteLinks, setNoteLinks] = (0, import_react20.useState)([]);
|
|
9850
|
+
const [noteImages, setNoteImages] = (0, import_react20.useState)([]);
|
|
9833
9851
|
const [isNoteFormOpen, setIsNoteFormOpen] = (0, import_react20.useState)(false);
|
|
9852
|
+
const [editingEntryId, setEditingEntryId] = (0, import_react20.useState)(null);
|
|
9853
|
+
const [editingEntryLabel, setEditingEntryLabel] = (0, import_react20.useState)("");
|
|
9834
9854
|
const maxPanelW = typeof window !== "undefined" ? window.innerWidth * 0.92 : 1200;
|
|
9835
9855
|
const { width: panelWidth, isResizing, handlePointerDown: handleResize, setWidth } = useResizablePanel({
|
|
9836
9856
|
initialWidth: isReadMode ? 700 : 440,
|
|
@@ -9962,11 +9982,30 @@ function QuestDetailsPanel({
|
|
|
9962
9982
|
}
|
|
9963
9983
|
};
|
|
9964
9984
|
const handleAddTimelineNote = async () => {
|
|
9965
|
-
if (!noteText.trim() || isSaving) return;
|
|
9985
|
+
if (!noteText.trim() && noteLinks.length === 0 && noteImages.length === 0 || isSaving) return;
|
|
9966
9986
|
setIsSaving(true);
|
|
9967
9987
|
const actorId = (currentUser == null ? void 0 : currentUser.id) || "unknown";
|
|
9968
|
-
|
|
9969
|
-
|
|
9988
|
+
let updatedTimeline;
|
|
9989
|
+
if (editingEntryId) {
|
|
9990
|
+
updatedTimeline = timeline.map((entry) => {
|
|
9991
|
+
if (entry.id === editingEntryId) {
|
|
9992
|
+
return {
|
|
9993
|
+
...entry,
|
|
9994
|
+
notes: noteText.trim() ? entry.notes ? `${entry.notes}
|
|
9995
|
+
${noteText}` : noteText : entry.notes,
|
|
9996
|
+
links: [...entry.links || [], ...noteLinks],
|
|
9997
|
+
images: [...entry.images || [], ...noteImages]
|
|
9998
|
+
};
|
|
9999
|
+
}
|
|
10000
|
+
return entry;
|
|
10001
|
+
});
|
|
10002
|
+
} else {
|
|
10003
|
+
const newEntry = createTimelineEntry(actorId, noteText, "comment", {
|
|
10004
|
+
links: noteLinks,
|
|
10005
|
+
images: noteImages
|
|
10006
|
+
});
|
|
10007
|
+
updatedTimeline = [...timeline, newEntry];
|
|
10008
|
+
}
|
|
9970
10009
|
try {
|
|
9971
10010
|
const nodeToSave = {
|
|
9972
10011
|
...node,
|
|
@@ -9976,13 +10015,47 @@ function QuestDetailsPanel({
|
|
|
9976
10015
|
setTimeline(updatedTimeline);
|
|
9977
10016
|
onDataUpdate(nodeToSave);
|
|
9978
10017
|
setNoteText("");
|
|
10018
|
+
setNoteLinks([]);
|
|
10019
|
+
setNoteImages([]);
|
|
9979
10020
|
setIsNoteFormOpen(false);
|
|
10021
|
+
setEditingEntryId(null);
|
|
10022
|
+
setEditingEntryLabel("");
|
|
9980
10023
|
} catch (error) {
|
|
9981
10024
|
console.error("Erro ao adicionar nota:", error);
|
|
9982
10025
|
} finally {
|
|
9983
10026
|
setIsSaving(false);
|
|
9984
10027
|
}
|
|
9985
10028
|
};
|
|
10029
|
+
const handleOpenNoteForEntry = (entry) => {
|
|
10030
|
+
setEditingEntryId(entry.id);
|
|
10031
|
+
setEditingEntryLabel(entry.description);
|
|
10032
|
+
setNoteText("");
|
|
10033
|
+
setNoteLinks([]);
|
|
10034
|
+
setNoteImages([]);
|
|
10035
|
+
setIsNoteFormOpen(true);
|
|
10036
|
+
setTimeout(() => {
|
|
10037
|
+
const form = document.getElementById("quest-note-form");
|
|
10038
|
+
form == null ? void 0 : form.scrollIntoView({ behavior: "smooth", block: "center" });
|
|
10039
|
+
}, 100);
|
|
10040
|
+
};
|
|
10041
|
+
const addLinkToNote = () => {
|
|
10042
|
+
setNoteLinks([...noteLinks, { id: v4_default(), name: "", value: "" }]);
|
|
10043
|
+
};
|
|
10044
|
+
const removeLinkFromNote = (id) => {
|
|
10045
|
+
setNoteLinks(noteLinks.filter((l) => l.id !== id));
|
|
10046
|
+
};
|
|
10047
|
+
const updateLinkInNote = (id, field, val) => {
|
|
10048
|
+
setNoteLinks(noteLinks.map((l) => l.id === id ? { ...l, [field]: val } : l));
|
|
10049
|
+
};
|
|
10050
|
+
const addImageToNote = () => {
|
|
10051
|
+
setNoteImages([...noteImages, { id: v4_default(), name: "Image", value: "" }]);
|
|
10052
|
+
};
|
|
10053
|
+
const removeImageFromNote = (id) => {
|
|
10054
|
+
setNoteImages(noteImages.filter((img) => img.id !== id));
|
|
10055
|
+
};
|
|
10056
|
+
const updateImageInNote = (id, val) => {
|
|
10057
|
+
setNoteImages(noteImages.map((img) => img.id === id ? { ...img, value: val } : img));
|
|
10058
|
+
};
|
|
9986
10059
|
const handleStatusChange = (newStatus) => {
|
|
9987
10060
|
setStatus(newStatus);
|
|
9988
10061
|
const newColor = QUEST_STATUS_COLORS3[newStatus];
|
|
@@ -10326,34 +10399,78 @@ function QuestDetailsPanel({
|
|
|
10326
10399
|
"button",
|
|
10327
10400
|
{
|
|
10328
10401
|
type: "button",
|
|
10329
|
-
onClick: () =>
|
|
10402
|
+
onClick: () => {
|
|
10403
|
+
if (isNoteFormOpen && editingEntryId) {
|
|
10404
|
+
setEditingEntryId(null);
|
|
10405
|
+
setEditingEntryLabel("");
|
|
10406
|
+
setNoteText("");
|
|
10407
|
+
setNoteLinks([]);
|
|
10408
|
+
setNoteImages([]);
|
|
10409
|
+
} else {
|
|
10410
|
+
setIsNoteFormOpen(!isNoteFormOpen);
|
|
10411
|
+
setEditingEntryId(null);
|
|
10412
|
+
setEditingEntryLabel("");
|
|
10413
|
+
}
|
|
10414
|
+
},
|
|
10330
10415
|
className: "flex items-center gap-1.5 px-2 py-1 text-[10px] rounded-md bg-white/5 hover:bg-white/10 border border-white/10 transition-colors text-slate-300"
|
|
10331
10416
|
},
|
|
10332
|
-
isNoteFormOpen ? /* @__PURE__ */ import_react20.default.createElement(import_fi18.FiX, { size: 12 }) : /* @__PURE__ */ import_react20.default.createElement(import_fi18.FiPlus, { size: 12 }),
|
|
10333
|
-
isNoteFormOpen ? "Cancelar" : "Nova Nota"
|
|
10334
|
-
)), isNoteFormOpen && /* @__PURE__ */ import_react20.default.createElement("div", { className: "mb-6 p-4 rounded-xl bg-white/5 border border-white/5 space-y-3 animate-in fade-in slide-in-from-top-2" }, /* @__PURE__ */ import_react20.default.createElement(
|
|
10417
|
+
isNoteFormOpen && !editingEntryId ? /* @__PURE__ */ import_react20.default.createElement(import_fi18.FiX, { size: 12 }) : /* @__PURE__ */ import_react20.default.createElement(import_fi18.FiPlus, { size: 12 }),
|
|
10418
|
+
isNoteFormOpen && !editingEntryId ? "Cancelar" : "Nova Nota"
|
|
10419
|
+
)), isNoteFormOpen && /* @__PURE__ */ import_react20.default.createElement("div", { id: "quest-note-form", className: "mb-6 p-4 rounded-xl bg-white/5 border border-white/5 space-y-3 animate-in fade-in slide-in-from-top-2 border-l-4 border-l-indigo-500/40" }, editingEntryId && /* @__PURE__ */ import_react20.default.createElement("div", { className: "flex items-center justify-between mb-2 pb-2 border-b border-white/5" }, /* @__PURE__ */ import_react20.default.createElement("div", { className: "flex flex-col" }, /* @__PURE__ */ import_react20.default.createElement("span", { className: "text-[10px] text-indigo-400 font-bold uppercase tracking-wider" }, "Adicionando \xE0 etapa:"), /* @__PURE__ */ import_react20.default.createElement("span", { className: "text-xs text-slate-300 italic truncate max-w-[250px]" }, editingEntryLabel)), /* @__PURE__ */ import_react20.default.createElement("button", { type: "button", onClick: () => {
|
|
10420
|
+
setIsNoteFormOpen(false);
|
|
10421
|
+
setEditingEntryId(null);
|
|
10422
|
+
}, className: "text-slate-500 hover:text-white" }, /* @__PURE__ */ import_react20.default.createElement(import_fi18.FiX, { size: 14 }))), /* @__PURE__ */ import_react20.default.createElement(
|
|
10335
10423
|
"textarea",
|
|
10336
10424
|
{
|
|
10337
10425
|
value: noteText,
|
|
10338
10426
|
onChange: (e) => setNoteText(e.target.value),
|
|
10339
|
-
placeholder: "Escreva uma observa\xE7\xE3o no hist\xF3rico...",
|
|
10427
|
+
placeholder: editingEntryId ? "Adicione uma observa\xE7\xE3o a esta etapa..." : "Escreva uma observa\xE7\xE3o no hist\xF3rico...",
|
|
10340
10428
|
className: "w-full bg-slate-900/50 p-3 text-sm rounded-lg border border-white/10 focus:outline-none focus:ring-1 focus:ring-indigo-500/50 min-h-[80px] resize-none"
|
|
10341
10429
|
}
|
|
10342
|
-
), /* @__PURE__ */ import_react20.default.createElement("div", { className: "flex justify-
|
|
10430
|
+
), /* @__PURE__ */ import_react20.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ import_react20.default.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ import_react20.default.createElement("span", { className: "text-[10px] text-slate-500 uppercase font-bold tracking-tight" }, "Links"), /* @__PURE__ */ import_react20.default.createElement("button", { type: "button", onClick: addLinkToNote, className: "text-indigo-400 hover:text-indigo-300 text-[10px] flex items-center gap-1 font-medium" }, /* @__PURE__ */ import_react20.default.createElement(import_fi18.FiPlus, { size: 10 }), " Adicionar Link")), noteLinks.length > 0 && /* @__PURE__ */ import_react20.default.createElement("div", { className: "space-y-2" }, noteLinks.map((link) => /* @__PURE__ */ import_react20.default.createElement("div", { key: link.id, className: "flex items-center gap-2 animate-in fade-in slide-in-from-left-1" }, /* @__PURE__ */ import_react20.default.createElement(
|
|
10431
|
+
"input",
|
|
10432
|
+
{
|
|
10433
|
+
type: "text",
|
|
10434
|
+
placeholder: "T\xEDtulo",
|
|
10435
|
+
value: link.name,
|
|
10436
|
+
onChange: (e) => updateLinkInNote(link.id, "name", e.target.value),
|
|
10437
|
+
className: "w-1/3 bg-slate-950/50 border border-white/5 rounded px-2 py-1 text-[10px] focus:outline-none focus:border-indigo-500/50"
|
|
10438
|
+
}
|
|
10439
|
+
), /* @__PURE__ */ import_react20.default.createElement(
|
|
10440
|
+
"input",
|
|
10441
|
+
{
|
|
10442
|
+
type: "text",
|
|
10443
|
+
placeholder: "URL (https://...)",
|
|
10444
|
+
value: link.value,
|
|
10445
|
+
onChange: (e) => updateLinkInNote(link.id, "value", e.target.value),
|
|
10446
|
+
className: "flex-1 bg-slate-950/50 border border-white/5 rounded px-2 py-1 text-[10px] focus:outline-none focus:border-indigo-500/50"
|
|
10447
|
+
}
|
|
10448
|
+
), /* @__PURE__ */ import_react20.default.createElement("button", { type: "button", onClick: () => removeLinkFromNote(link.id), className: "text-slate-600 hover:text-red-400 transition-colors" }, /* @__PURE__ */ import_react20.default.createElement(import_fi18.FiX, { size: 12 })))))), /* @__PURE__ */ import_react20.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ import_react20.default.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ import_react20.default.createElement("span", { className: "text-[10px] text-slate-500 uppercase font-bold tracking-tight" }, "Imagens (URLs)"), /* @__PURE__ */ import_react20.default.createElement("button", { type: "button", onClick: addImageToNote, className: "text-indigo-400 hover:text-indigo-300 text-[10px] flex items-center gap-1 font-medium" }, /* @__PURE__ */ import_react20.default.createElement(import_fi18.FiPlus, { size: 10 }), " Adicionar Imagem")), noteImages.length > 0 && /* @__PURE__ */ import_react20.default.createElement("div", { className: "space-y-2" }, noteImages.map((img) => /* @__PURE__ */ import_react20.default.createElement("div", { key: img.id, className: "flex items-center gap-2 animate-in fade-in slide-in-from-left-1" }, /* @__PURE__ */ import_react20.default.createElement("div", { className: "flex-1 flex items-center gap-2 bg-slate-950/50 border border-white/5 rounded px-2 py-1" }, /* @__PURE__ */ import_react20.default.createElement(FiImage, { size: 10, className: "text-slate-600" }), /* @__PURE__ */ import_react20.default.createElement(
|
|
10449
|
+
"input",
|
|
10450
|
+
{
|
|
10451
|
+
type: "text",
|
|
10452
|
+
placeholder: "URL da Imagem (https://...)",
|
|
10453
|
+
value: img.value,
|
|
10454
|
+
onChange: (e) => updateImageInNote(img.id, e.target.value),
|
|
10455
|
+
className: "flex-1 bg-transparent text-[10px] focus:outline-none"
|
|
10456
|
+
}
|
|
10457
|
+
)), /* @__PURE__ */ import_react20.default.createElement("button", { type: "button", onClick: () => removeImageFromNote(img.id), className: "text-slate-600 hover:text-red-400 transition-colors" }, /* @__PURE__ */ import_react20.default.createElement(import_fi18.FiX, { size: 12 })))))), /* @__PURE__ */ import_react20.default.createElement("div", { className: "flex justify-end gap-2 pt-2" }, /* @__PURE__ */ import_react20.default.createElement(
|
|
10343
10458
|
"button",
|
|
10344
10459
|
{
|
|
10345
10460
|
type: "button",
|
|
10346
10461
|
onClick: handleAddTimelineNote,
|
|
10347
|
-
disabled: !noteText.trim() || isSaving,
|
|
10462
|
+
disabled: !noteText.trim() && noteLinks.length === 0 && noteImages.length === 0 || isSaving,
|
|
10348
10463
|
className: "px-3 py-1.5 rounded-lg bg-indigo-600 hover:bg-indigo-500 text-white text-xs font-semibold transition-colors disabled:opacity-50"
|
|
10349
10464
|
},
|
|
10350
|
-
"Adicionar ao Hist\xF3rico"
|
|
10465
|
+
editingEntryId ? "Salvar nesta Etapa" : "Adicionar ao Hist\xF3rico"
|
|
10351
10466
|
))), /* @__PURE__ */ import_react20.default.createElement(
|
|
10352
10467
|
QuestTimeline,
|
|
10353
10468
|
{
|
|
10354
10469
|
timeline,
|
|
10355
10470
|
viewMembers,
|
|
10356
|
-
onOpenImageViewer
|
|
10471
|
+
onOpenImageViewer,
|
|
10472
|
+
canEdit,
|
|
10473
|
+
onAddNote: handleOpenNoteForEntry
|
|
10357
10474
|
}
|
|
10358
10475
|
)), /* @__PURE__ */ import_react20.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ import_react20.default.createElement("label", { className: "text-xs text-slate-300" }, "Tamanho no Node (Size)"), /* @__PURE__ */ import_react20.default.createElement("div", { className: "flex items-center gap-5" }, ["small", "medium", "large"].map((s) => {
|
|
10359
10476
|
const isSelected = size === s;
|
package/dist/index.mjs
CHANGED
|
@@ -4002,7 +4002,7 @@ import { FiPlus, FiEdit2 as FiEdit22, FiBookOpen } from "react-icons/fi";
|
|
|
4002
4002
|
|
|
4003
4003
|
// src/components/DescriptionEditModal.jsx
|
|
4004
4004
|
import React5, { useState as useState6, useEffect as useEffect5, useRef as useRef5, useMemo as useMemo4 } from "react";
|
|
4005
|
-
import { FiType, FiList, FiCode, FiLink as FiLink2, FiAtSign, FiSearch as FiSearch2, FiHexagon as FiHexagon2, FiGlobe, FiImage, FiCheckSquare } from "react-icons/fi";
|
|
4005
|
+
import { FiType, FiList, FiCode, FiLink as FiLink2, FiAtSign, FiSearch as FiSearch2, FiHexagon as FiHexagon2, FiGlobe, FiImage as FiImage2, FiCheckSquare } from "react-icons/fi";
|
|
4006
4006
|
|
|
4007
4007
|
// src/components/SectionImportModal.jsx
|
|
4008
4008
|
import React4, { useState as useState5, useMemo as useMemo3, useRef as useRef4, useEffect as useEffect4 } from "react";
|
|
@@ -4749,7 +4749,7 @@ ${space}${bullet} `);
|
|
|
4749
4749
|
className: "flex items-center gap-1 px-3 py-1.5 rounded bg-indigo-600/30 hover:bg-indigo-600/50 border border-indigo-500/30 text-indigo-200 text-xs font-medium transition-colors whitespace-nowrap",
|
|
4750
4750
|
title: "Inserir Imagem (Propriedade ou URL)"
|
|
4751
4751
|
},
|
|
4752
|
-
/* @__PURE__ */ React5.createElement(
|
|
4752
|
+
/* @__PURE__ */ React5.createElement(FiImage2, { size: 12 }),
|
|
4753
4753
|
" Imagem"
|
|
4754
4754
|
), /* @__PURE__ */ React5.createElement(
|
|
4755
4755
|
"button",
|
|
@@ -4888,7 +4888,7 @@ ${space}${bullet} `);
|
|
|
4888
4888
|
|
|
4889
4889
|
// src/components/DescriptionDisplay.jsx
|
|
4890
4890
|
import React6, { useMemo as useMemo5, useState as useState7, useEffect as useEffect6, useRef as useRef6 } from "react";
|
|
4891
|
-
import { FiCopy as FiCopy2, FiCheck as FiCheck3, FiChevronDown as FiChevronDown3, FiChevronRight as FiChevronRight2, FiTerminal as FiTerminal2, FiCornerDownRight, FiExternalLink as FiExternalLink2, FiImage as
|
|
4891
|
+
import { FiCopy as FiCopy2, FiCheck as FiCheck3, FiChevronDown as FiChevronDown3, FiChevronRight as FiChevronRight2, FiTerminal as FiTerminal2, FiCornerDownRight, FiExternalLink as FiExternalLink2, FiImage as FiImage3, FiSave } from "react-icons/fi";
|
|
4892
4892
|
var CodeBlock2 = ({ content, isActive, onClick }) => {
|
|
4893
4893
|
const [isExpanded, setIsExpanded] = useState7(false);
|
|
4894
4894
|
const [copied, setCopied] = useState7(false);
|
|
@@ -4985,7 +4985,7 @@ var renderTextWithImages = (text, onImageClick) => {
|
|
|
4985
4985
|
},
|
|
4986
4986
|
className: "inline-flex items-center gap-1 text-emerald-400 hover:text-emerald-300 hover:underline decoration-emerald-500/50 underline-offset-2 transition-colors cursor-pointer align-baseline mx-0.5"
|
|
4987
4987
|
},
|
|
4988
|
-
/* @__PURE__ */ React6.createElement(
|
|
4988
|
+
/* @__PURE__ */ React6.createElement(FiImage3, { size: 11 }),
|
|
4989
4989
|
/* @__PURE__ */ React6.createElement("span", null, name)
|
|
4990
4990
|
);
|
|
4991
4991
|
}
|
|
@@ -9209,7 +9209,7 @@ function InSceneQuestForm({
|
|
|
9209
9209
|
|
|
9210
9210
|
// src/components/NodeDetailsPanel.jsx
|
|
9211
9211
|
import React17, { useState as useState18, useEffect as useEffect15, useRef as useRef13 } from "react";
|
|
9212
|
-
import { FiPlus as FiPlus7, FiMaximize2 as FiMaximize23, FiX as FiX6, FiCheck as FiCheck10, FiImage as
|
|
9212
|
+
import { FiPlus as FiPlus7, FiMaximize2 as FiMaximize23, FiX as FiX6, FiCheck as FiCheck10, FiImage as FiImage4, FiEdit2 as FiEdit27, FiLoader as FiLoader2, FiBookOpen as FiBookOpen3, FiSun as FiSun2, FiLink as FiLink5, FiDatabase } from "react-icons/fi";
|
|
9213
9213
|
function NodeDetailsPanel({
|
|
9214
9214
|
node,
|
|
9215
9215
|
onClose,
|
|
@@ -9753,12 +9753,16 @@ var EVENT_ICONS = {
|
|
|
9753
9753
|
function QuestTimeline({
|
|
9754
9754
|
timeline = [],
|
|
9755
9755
|
viewMembers = [],
|
|
9756
|
-
onOpenImageViewer
|
|
9756
|
+
onOpenImageViewer,
|
|
9757
|
+
onAddNote,
|
|
9758
|
+
// Nova prop para adicionar nota a uma etapa específica
|
|
9759
|
+
canEdit = true
|
|
9757
9760
|
}) {
|
|
9758
9761
|
const sortedTimeline = [...timeline].sort((a, b) => b.timestamp - a.timestamp);
|
|
9759
9762
|
const getMemberName = (userId) => {
|
|
9760
|
-
|
|
9761
|
-
|
|
9763
|
+
if (!userId) return "Sistema";
|
|
9764
|
+
const member = viewMembers.find((m) => String(m.id) === String(userId));
|
|
9765
|
+
return (member == null ? void 0 : member.name) || (member == null ? void 0 : member.email) || userId;
|
|
9762
9766
|
};
|
|
9763
9767
|
const formatDate = (timestamp) => {
|
|
9764
9768
|
const date = new Date(timestamp);
|
|
@@ -9772,11 +9776,23 @@ function QuestTimeline({
|
|
|
9772
9776
|
if (timeline.length === 0) {
|
|
9773
9777
|
return /* @__PURE__ */ React18.createElement("div", { className: "py-6 flex flex-col items-center justify-center gap-2 border border-white/5 bg-white/5 rounded-xl" }, /* @__PURE__ */ React18.createElement(FiAlertCircle, { className: "text-slate-600", size: 16 }), /* @__PURE__ */ React18.createElement("p", { className: "text-[10px] text-slate-500 font-light uppercase tracking-widest" }, "Nenhum hist\xF3rico dispon\xEDvel"));
|
|
9774
9778
|
}
|
|
9775
|
-
return /* @__PURE__ */ React18.createElement("div", { className: "space-y-4" }, /* @__PURE__ */ React18.createElement("h3", { className: "text-xs text-slate-400 font-medium uppercase tracking-wider flex items-center gap-2" }, "Hist\xF3rico (Timeline)"), /* @__PURE__ */ React18.createElement("div", { className: "relative pl-
|
|
9779
|
+
return /* @__PURE__ */ React18.createElement("div", { className: "space-y-4" }, /* @__PURE__ */ React18.createElement("h3", { className: "text-xs text-slate-400 font-medium uppercase tracking-wider flex items-center gap-2" }, "Hist\xF3rico (Timeline)"), /* @__PURE__ */ React18.createElement("div", { className: "relative pl-10 space-y-6 before:content-[''] before:absolute before:left-[21px] before:top-2 before:bottom-2 before:w-[2px] before:bg-white/5" }, sortedTimeline.map((event, index) => {
|
|
9776
9780
|
const config = EVENT_ICONS[event.type] || EVENT_ICONS.default;
|
|
9777
9781
|
const Icon = config.icon;
|
|
9778
9782
|
const actorName = getMemberName(event.actorId);
|
|
9779
|
-
return /* @__PURE__ */ React18.createElement("div", { key: index, className: "relative animate-in fade-in slide-in-from-left-2 duration-300", style: { animationDelay: `${index * 50}ms` } }, /* @__PURE__ */ React18.createElement("div", { className: `absolute -left-[
|
|
9783
|
+
return /* @__PURE__ */ React18.createElement("div", { key: event.id || index, className: "relative animate-in fade-in slide-in-from-left-2 duration-300", style: { animationDelay: `${index * 50}ms` } }, /* @__PURE__ */ React18.createElement("div", { className: `absolute -left-[35px] top-0 w-8 h-8 rounded-full ${config.bg} flex items-center justify-center ring-4 ring-slate-950 border border-white/5` }, /* @__PURE__ */ React18.createElement(Icon, { className: config.iconColor || config.color, size: 14 })), /* @__PURE__ */ React18.createElement("div", { className: "group space-y-1" }, /* @__PURE__ */ React18.createElement("div", { className: "flex items-center justify-between gap-4" }, /* @__PURE__ */ React18.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React18.createElement("span", { className: "text-xs font-semibold text-slate-200" }, actorName), canEdit && onAddNote && /* @__PURE__ */ React18.createElement(
|
|
9784
|
+
"button",
|
|
9785
|
+
{
|
|
9786
|
+
onClick: () => onAddNote(event),
|
|
9787
|
+
className: "opacity-0 group-hover:opacity-100 p-1 rounded-md hover:bg-white/5 text-slate-500 hover:text-indigo-400 transition-all",
|
|
9788
|
+
title: "Adicionar detalhe/anexo a esta etapa"
|
|
9789
|
+
},
|
|
9790
|
+
/* @__PURE__ */ React18.createElement(FiPlusCircle, { size: 12 })
|
|
9791
|
+
)), /* @__PURE__ */ React18.createElement("span", { className: "text-[10px] text-slate-500 tabular-nums" }, formatDate(event.timestamp))), /* @__PURE__ */ React18.createElement("p", { className: "text-sm text-slate-400 leading-relaxed" }, event.description), event.notes && /* @__PURE__ */ React18.createElement("div", { className: "mt-1 py-1 px-2 rounded bg-indigo-500/5 border-l-2 border-indigo-500/30" }, /* @__PURE__ */ React18.createElement("p", { className: "text-[11px] text-slate-300 italic whitespace-pre-wrap" }, event.notes)), (event.from_status || event.to_status) && /* @__PURE__ */ React18.createElement("div", { className: "flex items-center gap-1.5 py-1 px-2 rounded-md bg-white/5 border border-white/5 w-fit mt-2" }, /* @__PURE__ */ React18.createElement("span", { className: "text-[10px] text-slate-500" }, event.from_status || "?"), /* @__PURE__ */ React18.createElement(FiArrowRight, { size: 10, className: "text-slate-600" }), /* @__PURE__ */ React18.createElement("span", { className: "text-[10px] text-indigo-300 font-bold" }, event.to_status || "?")), event.metadata && Object.keys(event.metadata).length > 0 && /* @__PURE__ */ React18.createElement("div", { className: "mt-2 text-[10px] grid grid-cols-2 gap-2 p-2 bg-slate-900/50 rounded border border-white/5" }, Object.entries(event.metadata).map(([key, value]) => {
|
|
9792
|
+
const isAssigneeId = key.toLowerCase().includes("assignee_id") || key.toLowerCase().includes("respons\xE1vel") || key.toLowerCase().includes("assignee id");
|
|
9793
|
+
const displayValue = isAssigneeId && typeof value === "string" ? getMemberName(value) : typeof value === "string" ? value : JSON.stringify(value);
|
|
9794
|
+
return /* @__PURE__ */ React18.createElement("div", { key, className: "flex flex-col gap-0.5" }, /* @__PURE__ */ React18.createElement("span", { className: "text-slate-500 capitalize" }, key.replace(/_/g, " ")), /* @__PURE__ */ React18.createElement("span", { className: `${isAssigneeId ? "text-indigo-300 font-medium" : "text-slate-300"} truncate font-mono` }, displayValue));
|
|
9795
|
+
})), event.links && event.links.length > 0 && /* @__PURE__ */ React18.createElement("div", { className: "flex flex-wrap gap-2 mt-2" }, event.links.map((link, lIdx) => /* @__PURE__ */ React18.createElement(
|
|
9780
9796
|
"a",
|
|
9781
9797
|
{
|
|
9782
9798
|
key: lIdx,
|
|
@@ -9793,10 +9809,10 @@ function QuestTimeline({
|
|
|
9793
9809
|
key: iIdx,
|
|
9794
9810
|
type: "button",
|
|
9795
9811
|
onClick: () => onOpenImageViewer == null ? void 0 : onOpenImageViewer(event.images, iIdx),
|
|
9796
|
-
className: "relative w-12 h-12 rounded border border-white/10 overflow-hidden hover:border-sky-500/50 transition-colors group"
|
|
9812
|
+
className: "relative w-12 h-12 rounded border border-white/10 overflow-hidden hover:border-sky-500/50 transition-colors group/img"
|
|
9797
9813
|
},
|
|
9798
9814
|
/* @__PURE__ */ React18.createElement("img", { src: img.value, alt: img.name, className: "w-full h-full object-cover" }),
|
|
9799
|
-
/* @__PURE__ */ React18.createElement("div", { className: "absolute inset-0 bg-slate-900/40 opacity-0 group-hover:opacity-100 flex items-center justify-center transition-opacity" }, /* @__PURE__ */ React18.createElement(FiSearch6, { size: 12, className: "text-white" }))
|
|
9815
|
+
/* @__PURE__ */ React18.createElement("div", { className: "absolute inset-0 bg-slate-900/40 opacity-0 group-hover/img:opacity-100 flex items-center justify-center transition-opacity" }, /* @__PURE__ */ React18.createElement(FiSearch6, { size: 12, className: "text-white" }))
|
|
9800
9816
|
)))));
|
|
9801
9817
|
})));
|
|
9802
9818
|
}
|
|
@@ -9859,7 +9875,11 @@ function QuestDetailsPanel({
|
|
|
9859
9875
|
const [isLinkCopied, setIsLinkCopied] = useState19(false);
|
|
9860
9876
|
const [hasUnsavedChanges, setHasUnsavedChanges] = useState19(false);
|
|
9861
9877
|
const [noteText, setNoteText] = useState19("");
|
|
9878
|
+
const [noteLinks, setNoteLinks] = useState19([]);
|
|
9879
|
+
const [noteImages, setNoteImages] = useState19([]);
|
|
9862
9880
|
const [isNoteFormOpen, setIsNoteFormOpen] = useState19(false);
|
|
9881
|
+
const [editingEntryId, setEditingEntryId] = useState19(null);
|
|
9882
|
+
const [editingEntryLabel, setEditingEntryLabel] = useState19("");
|
|
9863
9883
|
const maxPanelW = typeof window !== "undefined" ? window.innerWidth * 0.92 : 1200;
|
|
9864
9884
|
const { width: panelWidth, isResizing, handlePointerDown: handleResize, setWidth } = useResizablePanel({
|
|
9865
9885
|
initialWidth: isReadMode ? 700 : 440,
|
|
@@ -9991,11 +10011,30 @@ function QuestDetailsPanel({
|
|
|
9991
10011
|
}
|
|
9992
10012
|
};
|
|
9993
10013
|
const handleAddTimelineNote = async () => {
|
|
9994
|
-
if (!noteText.trim() || isSaving) return;
|
|
10014
|
+
if (!noteText.trim() && noteLinks.length === 0 && noteImages.length === 0 || isSaving) return;
|
|
9995
10015
|
setIsSaving(true);
|
|
9996
10016
|
const actorId = (currentUser == null ? void 0 : currentUser.id) || "unknown";
|
|
9997
|
-
|
|
9998
|
-
|
|
10017
|
+
let updatedTimeline;
|
|
10018
|
+
if (editingEntryId) {
|
|
10019
|
+
updatedTimeline = timeline.map((entry) => {
|
|
10020
|
+
if (entry.id === editingEntryId) {
|
|
10021
|
+
return {
|
|
10022
|
+
...entry,
|
|
10023
|
+
notes: noteText.trim() ? entry.notes ? `${entry.notes}
|
|
10024
|
+
${noteText}` : noteText : entry.notes,
|
|
10025
|
+
links: [...entry.links || [], ...noteLinks],
|
|
10026
|
+
images: [...entry.images || [], ...noteImages]
|
|
10027
|
+
};
|
|
10028
|
+
}
|
|
10029
|
+
return entry;
|
|
10030
|
+
});
|
|
10031
|
+
} else {
|
|
10032
|
+
const newEntry = createTimelineEntry(actorId, noteText, "comment", {
|
|
10033
|
+
links: noteLinks,
|
|
10034
|
+
images: noteImages
|
|
10035
|
+
});
|
|
10036
|
+
updatedTimeline = [...timeline, newEntry];
|
|
10037
|
+
}
|
|
9999
10038
|
try {
|
|
10000
10039
|
const nodeToSave = {
|
|
10001
10040
|
...node,
|
|
@@ -10005,13 +10044,47 @@ function QuestDetailsPanel({
|
|
|
10005
10044
|
setTimeline(updatedTimeline);
|
|
10006
10045
|
onDataUpdate(nodeToSave);
|
|
10007
10046
|
setNoteText("");
|
|
10047
|
+
setNoteLinks([]);
|
|
10048
|
+
setNoteImages([]);
|
|
10008
10049
|
setIsNoteFormOpen(false);
|
|
10050
|
+
setEditingEntryId(null);
|
|
10051
|
+
setEditingEntryLabel("");
|
|
10009
10052
|
} catch (error) {
|
|
10010
10053
|
console.error("Erro ao adicionar nota:", error);
|
|
10011
10054
|
} finally {
|
|
10012
10055
|
setIsSaving(false);
|
|
10013
10056
|
}
|
|
10014
10057
|
};
|
|
10058
|
+
const handleOpenNoteForEntry = (entry) => {
|
|
10059
|
+
setEditingEntryId(entry.id);
|
|
10060
|
+
setEditingEntryLabel(entry.description);
|
|
10061
|
+
setNoteText("");
|
|
10062
|
+
setNoteLinks([]);
|
|
10063
|
+
setNoteImages([]);
|
|
10064
|
+
setIsNoteFormOpen(true);
|
|
10065
|
+
setTimeout(() => {
|
|
10066
|
+
const form = document.getElementById("quest-note-form");
|
|
10067
|
+
form == null ? void 0 : form.scrollIntoView({ behavior: "smooth", block: "center" });
|
|
10068
|
+
}, 100);
|
|
10069
|
+
};
|
|
10070
|
+
const addLinkToNote = () => {
|
|
10071
|
+
setNoteLinks([...noteLinks, { id: v4_default(), name: "", value: "" }]);
|
|
10072
|
+
};
|
|
10073
|
+
const removeLinkFromNote = (id) => {
|
|
10074
|
+
setNoteLinks(noteLinks.filter((l) => l.id !== id));
|
|
10075
|
+
};
|
|
10076
|
+
const updateLinkInNote = (id, field, val) => {
|
|
10077
|
+
setNoteLinks(noteLinks.map((l) => l.id === id ? { ...l, [field]: val } : l));
|
|
10078
|
+
};
|
|
10079
|
+
const addImageToNote = () => {
|
|
10080
|
+
setNoteImages([...noteImages, { id: v4_default(), name: "Image", value: "" }]);
|
|
10081
|
+
};
|
|
10082
|
+
const removeImageFromNote = (id) => {
|
|
10083
|
+
setNoteImages(noteImages.filter((img) => img.id !== id));
|
|
10084
|
+
};
|
|
10085
|
+
const updateImageInNote = (id, val) => {
|
|
10086
|
+
setNoteImages(noteImages.map((img) => img.id === id ? { ...img, value: val } : img));
|
|
10087
|
+
};
|
|
10015
10088
|
const handleStatusChange = (newStatus) => {
|
|
10016
10089
|
setStatus(newStatus);
|
|
10017
10090
|
const newColor = QUEST_STATUS_COLORS3[newStatus];
|
|
@@ -10355,34 +10428,78 @@ function QuestDetailsPanel({
|
|
|
10355
10428
|
"button",
|
|
10356
10429
|
{
|
|
10357
10430
|
type: "button",
|
|
10358
|
-
onClick: () =>
|
|
10431
|
+
onClick: () => {
|
|
10432
|
+
if (isNoteFormOpen && editingEntryId) {
|
|
10433
|
+
setEditingEntryId(null);
|
|
10434
|
+
setEditingEntryLabel("");
|
|
10435
|
+
setNoteText("");
|
|
10436
|
+
setNoteLinks([]);
|
|
10437
|
+
setNoteImages([]);
|
|
10438
|
+
} else {
|
|
10439
|
+
setIsNoteFormOpen(!isNoteFormOpen);
|
|
10440
|
+
setEditingEntryId(null);
|
|
10441
|
+
setEditingEntryLabel("");
|
|
10442
|
+
}
|
|
10443
|
+
},
|
|
10359
10444
|
className: "flex items-center gap-1.5 px-2 py-1 text-[10px] rounded-md bg-white/5 hover:bg-white/10 border border-white/10 transition-colors text-slate-300"
|
|
10360
10445
|
},
|
|
10361
|
-
isNoteFormOpen ? /* @__PURE__ */ React19.createElement(FiX7, { size: 12 }) : /* @__PURE__ */ React19.createElement(FiPlus8, { size: 12 }),
|
|
10362
|
-
isNoteFormOpen ? "Cancelar" : "Nova Nota"
|
|
10363
|
-
)), isNoteFormOpen && /* @__PURE__ */ React19.createElement("div", { className: "mb-6 p-4 rounded-xl bg-white/5 border border-white/5 space-y-3 animate-in fade-in slide-in-from-top-2" }, /* @__PURE__ */ React19.createElement(
|
|
10446
|
+
isNoteFormOpen && !editingEntryId ? /* @__PURE__ */ React19.createElement(FiX7, { size: 12 }) : /* @__PURE__ */ React19.createElement(FiPlus8, { size: 12 }),
|
|
10447
|
+
isNoteFormOpen && !editingEntryId ? "Cancelar" : "Nova Nota"
|
|
10448
|
+
)), isNoteFormOpen && /* @__PURE__ */ React19.createElement("div", { id: "quest-note-form", className: "mb-6 p-4 rounded-xl bg-white/5 border border-white/5 space-y-3 animate-in fade-in slide-in-from-top-2 border-l-4 border-l-indigo-500/40" }, editingEntryId && /* @__PURE__ */ React19.createElement("div", { className: "flex items-center justify-between mb-2 pb-2 border-b border-white/5" }, /* @__PURE__ */ React19.createElement("div", { className: "flex flex-col" }, /* @__PURE__ */ React19.createElement("span", { className: "text-[10px] text-indigo-400 font-bold uppercase tracking-wider" }, "Adicionando \xE0 etapa:"), /* @__PURE__ */ React19.createElement("span", { className: "text-xs text-slate-300 italic truncate max-w-[250px]" }, editingEntryLabel)), /* @__PURE__ */ React19.createElement("button", { type: "button", onClick: () => {
|
|
10449
|
+
setIsNoteFormOpen(false);
|
|
10450
|
+
setEditingEntryId(null);
|
|
10451
|
+
}, className: "text-slate-500 hover:text-white" }, /* @__PURE__ */ React19.createElement(FiX7, { size: 14 }))), /* @__PURE__ */ React19.createElement(
|
|
10364
10452
|
"textarea",
|
|
10365
10453
|
{
|
|
10366
10454
|
value: noteText,
|
|
10367
10455
|
onChange: (e) => setNoteText(e.target.value),
|
|
10368
|
-
placeholder: "Escreva uma observa\xE7\xE3o no hist\xF3rico...",
|
|
10456
|
+
placeholder: editingEntryId ? "Adicione uma observa\xE7\xE3o a esta etapa..." : "Escreva uma observa\xE7\xE3o no hist\xF3rico...",
|
|
10369
10457
|
className: "w-full bg-slate-900/50 p-3 text-sm rounded-lg border border-white/10 focus:outline-none focus:ring-1 focus:ring-indigo-500/50 min-h-[80px] resize-none"
|
|
10370
10458
|
}
|
|
10371
|
-
), /* @__PURE__ */ React19.createElement("div", { className: "flex justify-
|
|
10459
|
+
), /* @__PURE__ */ React19.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React19.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React19.createElement("span", { className: "text-[10px] text-slate-500 uppercase font-bold tracking-tight" }, "Links"), /* @__PURE__ */ React19.createElement("button", { type: "button", onClick: addLinkToNote, className: "text-indigo-400 hover:text-indigo-300 text-[10px] flex items-center gap-1 font-medium" }, /* @__PURE__ */ React19.createElement(FiPlus8, { size: 10 }), " Adicionar Link")), noteLinks.length > 0 && /* @__PURE__ */ React19.createElement("div", { className: "space-y-2" }, noteLinks.map((link) => /* @__PURE__ */ React19.createElement("div", { key: link.id, className: "flex items-center gap-2 animate-in fade-in slide-in-from-left-1" }, /* @__PURE__ */ React19.createElement(
|
|
10460
|
+
"input",
|
|
10461
|
+
{
|
|
10462
|
+
type: "text",
|
|
10463
|
+
placeholder: "T\xEDtulo",
|
|
10464
|
+
value: link.name,
|
|
10465
|
+
onChange: (e) => updateLinkInNote(link.id, "name", e.target.value),
|
|
10466
|
+
className: "w-1/3 bg-slate-950/50 border border-white/5 rounded px-2 py-1 text-[10px] focus:outline-none focus:border-indigo-500/50"
|
|
10467
|
+
}
|
|
10468
|
+
), /* @__PURE__ */ React19.createElement(
|
|
10469
|
+
"input",
|
|
10470
|
+
{
|
|
10471
|
+
type: "text",
|
|
10472
|
+
placeholder: "URL (https://...)",
|
|
10473
|
+
value: link.value,
|
|
10474
|
+
onChange: (e) => updateLinkInNote(link.id, "value", e.target.value),
|
|
10475
|
+
className: "flex-1 bg-slate-950/50 border border-white/5 rounded px-2 py-1 text-[10px] focus:outline-none focus:border-indigo-500/50"
|
|
10476
|
+
}
|
|
10477
|
+
), /* @__PURE__ */ React19.createElement("button", { type: "button", onClick: () => removeLinkFromNote(link.id), className: "text-slate-600 hover:text-red-400 transition-colors" }, /* @__PURE__ */ React19.createElement(FiX7, { size: 12 })))))), /* @__PURE__ */ React19.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React19.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React19.createElement("span", { className: "text-[10px] text-slate-500 uppercase font-bold tracking-tight" }, "Imagens (URLs)"), /* @__PURE__ */ React19.createElement("button", { type: "button", onClick: addImageToNote, className: "text-indigo-400 hover:text-indigo-300 text-[10px] flex items-center gap-1 font-medium" }, /* @__PURE__ */ React19.createElement(FiPlus8, { size: 10 }), " Adicionar Imagem")), noteImages.length > 0 && /* @__PURE__ */ React19.createElement("div", { className: "space-y-2" }, noteImages.map((img) => /* @__PURE__ */ React19.createElement("div", { key: img.id, className: "flex items-center gap-2 animate-in fade-in slide-in-from-left-1" }, /* @__PURE__ */ React19.createElement("div", { className: "flex-1 flex items-center gap-2 bg-slate-950/50 border border-white/5 rounded px-2 py-1" }, /* @__PURE__ */ React19.createElement(FiImage, { size: 10, className: "text-slate-600" }), /* @__PURE__ */ React19.createElement(
|
|
10478
|
+
"input",
|
|
10479
|
+
{
|
|
10480
|
+
type: "text",
|
|
10481
|
+
placeholder: "URL da Imagem (https://...)",
|
|
10482
|
+
value: img.value,
|
|
10483
|
+
onChange: (e) => updateImageInNote(img.id, e.target.value),
|
|
10484
|
+
className: "flex-1 bg-transparent text-[10px] focus:outline-none"
|
|
10485
|
+
}
|
|
10486
|
+
)), /* @__PURE__ */ React19.createElement("button", { type: "button", onClick: () => removeImageFromNote(img.id), className: "text-slate-600 hover:text-red-400 transition-colors" }, /* @__PURE__ */ React19.createElement(FiX7, { size: 12 })))))), /* @__PURE__ */ React19.createElement("div", { className: "flex justify-end gap-2 pt-2" }, /* @__PURE__ */ React19.createElement(
|
|
10372
10487
|
"button",
|
|
10373
10488
|
{
|
|
10374
10489
|
type: "button",
|
|
10375
10490
|
onClick: handleAddTimelineNote,
|
|
10376
|
-
disabled: !noteText.trim() || isSaving,
|
|
10491
|
+
disabled: !noteText.trim() && noteLinks.length === 0 && noteImages.length === 0 || isSaving,
|
|
10377
10492
|
className: "px-3 py-1.5 rounded-lg bg-indigo-600 hover:bg-indigo-500 text-white text-xs font-semibold transition-colors disabled:opacity-50"
|
|
10378
10493
|
},
|
|
10379
|
-
"Adicionar ao Hist\xF3rico"
|
|
10494
|
+
editingEntryId ? "Salvar nesta Etapa" : "Adicionar ao Hist\xF3rico"
|
|
10380
10495
|
))), /* @__PURE__ */ React19.createElement(
|
|
10381
10496
|
QuestTimeline,
|
|
10382
10497
|
{
|
|
10383
10498
|
timeline,
|
|
10384
10499
|
viewMembers,
|
|
10385
|
-
onOpenImageViewer
|
|
10500
|
+
onOpenImageViewer,
|
|
10501
|
+
canEdit,
|
|
10502
|
+
onAddNote: handleOpenNoteForEntry
|
|
10386
10503
|
}
|
|
10387
10504
|
)), /* @__PURE__ */ React19.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React19.createElement("label", { className: "text-xs text-slate-300" }, "Tamanho no Node (Size)"), /* @__PURE__ */ React19.createElement("div", { className: "flex items-center gap-5" }, ["small", "medium", "large"].map((s) => {
|
|
10388
10505
|
const isSelected = size === s;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lv-x-software-house/x_view",
|
|
3
|
-
"version": "1.2.5-dev.
|
|
3
|
+
"version": "1.2.5-dev.33",
|
|
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",
|