@lv-x-software-house/x_view 1.2.5-dev.49 → 1.2.5-dev.50

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.
Files changed (3) hide show
  1. package/dist/index.js +147 -127
  2. package/dist/index.mjs +147 -127
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1114,8 +1114,7 @@ function XViewSidebar({
1114
1114
  title: "Gerenciar os milestones deste cen\xE1rio"
1115
1115
  },
1116
1116
  /* @__PURE__ */ import_react2.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react2.default.createElement("circle", { cx: "12", cy: "12", r: "10" }), /* @__PURE__ */ import_react2.default.createElement("circle", { cx: "12", cy: "12", r: "6" }), /* @__PURE__ */ import_react2.default.createElement("circle", { cx: "12", cy: "12", r: "2" })),
1117
- "Gerenciar Milestones",
1118
- milestones.length > 0 && /* @__PURE__ */ import_react2.default.createElement("span", { className: "ml-1.5 px-1.5 py-0.5 rounded-full bg-indigo-500/30 text-[10px] font-bold border border-indigo-400/30" }, milestones.length)
1117
+ "Gerenciar Milestones"
1119
1118
  ))), /* @__PURE__ */ import_react2.default.createElement("div", { className: "px-4 py-3 border-t border-white/10 bg-slate-900/30" }, /* @__PURE__ */ import_react2.default.createElement("section", { className: "space-y-2" }, /* @__PURE__ */ import_react2.default.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ import_react2.default.createElement("p", { className: "text-[11px] uppercase tracking-wider text-slate-400" }, "Navega\xE7\xE3o")), ability.can("update", "Scene") && /* @__PURE__ */ import_react2.default.createElement(
1120
1119
  "button",
1121
1120
  {
@@ -9491,10 +9490,10 @@ function InSceneQuestForm({
9491
9490
  onUpdateMilestones = () => {
9492
9491
  }
9493
9492
  }) {
9494
- var _a, _b, _c;
9493
+ var _a, _b;
9495
9494
  const [name, setName] = (0, import_react17.useState)("");
9496
9495
  const [assigneeId, setAssigneeId] = (0, import_react17.useState)("");
9497
- const [milestoneId, setMilestoneId] = (0, import_react17.useState)("");
9496
+ const [milestoneIds, setMilestoneIds] = (0, import_react17.useState)([]);
9498
9497
  const [types, setTypes] = (0, import_react17.useState)(["quest"]);
9499
9498
  const [typeInput, setTypeInput] = (0, import_react17.useState)("");
9500
9499
  const [status, setStatus] = (0, import_react17.useState)("Backlog");
@@ -9516,31 +9515,48 @@ function InSceneQuestForm({
9516
9515
  const [customProps, setCustomProps] = (0, import_react17.useState)([]);
9517
9516
  const [isDescriptionModalOpen, setIsDescriptionModalOpen] = (0, import_react17.useState)(false);
9518
9517
  const propsEndRef = (0, import_react17.useRef)(null);
9519
- const [isMilestoneDropdownOpen, setIsMilestoneDropdownOpen] = (0, import_react17.useState)(false);
9520
- const [milestoneSearchQuery, setMilestoneSearchQuery] = (0, import_react17.useState)("");
9518
+ const [milestoneInput, setMilestoneInput] = (0, import_react17.useState)("");
9519
+ const [showMilestoneSuggestions, setShowMilestoneSuggestions] = (0, import_react17.useState)(false);
9521
9520
  const activeMilestones = import_react17.default.useMemo(
9522
9521
  () => (milestones || []).filter((ms) => ms.status === "active"),
9523
9522
  [milestones]
9524
9523
  );
9525
9524
  const filteredMilestones = import_react17.default.useMemo(() => {
9526
- if (!milestoneSearchQuery.trim()) return activeMilestones;
9525
+ const search = milestoneInput.toLowerCase().trim();
9527
9526
  return activeMilestones.filter(
9528
- (ms) => ms.name.toLowerCase().includes(milestoneSearchQuery.toLowerCase())
9527
+ (ms) => ms.name.toLowerCase().includes(search) && !milestoneIds.includes(ms.id)
9529
9528
  );
9530
- }, [activeMilestones, milestoneSearchQuery]);
9531
- const handleSelectMilestone = (id) => {
9532
- setMilestoneId(id);
9533
- setIsMilestoneDropdownOpen(false);
9534
- setMilestoneSearchQuery("");
9529
+ }, [activeMilestones, milestoneInput, milestoneIds]);
9530
+ const handleAddMilestone = async (ms) => {
9531
+ let id = ms.id;
9532
+ if (!id) {
9533
+ const name2 = ms.name.trim();
9534
+ if (!name2) return;
9535
+ const existing = activeMilestones.find((m) => m.name.toLowerCase() === name2.toLowerCase());
9536
+ if (existing) {
9537
+ id = existing.id;
9538
+ } else {
9539
+ id = `ms_${Date.now()}`;
9540
+ const newMs = { id, name: name2, status: "active" };
9541
+ await onUpdateMilestones([...milestones, newMs]);
9542
+ }
9543
+ }
9544
+ if (id && !milestoneIds.includes(id)) {
9545
+ setMilestoneIds([...milestoneIds, id]);
9546
+ setMilestoneInput("");
9547
+ setShowMilestoneSuggestions(false);
9548
+ }
9535
9549
  };
9536
- const handleCreateMilestone = async (name2) => {
9537
- if (!name2.trim()) return;
9538
- const newId = `ms_${Date.now()}`;
9539
- const newMs = { id: newId, name: name2.trim(), status: "active" };
9540
- await onUpdateMilestones([...milestones, newMs]);
9541
- setMilestoneId(newId);
9542
- setIsMilestoneDropdownOpen(false);
9543
- setMilestoneSearchQuery("");
9550
+ const handleRemoveMilestone = (idToRemove) => {
9551
+ setMilestoneIds(milestoneIds.filter((id) => id !== idToRemove));
9552
+ };
9553
+ const handleMilestoneInputKeyDown = (e) => {
9554
+ if (e.key === "Enter" && milestoneInput.trim()) {
9555
+ e.preventDefault();
9556
+ handleAddMilestone({ name: milestoneInput });
9557
+ } else if (e.key === "Backspace" && milestoneInput === "" && milestoneIds.length > 0) {
9558
+ handleRemoveMilestone(milestoneIds[milestoneIds.length - 1]);
9559
+ }
9544
9560
  };
9545
9561
  const standardizedName = `${viewName} - ${questCounter} - \xBB ${name || "Nova Quest"}`;
9546
9562
  const handleAddProp = () => {
@@ -9609,7 +9625,7 @@ function InSceneQuestForm({
9609
9625
  timeline: initialTimeline,
9610
9626
  Date: questDate ? { ...questDate, confirmed: true } : null,
9611
9627
  recurrence_config: recurrenceConfig,
9612
- milestone_id: milestoneId || null,
9628
+ milestone_ids: milestoneIds,
9613
9629
  ...additionalData
9614
9630
  });
9615
9631
  };
@@ -9713,71 +9729,58 @@ function InSceneQuestForm({
9713
9729
  }
9714
9730
  ),
9715
9731
  s
9716
- )))))), /* @__PURE__ */ import_react17.default.createElement("div", { className: "space-y-1.5 relative mt-2" }, /* @__PURE__ */ import_react17.default.createElement("label", { className: "text-xs text-slate-300 font-medium uppercase tracking-wider" }, "Milestone"), /* @__PURE__ */ import_react17.default.createElement("div", { className: "relative" }, /* @__PURE__ */ import_react17.default.createElement(
9717
- "button",
9718
- {
9719
- type: "button",
9720
- onClick: () => setIsMilestoneDropdownOpen(!isMilestoneDropdownOpen),
9721
- className: "w-full bg-slate-800/70 p-2.5 text-sm rounded-lg border border-white/10 hover:border-white/20 focus:outline-none focus:ring-2 focus:ring-indigo-400/60 transition-colors flex items-center justify-between"
9722
- },
9723
- /* @__PURE__ */ import_react17.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ import_react17.default.createElement(import_fi15.FiTarget, { className: "text-slate-400", size: 14 }), /* @__PURE__ */ import_react17.default.createElement("span", { className: "text-slate-200 font-medium" }, ((_a = (milestones || []).find((m) => m.id === milestoneId)) == null ? void 0 : _a.name) || "Nenhum")),
9724
- /* @__PURE__ */ import_react17.default.createElement(
9725
- import_fi15.FiChevronDown,
9726
- {
9727
- className: `text-slate-400 transition-transform duration-200 ${isMilestoneDropdownOpen ? "rotate-180" : ""}`
9728
- }
9729
- )
9730
- ), isMilestoneDropdownOpen && /* @__PURE__ */ import_react17.default.createElement(import_react17.default.Fragment, null, /* @__PURE__ */ import_react17.default.createElement(
9731
- "div",
9732
- {
9733
- className: "fixed inset-0 z-40",
9734
- onClick: () => {
9735
- setIsMilestoneDropdownOpen(false);
9736
- setMilestoneSearchQuery("");
9737
- }
9738
- }
9739
- ), /* @__PURE__ */ import_react17.default.createElement("div", { className: "absolute top-full left-0 mt-1.5 w-full bg-slate-900 border border-white/10 rounded-lg shadow-[0_8px_30px_rgba(0,0,0,0.5)] z-50 overflow-hidden flex flex-col" }, /* @__PURE__ */ import_react17.default.createElement("div", { className: "p-2 border-b border-white/5 bg-white/5 flex items-center gap-2" }, /* @__PURE__ */ import_react17.default.createElement(import_fi15.FiSearch, { className: "text-slate-500", size: 14 }), /* @__PURE__ */ import_react17.default.createElement(
9732
+ )))))), /* @__PURE__ */ import_react17.default.createElement("div", { className: "space-y-1.5 relative mt-2" }, /* @__PURE__ */ import_react17.default.createElement("label", { className: "text-xs text-slate-300 font-medium uppercase tracking-wider" }, "Milestones"), /* @__PURE__ */ import_react17.default.createElement("div", { className: `relative w-full bg-slate-800/70 p-1.5 min-h-[42px] flex flex-wrap gap-1.5 rounded-lg border border-white/10 focus-within:ring-2 focus-within:ring-indigo-400/60 transition-all cursor-text` }, milestoneIds.map((id) => {
9733
+ const ms = (milestones || []).find((m) => m.id === id);
9734
+ if (!ms) return null;
9735
+ return /* @__PURE__ */ import_react17.default.createElement("span", { key: id, className: "flex items-center gap-1 px-1.5 py-0.5 rounded-md text-xs font-medium border bg-sky-500/20 text-sky-200 border-sky-500/30" }, ms.name, /* @__PURE__ */ import_react17.default.createElement("button", { type: "button", onClick: () => handleRemoveMilestone(id), className: "hover:text-white transition-colors" }, /* @__PURE__ */ import_react17.default.createElement(import_fi15.FiX, { size: 12 })));
9736
+ }), /* @__PURE__ */ import_react17.default.createElement(
9740
9737
  "input",
9741
9738
  {
9742
9739
  type: "text",
9743
- autoFocus: true,
9744
- placeholder: "Buscar ou criar milestone...",
9745
- value: milestoneSearchQuery,
9746
- onChange: (e) => setMilestoneSearchQuery(e.target.value),
9747
- className: "bg-transparent border-none outline-none text-xs text-white placeholder-slate-500 w-full",
9748
- onClick: (e) => e.stopPropagation()
9740
+ value: milestoneInput,
9741
+ onChange: (e) => {
9742
+ setMilestoneInput(e.target.value);
9743
+ setShowMilestoneSuggestions(true);
9744
+ },
9745
+ onKeyDown: handleMilestoneInputKeyDown,
9746
+ onFocus: () => setShowMilestoneSuggestions(true),
9747
+ onBlur: () => {
9748
+ setTimeout(() => setShowMilestoneSuggestions(false), 200);
9749
+ },
9750
+ className: "flex-1 bg-transparent text-sm min-w-[80px] focus:outline-none text-slate-200",
9751
+ placeholder: milestoneIds.length === 0 ? "Adicionar milestone..." : "",
9752
+ autoComplete: "off"
9749
9753
  }
9750
- )), /* @__PURE__ */ import_react17.default.createElement("ul", { className: "max-h-48 overflow-y-auto custom-scrollbar" }, /* @__PURE__ */ import_react17.default.createElement(
9751
- "li",
9752
- {
9753
- onClick: () => handleSelectMilestone(""),
9754
- className: `px-3 py-2.5 text-sm cursor-pointer transition-colors flex items-center gap-2 ${!milestoneId ? "bg-indigo-500/20 text-white" : "text-slate-300 hover:bg-white/5 hover:text-white"}`
9755
- },
9756
- "Nenhum"
9757
- ), filteredMilestones.map((ms) => /* @__PURE__ */ import_react17.default.createElement(
9754
+ ), showMilestoneSuggestions && filteredMilestones.length > 0 && /* @__PURE__ */ import_react17.default.createElement("ul", { className: "custom-scrollbar absolute top-full left-0 z-[100] w-full mt-1 max-h-40 overflow-y-auto rounded-lg bg-slate-800 border border-white/10 shadow-lg" }, filteredMilestones.map((ms) => /* @__PURE__ */ import_react17.default.createElement(
9758
9755
  "li",
9759
9756
  {
9760
9757
  key: ms.id,
9761
- onClick: () => handleSelectMilestone(ms.id),
9762
- className: `px-3 py-2.5 text-sm cursor-pointer transition-colors flex items-center gap-2 ${milestoneId === ms.id ? "bg-indigo-500/20 text-white" : "text-slate-300 hover:bg-white/5 hover:text-white"}`
9758
+ className: "px-3 py-2 text-sm text-slate-200 cursor-pointer hover:bg-indigo-600/50",
9759
+ onMouseDown: (e) => {
9760
+ e.preventDefault();
9761
+ handleAddMilestone(ms);
9762
+ }
9763
9763
  },
9764
9764
  ms.name
9765
- )), milestoneSearchQuery.trim() && !filteredMilestones.some((ms) => ms.name.toLowerCase() === milestoneSearchQuery.toLowerCase().trim()) && /* @__PURE__ */ import_react17.default.createElement(
9765
+ ))), showMilestoneSuggestions && milestoneInput.trim() && !filteredMilestones.some((m) => m.name.toLowerCase() === milestoneInput.toLowerCase().trim()) && /* @__PURE__ */ import_react17.default.createElement("ul", { className: "custom-scrollbar absolute top-full left-0 z-[100] w-full mt-1 rounded-lg bg-slate-800 border border-white/10 shadow-lg" }, /* @__PURE__ */ import_react17.default.createElement(
9766
9766
  "li",
9767
9767
  {
9768
- onClick: () => handleCreateMilestone(milestoneSearchQuery),
9769
- className: "px-3 py-3 text-sm cursor-pointer bg-indigo-600/20 text-indigo-200 hover:bg-indigo-600/40 transition-colors flex flex-col gap-0.5"
9768
+ className: "px-3 py-3 text-sm cursor-pointer hover:bg-indigo-600/50 flex flex-col gap-0.5",
9769
+ onMouseDown: (e) => {
9770
+ e.preventDefault();
9771
+ handleAddMilestone({ name: milestoneInput });
9772
+ }
9770
9773
  },
9771
- /* @__PURE__ */ import_react17.default.createElement("span", { className: "text-[10px] uppercase font-bold opacity-60" }, "Criar Novo Milestone"),
9772
- /* @__PURE__ */ import_react17.default.createElement("span", { className: "font-medium" }, '"', milestoneSearchQuery, '"')
9773
- )))))), /* @__PURE__ */ import_react17.default.createElement("div", { className: "space-y-1.5 relative mt-2" }, /* @__PURE__ */ import_react17.default.createElement("label", { className: "text-xs text-slate-300 font-medium uppercase tracking-wider" }, "Assignee (Respons\xE1vel)"), /* @__PURE__ */ import_react17.default.createElement("div", { className: "relative" }, /* @__PURE__ */ import_react17.default.createElement(
9774
+ /* @__PURE__ */ import_react17.default.createElement("span", { className: "text-[10px] uppercase font-bold text-slate-500" }, "Criar novo milestone"),
9775
+ /* @__PURE__ */ import_react17.default.createElement("span", { className: "text-white" }, '"', milestoneInput, '"')
9776
+ )))), /* @__PURE__ */ import_react17.default.createElement("div", { className: "space-y-1.5 relative mt-2" }, /* @__PURE__ */ import_react17.default.createElement("label", { className: "text-xs text-slate-300 font-medium uppercase tracking-wider" }, "Assignee (Respons\xE1vel)"), /* @__PURE__ */ import_react17.default.createElement("div", { className: "relative" }, /* @__PURE__ */ import_react17.default.createElement(
9774
9777
  "button",
9775
9778
  {
9776
9779
  type: "button",
9777
9780
  onClick: () => setIsAssigneeDropdownOpen(!isAssigneeDropdownOpen),
9778
9781
  className: "w-full bg-slate-800/70 p-2.5 text-sm rounded-lg border border-white/10 hover:border-white/20 focus:outline-none focus:ring-2 focus:ring-indigo-400/60 transition-colors flex items-center justify-between"
9779
9782
  },
9780
- /* @__PURE__ */ import_react17.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ import_react17.default.createElement(import_fi15.FiUser, { className: "text-slate-400", size: 14 }), /* @__PURE__ */ import_react17.default.createElement("span", { className: "text-slate-200 font-medium" }, ((_b = viewMembers.find((m) => m.id === assigneeId)) == null ? void 0 : _b.name) || ((_c = viewMembers.find((m) => m.id === assigneeId)) == null ? void 0 : _c.email) || "Nenhum")),
9783
+ /* @__PURE__ */ import_react17.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ import_react17.default.createElement(import_fi15.FiUser, { className: "text-slate-400", size: 14 }), /* @__PURE__ */ import_react17.default.createElement("span", { className: "text-slate-200 font-medium" }, ((_a = viewMembers.find((m) => m.id === assigneeId)) == null ? void 0 : _a.name) || ((_b = viewMembers.find((m) => m.id === assigneeId)) == null ? void 0 : _b.email) || "Nenhum")),
9781
9784
  /* @__PURE__ */ import_react17.default.createElement(
9782
9785
  import_fi15.FiChevronDown,
9783
9786
  {
@@ -10754,7 +10757,7 @@ function QuestDetailsPanel({
10754
10757
  onUpdateMilestones = () => {
10755
10758
  }
10756
10759
  }) {
10757
- var _a, _b, _c;
10760
+ var _a, _b;
10758
10761
  const initialRawTitle = (node == null ? void 0 : node.raw_title) || (((_a = node == null ? void 0 : node.name) == null ? void 0 : _a.includes(" - \xBB ")) ? node.name.split(" - \xBB ")[1] : node == null ? void 0 : node.name) || "";
10759
10762
  const [rawTitle, setRawTitle] = (0, import_react20.useState)(initialRawTitle);
10760
10763
  const prefixParts = ((node == null ? void 0 : node.name) || "").split(" - \xBB ");
@@ -10767,7 +10770,7 @@ function QuestDetailsPanel({
10767
10770
  const [assigneeId, setAssigneeId] = (0, import_react20.useState)((node == null ? void 0 : node.assignee_id) || "");
10768
10771
  const [description, setDescription] = (0, import_react20.useState)((node == null ? void 0 : node.description) ?? "");
10769
10772
  const [intensity, setIntensity] = (0, import_react20.useState)((node == null ? void 0 : node.intensity) !== void 0 ? node.intensity : 0);
10770
- const [milestoneId, setMilestoneId] = (0, import_react20.useState)((node == null ? void 0 : node.milestone_id) || "");
10773
+ const [milestoneIds, setMilestoneIds] = (0, import_react20.useState)((node == null ? void 0 : node.milestone_ids) || []);
10771
10774
  const [isStatusDropdownOpen, setIsStatusDropdownOpen] = (0, import_react20.useState)(false);
10772
10775
  const [isAssigneeDropdownOpen, setIsAssigneeDropdownOpen] = (0, import_react20.useState)(false);
10773
10776
  const [assigneeSearchQuery, setAssigneeSearchQuery] = (0, import_react20.useState)("");
@@ -10805,35 +10808,51 @@ function QuestDetailsPanel({
10805
10808
  minWidth: 320,
10806
10809
  maxWidth: maxPanelW
10807
10810
  });
10808
- const [isMilestoneDropdownOpen, setIsMilestoneDropdownOpen] = (0, import_react20.useState)(false);
10809
- const [milestoneSearchQuery, setMilestoneSearchQuery] = (0, import_react20.useState)("");
10811
+ const [milestoneInput, setMilestoneInput] = (0, import_react20.useState)("");
10812
+ const [showMilestoneSuggestions, setShowMilestoneSuggestions] = (0, import_react20.useState)(false);
10810
10813
  const activeMilestones = import_react20.default.useMemo(
10811
10814
  () => (milestones || []).filter((ms) => ms.status === "active"),
10812
10815
  [milestones]
10813
10816
  );
10814
10817
  const filteredMilestones = import_react20.default.useMemo(() => {
10815
- const search = milestoneSearchQuery.toLowerCase().trim();
10816
- if (!search) return activeMilestones;
10818
+ const search = milestoneInput.toLowerCase().trim();
10817
10819
  return activeMilestones.filter(
10818
- (ms) => ms.name.toLowerCase().includes(search)
10820
+ (ms) => ms.name.toLowerCase().includes(search) && !milestoneIds.includes(ms.id)
10819
10821
  );
10820
- }, [activeMilestones, milestoneSearchQuery]);
10821
- const handleSelectMilestone = (id) => {
10822
- setMilestoneId(id);
10823
- setIsMilestoneDropdownOpen(false);
10824
- setMilestoneSearchQuery("");
10825
- setHasUnsavedChanges(true);
10822
+ }, [activeMilestones, milestoneInput, milestoneIds]);
10823
+ const handleAddMilestone = async (ms) => {
10824
+ let id = ms.id;
10825
+ if (!id) {
10826
+ const name = ms.name.trim();
10827
+ if (!name) return;
10828
+ const existing = activeMilestones.find((m) => m.name.toLowerCase() === name.toLowerCase());
10829
+ if (existing) {
10830
+ id = existing.id;
10831
+ } else {
10832
+ id = `ms_${Date.now()}`;
10833
+ const newMs = { id, name, status: "active" };
10834
+ await onUpdateMilestones([...milestones, newMs]);
10835
+ }
10836
+ }
10837
+ if (id && !milestoneIds.includes(id)) {
10838
+ setMilestoneIds([...milestoneIds, id]);
10839
+ setMilestoneInput("");
10840
+ setShowMilestoneSuggestions(false);
10841
+ setHasUnsavedChanges(true);
10842
+ }
10826
10843
  };
10827
- const handleCreateMilestone = async (name) => {
10828
- if (!name.trim()) return;
10829
- const newId = `ms_${Date.now()}`;
10830
- const newMs = { id: newId, name: name.trim(), status: "active" };
10831
- await onUpdateMilestones([...milestones, newMs]);
10832
- setMilestoneId(newId);
10833
- setIsMilestoneDropdownOpen(false);
10834
- setMilestoneSearchQuery("");
10844
+ const handleRemoveMilestone = (idToRemove) => {
10845
+ setMilestoneIds(milestoneIds.filter((id) => id !== idToRemove));
10835
10846
  setHasUnsavedChanges(true);
10836
10847
  };
10848
+ const handleMilestoneInputKeyDown = (e) => {
10849
+ if (e.key === "Enter" && milestoneInput.trim()) {
10850
+ e.preventDefault();
10851
+ handleAddMilestone({ name: milestoneInput });
10852
+ } else if (e.key === "Backspace" && milestoneInput === "" && milestoneIds.length > 0) {
10853
+ handleRemoveMilestone(milestoneIds[milestoneIds.length - 1]);
10854
+ }
10855
+ };
10837
10856
  (0, import_react20.useEffect)(() => {
10838
10857
  setWidth(isReadMode ? 700 : 440);
10839
10858
  }, [isReadMode, setWidth]);
@@ -10859,7 +10878,7 @@ function QuestDetailsPanel({
10859
10878
  setReturnAssigneeId("");
10860
10879
  setDescription((node == null ? void 0 : node.description) ?? "");
10861
10880
  setIntensity((node == null ? void 0 : node.intensity) !== void 0 ? node.intensity : 0);
10862
- setMilestoneId((node == null ? void 0 : node.milestone_id) || "");
10881
+ setMilestoneIds((node == null ? void 0 : node.milestone_ids) || []);
10863
10882
  setExistingSections((node == null ? void 0 : node.description_sections) || []);
10864
10883
  setCustomProps(extractCustomPropsFromNode(node || {}));
10865
10884
  setReviewStack((node == null ? void 0 : node.reviewStack) || []);
@@ -10872,7 +10891,6 @@ function QuestDetailsPanel({
10872
10891
  custom_date: "",
10873
10892
  next_assignee_id: ""
10874
10893
  });
10875
- setMilestoneId((node == null ? void 0 : node.milestone_id) || "");
10876
10894
  setHasUnsavedChanges(false);
10877
10895
  }
10878
10896
  }, [node]);
@@ -11172,7 +11190,7 @@ ${noteText}` : noteText : entry.notes,
11172
11190
  timeline: currentTimeline,
11173
11191
  ...extrasObj,
11174
11192
  version_node: node.version_node,
11175
- milestone_id: milestoneId || null
11193
+ milestone_ids: milestoneIds
11176
11194
  };
11177
11195
  await onSave(dataToSave, keepOpen);
11178
11196
  onDataUpdate(dataToSave);
@@ -11374,51 +11392,53 @@ ${noteText}` : noteText : entry.notes,
11374
11392
  maxLength: "10",
11375
11393
  className: "flex-1 bg-slate-800/70 p-2 text-xs rounded-lg border border-white/10 focus:outline-none focus:ring-1 focus:ring-indigo-400/60"
11376
11394
  }
11377
- ))))), /* @__PURE__ */ import_react20.default.createElement("div", { className: "space-y-1.5 relative mt-2" }, /* @__PURE__ */ import_react20.default.createElement("label", { className: "text-xs text-slate-300" }, "Milestone"), /* @__PURE__ */ import_react20.default.createElement("div", { className: "relative" }, /* @__PURE__ */ import_react20.default.createElement(
11378
- "button",
11379
- {
11380
- type: "button",
11381
- onClick: () => canEdit && setIsMilestoneDropdownOpen(!isMilestoneDropdownOpen),
11382
- disabled: !canEdit,
11383
- className: `w-full bg-slate-800/70 p-2.5 text-sm rounded-lg border border-white/10 transition-colors flex items-center justify-between ${canEdit ? "hover:border-white/20 focus:ring-2 focus:ring-indigo-400/60 cursor-pointer" : "cursor-default opacity-80"}`
11384
- },
11385
- /* @__PURE__ */ import_react20.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ import_react20.default.createElement(import_fi18.FiTarget, { className: "text-slate-400", size: 14 }), /* @__PURE__ */ import_react20.default.createElement("span", { className: "text-slate-200 font-medium" }, ((_b = (milestones || []).find((m) => m.id === milestoneId)) == null ? void 0 : _b.name) || "Nenhum")),
11386
- canEdit && /* @__PURE__ */ import_react20.default.createElement(import_fi18.FiChevronDown, { className: `text-slate-400 transition-transform duration-200 ${isMilestoneDropdownOpen ? "rotate-180" : ""}` })
11387
- ), isMilestoneDropdownOpen && canEdit && /* @__PURE__ */ import_react20.default.createElement(import_react20.default.Fragment, null, /* @__PURE__ */ import_react20.default.createElement("div", { className: "fixed inset-0 z-40", onClick: () => setIsMilestoneDropdownOpen(false) }), /* @__PURE__ */ import_react20.default.createElement("div", { className: "absolute top-full left-0 mt-1.5 w-full bg-slate-900 border border-white/10 rounded-lg shadow-[0_8px_30px_rgba(0,0,0,0.5)] z-50 overflow-hidden flex flex-col" }, /* @__PURE__ */ import_react20.default.createElement("div", { className: "p-2 border-b border-white/5 bg-white/5 flex items-center gap-2" }, /* @__PURE__ */ import_react20.default.createElement(import_fi18.FiSearch, { className: "text-slate-500", size: 14 }), /* @__PURE__ */ import_react20.default.createElement(
11395
+ ))))), /* @__PURE__ */ import_react20.default.createElement("div", { className: "space-y-1.5 relative mt-2" }, /* @__PURE__ */ import_react20.default.createElement("label", { className: "text-xs text-slate-300" }, "Milestones"), /* @__PURE__ */ import_react20.default.createElement("div", { className: `relative w-full bg-slate-800/70 p-1.5 min-h-[42px] flex flex-wrap gap-1.5 rounded-lg border border-white/10 ${canEdit ? "focus-within:ring-2 focus-within:ring-indigo-400/60" : ""} transition-all` }, milestoneIds.map((id) => {
11396
+ const ms = (milestones || []).find((m) => m.id === id);
11397
+ if (!ms) return null;
11398
+ return /* @__PURE__ */ import_react20.default.createElement("span", { key: id, className: "flex items-center gap-1 px-1.5 py-0.5 rounded-md text-xs font-medium border bg-sky-500/20 text-sky-200 border-sky-500/30" }, ms.name, canEdit && /* @__PURE__ */ import_react20.default.createElement("button", { type: "button", onClick: () => handleRemoveMilestone(id), className: "hover:text-white transition-colors" }, /* @__PURE__ */ import_react20.default.createElement(import_fi18.FiX, { size: 12 })));
11399
+ }), canEdit && /* @__PURE__ */ import_react20.default.createElement(
11388
11400
  "input",
11389
11401
  {
11390
11402
  type: "text",
11391
- autoFocus: true,
11392
- placeholder: "Buscar ou criar milestone...",
11393
- value: milestoneSearchQuery,
11394
- onChange: (e) => setMilestoneSearchQuery(e.target.value),
11395
- className: "bg-transparent border-none outline-none text-xs text-white placeholder-slate-500 w-full",
11396
- onClick: (e) => e.stopPropagation()
11403
+ value: milestoneInput,
11404
+ onChange: (e) => {
11405
+ setMilestoneInput(e.target.value);
11406
+ setShowMilestoneSuggestions(true);
11407
+ },
11408
+ onKeyDown: handleMilestoneInputKeyDown,
11409
+ onFocus: () => setShowMilestoneSuggestions(true),
11410
+ onBlur: () => {
11411
+ if (milestoneInput.trim()) {
11412
+ }
11413
+ setTimeout(() => setShowMilestoneSuggestions(false), 200);
11414
+ },
11415
+ className: "flex-1 bg-transparent text-sm min-w-[80px] focus:outline-none text-slate-200",
11416
+ placeholder: milestoneIds.length === 0 ? "Adicionar milestone..." : "",
11417
+ autoComplete: "off"
11397
11418
  }
11398
- )), /* @__PURE__ */ import_react20.default.createElement("ul", { className: "max-h-48 overflow-y-auto custom-scrollbar" }, /* @__PURE__ */ import_react20.default.createElement(
11399
- "li",
11400
- {
11401
- onClick: () => handleSelectMilestone(""),
11402
- className: `px-3 py-2.5 text-sm cursor-pointer transition-colors flex items-center gap-2 ${!milestoneId ? "bg-indigo-500/20 text-white" : "text-slate-300 hover:bg-white/5 hover:text-white"}`
11403
- },
11404
- "Nenhum"
11405
- ), filteredMilestones.map((ms) => /* @__PURE__ */ import_react20.default.createElement(
11419
+ ), canEdit && showMilestoneSuggestions && filteredMilestones.length > 0 && /* @__PURE__ */ import_react20.default.createElement("ul", { className: "custom-scrollbar absolute top-full left-0 z-[100] w-full mt-1 max-h-40 overflow-y-auto rounded-lg bg-slate-800 border border-white/10 shadow-lg" }, filteredMilestones.map((ms) => /* @__PURE__ */ import_react20.default.createElement(
11406
11420
  "li",
11407
11421
  {
11408
11422
  key: ms.id,
11409
- onClick: () => handleSelectMilestone(ms.id),
11410
- className: `px-3 py-2.5 text-sm cursor-pointer transition-colors flex items-center gap-2 ${milestoneId === ms.id ? "bg-indigo-500/20 text-white" : "text-slate-300 hover:bg-white/5 hover:text-white"}`
11423
+ className: "px-3 py-2 text-sm text-slate-200 cursor-pointer hover:bg-indigo-600/50",
11424
+ onMouseDown: (e) => {
11425
+ e.preventDefault();
11426
+ handleAddMilestone(ms);
11427
+ }
11411
11428
  },
11412
11429
  ms.name
11413
- )), milestoneSearchQuery.trim() && !filteredMilestones.some((ms) => ms.name.toLowerCase() === milestoneSearchQuery.toLowerCase().trim()) && /* @__PURE__ */ import_react20.default.createElement(
11430
+ ))), canEdit && showMilestoneSuggestions && milestoneInput.trim() && !filteredMilestones.some((m) => m.name.toLowerCase() === milestoneInput.toLowerCase().trim()) && /* @__PURE__ */ import_react20.default.createElement("ul", { className: "custom-scrollbar absolute top-full left-0 z-[100] w-full mt-1 rounded-lg bg-slate-800 border border-white/10 shadow-lg" }, /* @__PURE__ */ import_react20.default.createElement(
11414
11431
  "li",
11415
11432
  {
11416
- onClick: () => handleCreateMilestone(milestoneSearchQuery),
11417
- className: "px-3 py-3 text-sm cursor-pointer bg-indigo-600/20 text-indigo-200 hover:bg-indigo-600/40 transition-colors flex flex-col gap-0.5"
11433
+ className: "px-3 py-3 text-sm cursor-pointer hover:bg-indigo-600/50 flex flex-col gap-0.5",
11434
+ onMouseDown: (e) => {
11435
+ e.preventDefault();
11436
+ handleAddMilestone({ name: milestoneInput });
11437
+ }
11418
11438
  },
11419
- /* @__PURE__ */ import_react20.default.createElement("span", { className: "text-[10px] uppercase font-bold opacity-60" }, "Criar Novo Milestone"),
11420
- /* @__PURE__ */ import_react20.default.createElement("span", { className: "font-medium" }, '"', milestoneSearchQuery, '"')
11421
- )))))), /* @__PURE__ */ import_react20.default.createElement("div", { className: "space-y-1.5 relative mt-2" }, /* @__PURE__ */ import_react20.default.createElement("label", { className: "text-xs text-slate-300" }, "Status da Quest"), /* @__PURE__ */ import_react20.default.createElement("div", { className: "relative" }, /* @__PURE__ */ import_react20.default.createElement(
11439
+ /* @__PURE__ */ import_react20.default.createElement("span", { className: "text-[10px] uppercase font-bold text-slate-500" }, "Criar novo milestone"),
11440
+ /* @__PURE__ */ import_react20.default.createElement("span", { className: "text-white" }, '"', milestoneInput, '"')
11441
+ )))), /* @__PURE__ */ import_react20.default.createElement("div", { className: "space-y-1.5 relative mt-2" }, /* @__PURE__ */ import_react20.default.createElement("label", { className: "text-xs text-slate-300" }, "Status da Quest"), /* @__PURE__ */ import_react20.default.createElement("div", { className: "relative" }, /* @__PURE__ */ import_react20.default.createElement(
11422
11442
  "button",
11423
11443
  {
11424
11444
  type: "button",
@@ -11604,7 +11624,7 @@ ${noteText}` : noteText : entry.notes,
11604
11624
  onClick: () => setIsReturnDropdownOpen(!isReturnDropdownOpen),
11605
11625
  className: "w-full bg-slate-800/80 p-2 text-xs rounded-lg border border-white/10 hover:border-white/20 focus:outline-none focus:ring-1 focus:ring-purple-400/50 transition-colors flex items-center justify-between"
11606
11626
  },
11607
- /* @__PURE__ */ import_react20.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ import_react20.default.createElement(import_fi18.FiUser, { className: "text-slate-400", size: 12 }), /* @__PURE__ */ import_react20.default.createElement("span", { className: "text-slate-200 font-medium" }, ((_c = viewMembers.find((m) => String(m.id) === String(returnAssigneeId))) == null ? void 0 : _c.name) || "Selecionar respons\xE1vel...")),
11627
+ /* @__PURE__ */ import_react20.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ import_react20.default.createElement(import_fi18.FiUser, { className: "text-slate-400", size: 12 }), /* @__PURE__ */ import_react20.default.createElement("span", { className: "text-slate-200 font-medium" }, ((_b = viewMembers.find((m) => String(m.id) === String(returnAssigneeId))) == null ? void 0 : _b.name) || "Selecionar respons\xE1vel...")),
11608
11628
  /* @__PURE__ */ import_react20.default.createElement(import_fi18.FiChevronDown, { className: `text-slate-400 transition-transform duration-200 ${isReturnDropdownOpen ? "rotate-180" : ""}`, size: 14 })
11609
11629
  ), isReturnDropdownOpen && /* @__PURE__ */ import_react20.default.createElement(import_react20.default.Fragment, null, /* @__PURE__ */ import_react20.default.createElement("div", { className: "fixed inset-0 z-40", onClick: () => {
11610
11630
  setIsReturnDropdownOpen(false);
package/dist/index.mjs CHANGED
@@ -1075,8 +1075,7 @@ function XViewSidebar({
1075
1075
  title: "Gerenciar os milestones deste cen\xE1rio"
1076
1076
  },
1077
1077
  /* @__PURE__ */ React2.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React2.createElement("circle", { cx: "12", cy: "12", r: "10" }), /* @__PURE__ */ React2.createElement("circle", { cx: "12", cy: "12", r: "6" }), /* @__PURE__ */ React2.createElement("circle", { cx: "12", cy: "12", r: "2" })),
1078
- "Gerenciar Milestones",
1079
- milestones.length > 0 && /* @__PURE__ */ React2.createElement("span", { className: "ml-1.5 px-1.5 py-0.5 rounded-full bg-indigo-500/30 text-[10px] font-bold border border-indigo-400/30" }, milestones.length)
1078
+ "Gerenciar Milestones"
1080
1079
  ))), /* @__PURE__ */ React2.createElement("div", { className: "px-4 py-3 border-t border-white/10 bg-slate-900/30" }, /* @__PURE__ */ React2.createElement("section", { className: "space-y-2" }, /* @__PURE__ */ React2.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React2.createElement("p", { className: "text-[11px] uppercase tracking-wider text-slate-400" }, "Navega\xE7\xE3o")), ability.can("update", "Scene") && /* @__PURE__ */ React2.createElement(
1081
1080
  "button",
1082
1081
  {
@@ -9510,10 +9509,10 @@ function InSceneQuestForm({
9510
9509
  onUpdateMilestones = () => {
9511
9510
  }
9512
9511
  }) {
9513
- var _a, _b, _c;
9512
+ var _a, _b;
9514
9513
  const [name, setName] = useState17("");
9515
9514
  const [assigneeId, setAssigneeId] = useState17("");
9516
- const [milestoneId, setMilestoneId] = useState17("");
9515
+ const [milestoneIds, setMilestoneIds] = useState17([]);
9517
9516
  const [types, setTypes] = useState17(["quest"]);
9518
9517
  const [typeInput, setTypeInput] = useState17("");
9519
9518
  const [status, setStatus] = useState17("Backlog");
@@ -9535,31 +9534,48 @@ function InSceneQuestForm({
9535
9534
  const [customProps, setCustomProps] = useState17([]);
9536
9535
  const [isDescriptionModalOpen, setIsDescriptionModalOpen] = useState17(false);
9537
9536
  const propsEndRef = useRef12(null);
9538
- const [isMilestoneDropdownOpen, setIsMilestoneDropdownOpen] = useState17(false);
9539
- const [milestoneSearchQuery, setMilestoneSearchQuery] = useState17("");
9537
+ const [milestoneInput, setMilestoneInput] = useState17("");
9538
+ const [showMilestoneSuggestions, setShowMilestoneSuggestions] = useState17(false);
9540
9539
  const activeMilestones = React16.useMemo(
9541
9540
  () => (milestones || []).filter((ms) => ms.status === "active"),
9542
9541
  [milestones]
9543
9542
  );
9544
9543
  const filteredMilestones = React16.useMemo(() => {
9545
- if (!milestoneSearchQuery.trim()) return activeMilestones;
9544
+ const search = milestoneInput.toLowerCase().trim();
9546
9545
  return activeMilestones.filter(
9547
- (ms) => ms.name.toLowerCase().includes(milestoneSearchQuery.toLowerCase())
9546
+ (ms) => ms.name.toLowerCase().includes(search) && !milestoneIds.includes(ms.id)
9548
9547
  );
9549
- }, [activeMilestones, milestoneSearchQuery]);
9550
- const handleSelectMilestone = (id) => {
9551
- setMilestoneId(id);
9552
- setIsMilestoneDropdownOpen(false);
9553
- setMilestoneSearchQuery("");
9548
+ }, [activeMilestones, milestoneInput, milestoneIds]);
9549
+ const handleAddMilestone = async (ms) => {
9550
+ let id = ms.id;
9551
+ if (!id) {
9552
+ const name2 = ms.name.trim();
9553
+ if (!name2) return;
9554
+ const existing = activeMilestones.find((m) => m.name.toLowerCase() === name2.toLowerCase());
9555
+ if (existing) {
9556
+ id = existing.id;
9557
+ } else {
9558
+ id = `ms_${Date.now()}`;
9559
+ const newMs = { id, name: name2, status: "active" };
9560
+ await onUpdateMilestones([...milestones, newMs]);
9561
+ }
9562
+ }
9563
+ if (id && !milestoneIds.includes(id)) {
9564
+ setMilestoneIds([...milestoneIds, id]);
9565
+ setMilestoneInput("");
9566
+ setShowMilestoneSuggestions(false);
9567
+ }
9554
9568
  };
9555
- const handleCreateMilestone = async (name2) => {
9556
- if (!name2.trim()) return;
9557
- const newId = `ms_${Date.now()}`;
9558
- const newMs = { id: newId, name: name2.trim(), status: "active" };
9559
- await onUpdateMilestones([...milestones, newMs]);
9560
- setMilestoneId(newId);
9561
- setIsMilestoneDropdownOpen(false);
9562
- setMilestoneSearchQuery("");
9569
+ const handleRemoveMilestone = (idToRemove) => {
9570
+ setMilestoneIds(milestoneIds.filter((id) => id !== idToRemove));
9571
+ };
9572
+ const handleMilestoneInputKeyDown = (e) => {
9573
+ if (e.key === "Enter" && milestoneInput.trim()) {
9574
+ e.preventDefault();
9575
+ handleAddMilestone({ name: milestoneInput });
9576
+ } else if (e.key === "Backspace" && milestoneInput === "" && milestoneIds.length > 0) {
9577
+ handleRemoveMilestone(milestoneIds[milestoneIds.length - 1]);
9578
+ }
9563
9579
  };
9564
9580
  const standardizedName = `${viewName} - ${questCounter} - \xBB ${name || "Nova Quest"}`;
9565
9581
  const handleAddProp = () => {
@@ -9628,7 +9644,7 @@ function InSceneQuestForm({
9628
9644
  timeline: initialTimeline,
9629
9645
  Date: questDate ? { ...questDate, confirmed: true } : null,
9630
9646
  recurrence_config: recurrenceConfig,
9631
- milestone_id: milestoneId || null,
9647
+ milestone_ids: milestoneIds,
9632
9648
  ...additionalData
9633
9649
  });
9634
9650
  };
@@ -9732,71 +9748,58 @@ function InSceneQuestForm({
9732
9748
  }
9733
9749
  ),
9734
9750
  s
9735
- )))))), /* @__PURE__ */ React16.createElement("div", { className: "space-y-1.5 relative mt-2" }, /* @__PURE__ */ React16.createElement("label", { className: "text-xs text-slate-300 font-medium uppercase tracking-wider" }, "Milestone"), /* @__PURE__ */ React16.createElement("div", { className: "relative" }, /* @__PURE__ */ React16.createElement(
9736
- "button",
9737
- {
9738
- type: "button",
9739
- onClick: () => setIsMilestoneDropdownOpen(!isMilestoneDropdownOpen),
9740
- className: "w-full bg-slate-800/70 p-2.5 text-sm rounded-lg border border-white/10 hover:border-white/20 focus:outline-none focus:ring-2 focus:ring-indigo-400/60 transition-colors flex items-center justify-between"
9741
- },
9742
- /* @__PURE__ */ React16.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React16.createElement(FiTarget, { className: "text-slate-400", size: 14 }), /* @__PURE__ */ React16.createElement("span", { className: "text-slate-200 font-medium" }, ((_a = (milestones || []).find((m) => m.id === milestoneId)) == null ? void 0 : _a.name) || "Nenhum")),
9743
- /* @__PURE__ */ React16.createElement(
9744
- FiChevronDown6,
9745
- {
9746
- className: `text-slate-400 transition-transform duration-200 ${isMilestoneDropdownOpen ? "rotate-180" : ""}`
9747
- }
9748
- )
9749
- ), isMilestoneDropdownOpen && /* @__PURE__ */ React16.createElement(React16.Fragment, null, /* @__PURE__ */ React16.createElement(
9750
- "div",
9751
- {
9752
- className: "fixed inset-0 z-40",
9753
- onClick: () => {
9754
- setIsMilestoneDropdownOpen(false);
9755
- setMilestoneSearchQuery("");
9756
- }
9757
- }
9758
- ), /* @__PURE__ */ React16.createElement("div", { className: "absolute top-full left-0 mt-1.5 w-full bg-slate-900 border border-white/10 rounded-lg shadow-[0_8px_30px_rgba(0,0,0,0.5)] z-50 overflow-hidden flex flex-col" }, /* @__PURE__ */ React16.createElement("div", { className: "p-2 border-b border-white/5 bg-white/5 flex items-center gap-2" }, /* @__PURE__ */ React16.createElement(FiSearch5, { className: "text-slate-500", size: 14 }), /* @__PURE__ */ React16.createElement(
9751
+ )))))), /* @__PURE__ */ React16.createElement("div", { className: "space-y-1.5 relative mt-2" }, /* @__PURE__ */ React16.createElement("label", { className: "text-xs text-slate-300 font-medium uppercase tracking-wider" }, "Milestones"), /* @__PURE__ */ React16.createElement("div", { className: `relative w-full bg-slate-800/70 p-1.5 min-h-[42px] flex flex-wrap gap-1.5 rounded-lg border border-white/10 focus-within:ring-2 focus-within:ring-indigo-400/60 transition-all cursor-text` }, milestoneIds.map((id) => {
9752
+ const ms = (milestones || []).find((m) => m.id === id);
9753
+ if (!ms) return null;
9754
+ return /* @__PURE__ */ React16.createElement("span", { key: id, className: "flex items-center gap-1 px-1.5 py-0.5 rounded-md text-xs font-medium border bg-sky-500/20 text-sky-200 border-sky-500/30" }, ms.name, /* @__PURE__ */ React16.createElement("button", { type: "button", onClick: () => handleRemoveMilestone(id), className: "hover:text-white transition-colors" }, /* @__PURE__ */ React16.createElement(FiX5, { size: 12 })));
9755
+ }), /* @__PURE__ */ React16.createElement(
9759
9756
  "input",
9760
9757
  {
9761
9758
  type: "text",
9762
- autoFocus: true,
9763
- placeholder: "Buscar ou criar milestone...",
9764
- value: milestoneSearchQuery,
9765
- onChange: (e) => setMilestoneSearchQuery(e.target.value),
9766
- className: "bg-transparent border-none outline-none text-xs text-white placeholder-slate-500 w-full",
9767
- onClick: (e) => e.stopPropagation()
9759
+ value: milestoneInput,
9760
+ onChange: (e) => {
9761
+ setMilestoneInput(e.target.value);
9762
+ setShowMilestoneSuggestions(true);
9763
+ },
9764
+ onKeyDown: handleMilestoneInputKeyDown,
9765
+ onFocus: () => setShowMilestoneSuggestions(true),
9766
+ onBlur: () => {
9767
+ setTimeout(() => setShowMilestoneSuggestions(false), 200);
9768
+ },
9769
+ className: "flex-1 bg-transparent text-sm min-w-[80px] focus:outline-none text-slate-200",
9770
+ placeholder: milestoneIds.length === 0 ? "Adicionar milestone..." : "",
9771
+ autoComplete: "off"
9768
9772
  }
9769
- )), /* @__PURE__ */ React16.createElement("ul", { className: "max-h-48 overflow-y-auto custom-scrollbar" }, /* @__PURE__ */ React16.createElement(
9770
- "li",
9771
- {
9772
- onClick: () => handleSelectMilestone(""),
9773
- className: `px-3 py-2.5 text-sm cursor-pointer transition-colors flex items-center gap-2 ${!milestoneId ? "bg-indigo-500/20 text-white" : "text-slate-300 hover:bg-white/5 hover:text-white"}`
9774
- },
9775
- "Nenhum"
9776
- ), filteredMilestones.map((ms) => /* @__PURE__ */ React16.createElement(
9773
+ ), showMilestoneSuggestions && filteredMilestones.length > 0 && /* @__PURE__ */ React16.createElement("ul", { className: "custom-scrollbar absolute top-full left-0 z-[100] w-full mt-1 max-h-40 overflow-y-auto rounded-lg bg-slate-800 border border-white/10 shadow-lg" }, filteredMilestones.map((ms) => /* @__PURE__ */ React16.createElement(
9777
9774
  "li",
9778
9775
  {
9779
9776
  key: ms.id,
9780
- onClick: () => handleSelectMilestone(ms.id),
9781
- className: `px-3 py-2.5 text-sm cursor-pointer transition-colors flex items-center gap-2 ${milestoneId === ms.id ? "bg-indigo-500/20 text-white" : "text-slate-300 hover:bg-white/5 hover:text-white"}`
9777
+ className: "px-3 py-2 text-sm text-slate-200 cursor-pointer hover:bg-indigo-600/50",
9778
+ onMouseDown: (e) => {
9779
+ e.preventDefault();
9780
+ handleAddMilestone(ms);
9781
+ }
9782
9782
  },
9783
9783
  ms.name
9784
- )), milestoneSearchQuery.trim() && !filteredMilestones.some((ms) => ms.name.toLowerCase() === milestoneSearchQuery.toLowerCase().trim()) && /* @__PURE__ */ React16.createElement(
9784
+ ))), showMilestoneSuggestions && milestoneInput.trim() && !filteredMilestones.some((m) => m.name.toLowerCase() === milestoneInput.toLowerCase().trim()) && /* @__PURE__ */ React16.createElement("ul", { className: "custom-scrollbar absolute top-full left-0 z-[100] w-full mt-1 rounded-lg bg-slate-800 border border-white/10 shadow-lg" }, /* @__PURE__ */ React16.createElement(
9785
9785
  "li",
9786
9786
  {
9787
- onClick: () => handleCreateMilestone(milestoneSearchQuery),
9788
- className: "px-3 py-3 text-sm cursor-pointer bg-indigo-600/20 text-indigo-200 hover:bg-indigo-600/40 transition-colors flex flex-col gap-0.5"
9787
+ className: "px-3 py-3 text-sm cursor-pointer hover:bg-indigo-600/50 flex flex-col gap-0.5",
9788
+ onMouseDown: (e) => {
9789
+ e.preventDefault();
9790
+ handleAddMilestone({ name: milestoneInput });
9791
+ }
9789
9792
  },
9790
- /* @__PURE__ */ React16.createElement("span", { className: "text-[10px] uppercase font-bold opacity-60" }, "Criar Novo Milestone"),
9791
- /* @__PURE__ */ React16.createElement("span", { className: "font-medium" }, '"', milestoneSearchQuery, '"')
9792
- )))))), /* @__PURE__ */ React16.createElement("div", { className: "space-y-1.5 relative mt-2" }, /* @__PURE__ */ React16.createElement("label", { className: "text-xs text-slate-300 font-medium uppercase tracking-wider" }, "Assignee (Respons\xE1vel)"), /* @__PURE__ */ React16.createElement("div", { className: "relative" }, /* @__PURE__ */ React16.createElement(
9793
+ /* @__PURE__ */ React16.createElement("span", { className: "text-[10px] uppercase font-bold text-slate-500" }, "Criar novo milestone"),
9794
+ /* @__PURE__ */ React16.createElement("span", { className: "text-white" }, '"', milestoneInput, '"')
9795
+ )))), /* @__PURE__ */ React16.createElement("div", { className: "space-y-1.5 relative mt-2" }, /* @__PURE__ */ React16.createElement("label", { className: "text-xs text-slate-300 font-medium uppercase tracking-wider" }, "Assignee (Respons\xE1vel)"), /* @__PURE__ */ React16.createElement("div", { className: "relative" }, /* @__PURE__ */ React16.createElement(
9793
9796
  "button",
9794
9797
  {
9795
9798
  type: "button",
9796
9799
  onClick: () => setIsAssigneeDropdownOpen(!isAssigneeDropdownOpen),
9797
9800
  className: "w-full bg-slate-800/70 p-2.5 text-sm rounded-lg border border-white/10 hover:border-white/20 focus:outline-none focus:ring-2 focus:ring-indigo-400/60 transition-colors flex items-center justify-between"
9798
9801
  },
9799
- /* @__PURE__ */ React16.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React16.createElement(FiUser2, { className: "text-slate-400", size: 14 }), /* @__PURE__ */ React16.createElement("span", { className: "text-slate-200 font-medium" }, ((_b = viewMembers.find((m) => m.id === assigneeId)) == null ? void 0 : _b.name) || ((_c = viewMembers.find((m) => m.id === assigneeId)) == null ? void 0 : _c.email) || "Nenhum")),
9802
+ /* @__PURE__ */ React16.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React16.createElement(FiUser2, { className: "text-slate-400", size: 14 }), /* @__PURE__ */ React16.createElement("span", { className: "text-slate-200 font-medium" }, ((_a = viewMembers.find((m) => m.id === assigneeId)) == null ? void 0 : _a.name) || ((_b = viewMembers.find((m) => m.id === assigneeId)) == null ? void 0 : _b.email) || "Nenhum")),
9800
9803
  /* @__PURE__ */ React16.createElement(
9801
9804
  FiChevronDown6,
9802
9805
  {
@@ -10785,7 +10788,7 @@ function QuestDetailsPanel({
10785
10788
  onUpdateMilestones = () => {
10786
10789
  }
10787
10790
  }) {
10788
- var _a, _b, _c;
10791
+ var _a, _b;
10789
10792
  const initialRawTitle = (node == null ? void 0 : node.raw_title) || (((_a = node == null ? void 0 : node.name) == null ? void 0 : _a.includes(" - \xBB ")) ? node.name.split(" - \xBB ")[1] : node == null ? void 0 : node.name) || "";
10790
10793
  const [rawTitle, setRawTitle] = useState19(initialRawTitle);
10791
10794
  const prefixParts = ((node == null ? void 0 : node.name) || "").split(" - \xBB ");
@@ -10798,7 +10801,7 @@ function QuestDetailsPanel({
10798
10801
  const [assigneeId, setAssigneeId] = useState19((node == null ? void 0 : node.assignee_id) || "");
10799
10802
  const [description, setDescription] = useState19((node == null ? void 0 : node.description) ?? "");
10800
10803
  const [intensity, setIntensity] = useState19((node == null ? void 0 : node.intensity) !== void 0 ? node.intensity : 0);
10801
- const [milestoneId, setMilestoneId] = useState19((node == null ? void 0 : node.milestone_id) || "");
10804
+ const [milestoneIds, setMilestoneIds] = useState19((node == null ? void 0 : node.milestone_ids) || []);
10802
10805
  const [isStatusDropdownOpen, setIsStatusDropdownOpen] = useState19(false);
10803
10806
  const [isAssigneeDropdownOpen, setIsAssigneeDropdownOpen] = useState19(false);
10804
10807
  const [assigneeSearchQuery, setAssigneeSearchQuery] = useState19("");
@@ -10836,35 +10839,51 @@ function QuestDetailsPanel({
10836
10839
  minWidth: 320,
10837
10840
  maxWidth: maxPanelW
10838
10841
  });
10839
- const [isMilestoneDropdownOpen, setIsMilestoneDropdownOpen] = useState19(false);
10840
- const [milestoneSearchQuery, setMilestoneSearchQuery] = useState19("");
10842
+ const [milestoneInput, setMilestoneInput] = useState19("");
10843
+ const [showMilestoneSuggestions, setShowMilestoneSuggestions] = useState19(false);
10841
10844
  const activeMilestones = React19.useMemo(
10842
10845
  () => (milestones || []).filter((ms) => ms.status === "active"),
10843
10846
  [milestones]
10844
10847
  );
10845
10848
  const filteredMilestones = React19.useMemo(() => {
10846
- const search = milestoneSearchQuery.toLowerCase().trim();
10847
- if (!search) return activeMilestones;
10849
+ const search = milestoneInput.toLowerCase().trim();
10848
10850
  return activeMilestones.filter(
10849
- (ms) => ms.name.toLowerCase().includes(search)
10851
+ (ms) => ms.name.toLowerCase().includes(search) && !milestoneIds.includes(ms.id)
10850
10852
  );
10851
- }, [activeMilestones, milestoneSearchQuery]);
10852
- const handleSelectMilestone = (id) => {
10853
- setMilestoneId(id);
10854
- setIsMilestoneDropdownOpen(false);
10855
- setMilestoneSearchQuery("");
10856
- setHasUnsavedChanges(true);
10853
+ }, [activeMilestones, milestoneInput, milestoneIds]);
10854
+ const handleAddMilestone = async (ms) => {
10855
+ let id = ms.id;
10856
+ if (!id) {
10857
+ const name = ms.name.trim();
10858
+ if (!name) return;
10859
+ const existing = activeMilestones.find((m) => m.name.toLowerCase() === name.toLowerCase());
10860
+ if (existing) {
10861
+ id = existing.id;
10862
+ } else {
10863
+ id = `ms_${Date.now()}`;
10864
+ const newMs = { id, name, status: "active" };
10865
+ await onUpdateMilestones([...milestones, newMs]);
10866
+ }
10867
+ }
10868
+ if (id && !milestoneIds.includes(id)) {
10869
+ setMilestoneIds([...milestoneIds, id]);
10870
+ setMilestoneInput("");
10871
+ setShowMilestoneSuggestions(false);
10872
+ setHasUnsavedChanges(true);
10873
+ }
10857
10874
  };
10858
- const handleCreateMilestone = async (name) => {
10859
- if (!name.trim()) return;
10860
- const newId = `ms_${Date.now()}`;
10861
- const newMs = { id: newId, name: name.trim(), status: "active" };
10862
- await onUpdateMilestones([...milestones, newMs]);
10863
- setMilestoneId(newId);
10864
- setIsMilestoneDropdownOpen(false);
10865
- setMilestoneSearchQuery("");
10875
+ const handleRemoveMilestone = (idToRemove) => {
10876
+ setMilestoneIds(milestoneIds.filter((id) => id !== idToRemove));
10866
10877
  setHasUnsavedChanges(true);
10867
10878
  };
10879
+ const handleMilestoneInputKeyDown = (e) => {
10880
+ if (e.key === "Enter" && milestoneInput.trim()) {
10881
+ e.preventDefault();
10882
+ handleAddMilestone({ name: milestoneInput });
10883
+ } else if (e.key === "Backspace" && milestoneInput === "" && milestoneIds.length > 0) {
10884
+ handleRemoveMilestone(milestoneIds[milestoneIds.length - 1]);
10885
+ }
10886
+ };
10868
10887
  useEffect16(() => {
10869
10888
  setWidth(isReadMode ? 700 : 440);
10870
10889
  }, [isReadMode, setWidth]);
@@ -10890,7 +10909,7 @@ function QuestDetailsPanel({
10890
10909
  setReturnAssigneeId("");
10891
10910
  setDescription((node == null ? void 0 : node.description) ?? "");
10892
10911
  setIntensity((node == null ? void 0 : node.intensity) !== void 0 ? node.intensity : 0);
10893
- setMilestoneId((node == null ? void 0 : node.milestone_id) || "");
10912
+ setMilestoneIds((node == null ? void 0 : node.milestone_ids) || []);
10894
10913
  setExistingSections((node == null ? void 0 : node.description_sections) || []);
10895
10914
  setCustomProps(extractCustomPropsFromNode(node || {}));
10896
10915
  setReviewStack((node == null ? void 0 : node.reviewStack) || []);
@@ -10903,7 +10922,6 @@ function QuestDetailsPanel({
10903
10922
  custom_date: "",
10904
10923
  next_assignee_id: ""
10905
10924
  });
10906
- setMilestoneId((node == null ? void 0 : node.milestone_id) || "");
10907
10925
  setHasUnsavedChanges(false);
10908
10926
  }
10909
10927
  }, [node]);
@@ -11203,7 +11221,7 @@ ${noteText}` : noteText : entry.notes,
11203
11221
  timeline: currentTimeline,
11204
11222
  ...extrasObj,
11205
11223
  version_node: node.version_node,
11206
- milestone_id: milestoneId || null
11224
+ milestone_ids: milestoneIds
11207
11225
  };
11208
11226
  await onSave(dataToSave, keepOpen);
11209
11227
  onDataUpdate(dataToSave);
@@ -11405,51 +11423,53 @@ ${noteText}` : noteText : entry.notes,
11405
11423
  maxLength: "10",
11406
11424
  className: "flex-1 bg-slate-800/70 p-2 text-xs rounded-lg border border-white/10 focus:outline-none focus:ring-1 focus:ring-indigo-400/60"
11407
11425
  }
11408
- ))))), /* @__PURE__ */ React19.createElement("div", { className: "space-y-1.5 relative mt-2" }, /* @__PURE__ */ React19.createElement("label", { className: "text-xs text-slate-300" }, "Milestone"), /* @__PURE__ */ React19.createElement("div", { className: "relative" }, /* @__PURE__ */ React19.createElement(
11409
- "button",
11410
- {
11411
- type: "button",
11412
- onClick: () => canEdit && setIsMilestoneDropdownOpen(!isMilestoneDropdownOpen),
11413
- disabled: !canEdit,
11414
- className: `w-full bg-slate-800/70 p-2.5 text-sm rounded-lg border border-white/10 transition-colors flex items-center justify-between ${canEdit ? "hover:border-white/20 focus:ring-2 focus:ring-indigo-400/60 cursor-pointer" : "cursor-default opacity-80"}`
11415
- },
11416
- /* @__PURE__ */ React19.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React19.createElement(FiTarget3, { className: "text-slate-400", size: 14 }), /* @__PURE__ */ React19.createElement("span", { className: "text-slate-200 font-medium" }, ((_b = (milestones || []).find((m) => m.id === milestoneId)) == null ? void 0 : _b.name) || "Nenhum")),
11417
- canEdit && /* @__PURE__ */ React19.createElement(FiChevronDown7, { className: `text-slate-400 transition-transform duration-200 ${isMilestoneDropdownOpen ? "rotate-180" : ""}` })
11418
- ), isMilestoneDropdownOpen && canEdit && /* @__PURE__ */ React19.createElement(React19.Fragment, null, /* @__PURE__ */ React19.createElement("div", { className: "fixed inset-0 z-40", onClick: () => setIsMilestoneDropdownOpen(false) }), /* @__PURE__ */ React19.createElement("div", { className: "absolute top-full left-0 mt-1.5 w-full bg-slate-900 border border-white/10 rounded-lg shadow-[0_8px_30px_rgba(0,0,0,0.5)] z-50 overflow-hidden flex flex-col" }, /* @__PURE__ */ React19.createElement("div", { className: "p-2 border-b border-white/5 bg-white/5 flex items-center gap-2" }, /* @__PURE__ */ React19.createElement(FiSearch7, { className: "text-slate-500", size: 14 }), /* @__PURE__ */ React19.createElement(
11426
+ ))))), /* @__PURE__ */ React19.createElement("div", { className: "space-y-1.5 relative mt-2" }, /* @__PURE__ */ React19.createElement("label", { className: "text-xs text-slate-300" }, "Milestones"), /* @__PURE__ */ React19.createElement("div", { className: `relative w-full bg-slate-800/70 p-1.5 min-h-[42px] flex flex-wrap gap-1.5 rounded-lg border border-white/10 ${canEdit ? "focus-within:ring-2 focus-within:ring-indigo-400/60" : ""} transition-all` }, milestoneIds.map((id) => {
11427
+ const ms = (milestones || []).find((m) => m.id === id);
11428
+ if (!ms) return null;
11429
+ return /* @__PURE__ */ React19.createElement("span", { key: id, className: "flex items-center gap-1 px-1.5 py-0.5 rounded-md text-xs font-medium border bg-sky-500/20 text-sky-200 border-sky-500/30" }, ms.name, canEdit && /* @__PURE__ */ React19.createElement("button", { type: "button", onClick: () => handleRemoveMilestone(id), className: "hover:text-white transition-colors" }, /* @__PURE__ */ React19.createElement(FiX7, { size: 12 })));
11430
+ }), canEdit && /* @__PURE__ */ React19.createElement(
11419
11431
  "input",
11420
11432
  {
11421
11433
  type: "text",
11422
- autoFocus: true,
11423
- placeholder: "Buscar ou criar milestone...",
11424
- value: milestoneSearchQuery,
11425
- onChange: (e) => setMilestoneSearchQuery(e.target.value),
11426
- className: "bg-transparent border-none outline-none text-xs text-white placeholder-slate-500 w-full",
11427
- onClick: (e) => e.stopPropagation()
11434
+ value: milestoneInput,
11435
+ onChange: (e) => {
11436
+ setMilestoneInput(e.target.value);
11437
+ setShowMilestoneSuggestions(true);
11438
+ },
11439
+ onKeyDown: handleMilestoneInputKeyDown,
11440
+ onFocus: () => setShowMilestoneSuggestions(true),
11441
+ onBlur: () => {
11442
+ if (milestoneInput.trim()) {
11443
+ }
11444
+ setTimeout(() => setShowMilestoneSuggestions(false), 200);
11445
+ },
11446
+ className: "flex-1 bg-transparent text-sm min-w-[80px] focus:outline-none text-slate-200",
11447
+ placeholder: milestoneIds.length === 0 ? "Adicionar milestone..." : "",
11448
+ autoComplete: "off"
11428
11449
  }
11429
- )), /* @__PURE__ */ React19.createElement("ul", { className: "max-h-48 overflow-y-auto custom-scrollbar" }, /* @__PURE__ */ React19.createElement(
11430
- "li",
11431
- {
11432
- onClick: () => handleSelectMilestone(""),
11433
- className: `px-3 py-2.5 text-sm cursor-pointer transition-colors flex items-center gap-2 ${!milestoneId ? "bg-indigo-500/20 text-white" : "text-slate-300 hover:bg-white/5 hover:text-white"}`
11434
- },
11435
- "Nenhum"
11436
- ), filteredMilestones.map((ms) => /* @__PURE__ */ React19.createElement(
11450
+ ), canEdit && showMilestoneSuggestions && filteredMilestones.length > 0 && /* @__PURE__ */ React19.createElement("ul", { className: "custom-scrollbar absolute top-full left-0 z-[100] w-full mt-1 max-h-40 overflow-y-auto rounded-lg bg-slate-800 border border-white/10 shadow-lg" }, filteredMilestones.map((ms) => /* @__PURE__ */ React19.createElement(
11437
11451
  "li",
11438
11452
  {
11439
11453
  key: ms.id,
11440
- onClick: () => handleSelectMilestone(ms.id),
11441
- className: `px-3 py-2.5 text-sm cursor-pointer transition-colors flex items-center gap-2 ${milestoneId === ms.id ? "bg-indigo-500/20 text-white" : "text-slate-300 hover:bg-white/5 hover:text-white"}`
11454
+ className: "px-3 py-2 text-sm text-slate-200 cursor-pointer hover:bg-indigo-600/50",
11455
+ onMouseDown: (e) => {
11456
+ e.preventDefault();
11457
+ handleAddMilestone(ms);
11458
+ }
11442
11459
  },
11443
11460
  ms.name
11444
- )), milestoneSearchQuery.trim() && !filteredMilestones.some((ms) => ms.name.toLowerCase() === milestoneSearchQuery.toLowerCase().trim()) && /* @__PURE__ */ React19.createElement(
11461
+ ))), canEdit && showMilestoneSuggestions && milestoneInput.trim() && !filteredMilestones.some((m) => m.name.toLowerCase() === milestoneInput.toLowerCase().trim()) && /* @__PURE__ */ React19.createElement("ul", { className: "custom-scrollbar absolute top-full left-0 z-[100] w-full mt-1 rounded-lg bg-slate-800 border border-white/10 shadow-lg" }, /* @__PURE__ */ React19.createElement(
11445
11462
  "li",
11446
11463
  {
11447
- onClick: () => handleCreateMilestone(milestoneSearchQuery),
11448
- className: "px-3 py-3 text-sm cursor-pointer bg-indigo-600/20 text-indigo-200 hover:bg-indigo-600/40 transition-colors flex flex-col gap-0.5"
11464
+ className: "px-3 py-3 text-sm cursor-pointer hover:bg-indigo-600/50 flex flex-col gap-0.5",
11465
+ onMouseDown: (e) => {
11466
+ e.preventDefault();
11467
+ handleAddMilestone({ name: milestoneInput });
11468
+ }
11449
11469
  },
11450
- /* @__PURE__ */ React19.createElement("span", { className: "text-[10px] uppercase font-bold opacity-60" }, "Criar Novo Milestone"),
11451
- /* @__PURE__ */ React19.createElement("span", { className: "font-medium" }, '"', milestoneSearchQuery, '"')
11452
- )))))), /* @__PURE__ */ React19.createElement("div", { className: "space-y-1.5 relative mt-2" }, /* @__PURE__ */ React19.createElement("label", { className: "text-xs text-slate-300" }, "Status da Quest"), /* @__PURE__ */ React19.createElement("div", { className: "relative" }, /* @__PURE__ */ React19.createElement(
11470
+ /* @__PURE__ */ React19.createElement("span", { className: "text-[10px] uppercase font-bold text-slate-500" }, "Criar novo milestone"),
11471
+ /* @__PURE__ */ React19.createElement("span", { className: "text-white" }, '"', milestoneInput, '"')
11472
+ )))), /* @__PURE__ */ React19.createElement("div", { className: "space-y-1.5 relative mt-2" }, /* @__PURE__ */ React19.createElement("label", { className: "text-xs text-slate-300" }, "Status da Quest"), /* @__PURE__ */ React19.createElement("div", { className: "relative" }, /* @__PURE__ */ React19.createElement(
11453
11473
  "button",
11454
11474
  {
11455
11475
  type: "button",
@@ -11635,7 +11655,7 @@ ${noteText}` : noteText : entry.notes,
11635
11655
  onClick: () => setIsReturnDropdownOpen(!isReturnDropdownOpen),
11636
11656
  className: "w-full bg-slate-800/80 p-2 text-xs rounded-lg border border-white/10 hover:border-white/20 focus:outline-none focus:ring-1 focus:ring-purple-400/50 transition-colors flex items-center justify-between"
11637
11657
  },
11638
- /* @__PURE__ */ React19.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React19.createElement(FiUser3, { className: "text-slate-400", size: 12 }), /* @__PURE__ */ React19.createElement("span", { className: "text-slate-200 font-medium" }, ((_c = viewMembers.find((m) => String(m.id) === String(returnAssigneeId))) == null ? void 0 : _c.name) || "Selecionar respons\xE1vel...")),
11658
+ /* @__PURE__ */ React19.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React19.createElement(FiUser3, { className: "text-slate-400", size: 12 }), /* @__PURE__ */ React19.createElement("span", { className: "text-slate-200 font-medium" }, ((_b = viewMembers.find((m) => String(m.id) === String(returnAssigneeId))) == null ? void 0 : _b.name) || "Selecionar respons\xE1vel...")),
11639
11659
  /* @__PURE__ */ React19.createElement(FiChevronDown7, { className: `text-slate-400 transition-transform duration-200 ${isReturnDropdownOpen ? "rotate-180" : ""}`, size: 14 })
11640
11660
  ), isReturnDropdownOpen && /* @__PURE__ */ React19.createElement(React19.Fragment, null, /* @__PURE__ */ React19.createElement("div", { className: "fixed inset-0 z-40", onClick: () => {
11641
11661
  setIsReturnDropdownOpen(false);
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.49",
3
+ "version": "1.2.5-dev.50",
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",