@lv-x-software-house/x_view 1.2.5-dev.42 → 1.2.5-dev.44
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 +164 -71
- package/dist/index.mjs +164 -71
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1334,6 +1334,15 @@ var createNodeMesh = (nodeData, position, glowTexture) => {
|
|
|
1334
1334
|
label.name = "label";
|
|
1335
1335
|
mesh.userData.labelObject = label;
|
|
1336
1336
|
mesh.userData.labelOffset = new THREE.Vector3(0, 3.8, 0);
|
|
1337
|
+
if (nodeData.is_quest && nodeData.Date) {
|
|
1338
|
+
const timeInfo = parseDateProp(nodeData.Date);
|
|
1339
|
+
if (!timeInfo.isUndated && timeInfo.label) {
|
|
1340
|
+
const dateSprite = createTextSprite(timeInfo.label, 36);
|
|
1341
|
+
dateSprite.name = "questDateLabel";
|
|
1342
|
+
dateSprite.position.set(0, -5.5, 0);
|
|
1343
|
+
mesh.add(dateSprite);
|
|
1344
|
+
}
|
|
1345
|
+
}
|
|
1337
1346
|
return mesh;
|
|
1338
1347
|
};
|
|
1339
1348
|
var updateExistingNodeVisuals = (state, updatedNode) => {
|
|
@@ -3321,9 +3330,14 @@ var userActionHandlers = {
|
|
|
3321
3330
|
};
|
|
3322
3331
|
specificParentData.nodes.push(nextQuestNode);
|
|
3323
3332
|
if (stateRef.current.nodeObjects[String(nodeToSave.id)]) {
|
|
3324
|
-
const
|
|
3325
|
-
|
|
3326
|
-
|
|
3333
|
+
const oldMeshPosition = stateRef.current.nodeObjects[String(nodeToSave.id)].position.clone();
|
|
3334
|
+
setTimeout(() => {
|
|
3335
|
+
if (stateRef.current && stateRef.current.graphGroup) {
|
|
3336
|
+
const pos = oldMeshPosition.clone();
|
|
3337
|
+
pos.x += 12;
|
|
3338
|
+
addStandaloneNodeToScene(stateRef.current, nextQuestNode, pos);
|
|
3339
|
+
}
|
|
3340
|
+
}, 2e3);
|
|
3327
3341
|
}
|
|
3328
3342
|
}
|
|
3329
3343
|
}
|
|
@@ -4260,8 +4274,84 @@ function calculateNextRecurrenceDate(config) {
|
|
|
4260
4274
|
const d = String(nextDate.getDate()).padStart(2, "0");
|
|
4261
4275
|
const m = String(nextDate.getMonth() + 1).padStart(2, "0");
|
|
4262
4276
|
const y = nextDate.getFullYear();
|
|
4263
|
-
return {
|
|
4277
|
+
return {
|
|
4278
|
+
type: "Data",
|
|
4279
|
+
value: `${d}/${m}/${y}`,
|
|
4280
|
+
confirmed: true
|
|
4281
|
+
};
|
|
4264
4282
|
}
|
|
4283
|
+
var parseDate = (str) => {
|
|
4284
|
+
if (!str) return null;
|
|
4285
|
+
const parts = str.split("/");
|
|
4286
|
+
if (parts.length === 3) {
|
|
4287
|
+
const day = parseInt(parts[0], 10);
|
|
4288
|
+
const month = parseInt(parts[1], 10) - 1;
|
|
4289
|
+
const year = parseInt(parts[2], 10);
|
|
4290
|
+
if (!isNaN(day) && !isNaN(month) && !isNaN(year)) {
|
|
4291
|
+
return new Date(year, month, day);
|
|
4292
|
+
}
|
|
4293
|
+
}
|
|
4294
|
+
return null;
|
|
4295
|
+
};
|
|
4296
|
+
var parseDateProp = (dateProp) => {
|
|
4297
|
+
let info = { isUndated: true, label: "", type: "point" };
|
|
4298
|
+
if (!dateProp) return info;
|
|
4299
|
+
if (dateProp.type === "Data") {
|
|
4300
|
+
const d = parseDate(dateProp.value);
|
|
4301
|
+
if (d) {
|
|
4302
|
+
info = { startDate: d, endDate: d, label: dateProp.value, type: "point", isUndated: false };
|
|
4303
|
+
}
|
|
4304
|
+
} else if (dateProp.type === "Date Interval" || dateProp.type === "Date Range" || dateProp.type === "interval") {
|
|
4305
|
+
const sd = parseDate(dateProp.start || dateProp.value);
|
|
4306
|
+
const ed = parseDate(dateProp.end);
|
|
4307
|
+
if (sd) {
|
|
4308
|
+
info = {
|
|
4309
|
+
startDate: sd,
|
|
4310
|
+
endDate: ed || sd,
|
|
4311
|
+
label: `${dateProp.start || dateProp.value}${ed ? " - " + dateProp.end : ""}`,
|
|
4312
|
+
type: ed ? "interval" : "point",
|
|
4313
|
+
isUndated: false
|
|
4314
|
+
};
|
|
4315
|
+
}
|
|
4316
|
+
} else if (dateProp.date) {
|
|
4317
|
+
const d = parseDate(dateProp.date);
|
|
4318
|
+
if (d)
|
|
4319
|
+
info = {
|
|
4320
|
+
startDate: d,
|
|
4321
|
+
endDate: d,
|
|
4322
|
+
label: dateProp.date,
|
|
4323
|
+
type: "point",
|
|
4324
|
+
isUndated: false
|
|
4325
|
+
};
|
|
4326
|
+
} else if (dateProp.year) {
|
|
4327
|
+
const y = parseInt(dateProp.year, 10);
|
|
4328
|
+
if (!isNaN(y)) {
|
|
4329
|
+
const d = new Date(y, 0, 1);
|
|
4330
|
+
info = {
|
|
4331
|
+
startDate: d,
|
|
4332
|
+
endDate: d,
|
|
4333
|
+
label: String(y),
|
|
4334
|
+
type: "point",
|
|
4335
|
+
isUndated: false
|
|
4336
|
+
};
|
|
4337
|
+
}
|
|
4338
|
+
} else if (dateProp.date_interval && dateProp.date_interval.start) {
|
|
4339
|
+
const sY = parseInt(dateProp.date_interval.start, 10);
|
|
4340
|
+
const eY = parseInt(dateProp.date_interval.end, 10) || sY;
|
|
4341
|
+
if (!isNaN(sY)) {
|
|
4342
|
+
const sd = new Date(sY, 0, 1);
|
|
4343
|
+
const ed = new Date(eY, 11, 31);
|
|
4344
|
+
info = {
|
|
4345
|
+
startDate: sd,
|
|
4346
|
+
endDate: ed,
|
|
4347
|
+
label: `${sY} - ${eY}`,
|
|
4348
|
+
type: "interval",
|
|
4349
|
+
isUndated: false
|
|
4350
|
+
};
|
|
4351
|
+
}
|
|
4352
|
+
}
|
|
4353
|
+
return info;
|
|
4354
|
+
};
|
|
4265
4355
|
|
|
4266
4356
|
// src/components/CustomPropertyDisplay.jsx
|
|
4267
4357
|
var import_react4 = __toESM(require("react"));
|
|
@@ -9468,7 +9558,7 @@ function InSceneQuestForm({
|
|
|
9468
9558
|
textureImageUrl: null,
|
|
9469
9559
|
reviewStack,
|
|
9470
9560
|
timeline: initialTimeline,
|
|
9471
|
-
Date: questDate,
|
|
9561
|
+
Date: questDate ? { ...questDate, confirmed: true } : null,
|
|
9472
9562
|
recurrence_config: recurrenceConfig,
|
|
9473
9563
|
...additionalData
|
|
9474
9564
|
});
|
|
@@ -10932,7 +11022,7 @@ ${noteText}` : noteText : entry.notes,
|
|
|
10932
11022
|
description_sections: processedSections,
|
|
10933
11023
|
intensity,
|
|
10934
11024
|
recurrence_config: currentRecurrenceConfig,
|
|
10935
|
-
Date: questDate,
|
|
11025
|
+
Date: questDate ? { ...questDate, confirmed: true } : null,
|
|
10936
11026
|
useImageAsTexture: false,
|
|
10937
11027
|
textureImageUrl: null,
|
|
10938
11028
|
is_quest: true,
|
|
@@ -13495,7 +13585,7 @@ function XViewScene({
|
|
|
13495
13585
|
}
|
|
13496
13586
|
}
|
|
13497
13587
|
Object.values(nodeObjects).forEach((mesh) => {
|
|
13498
|
-
const oldLabel = mesh.getObjectByName("timelineLabel")
|
|
13588
|
+
const oldLabel = mesh.getObjectByName("timelineLabel");
|
|
13499
13589
|
if (oldLabel) {
|
|
13500
13590
|
mesh.remove(oldLabel);
|
|
13501
13591
|
if (oldLabel.material.map) oldLabel.material.map.dispose();
|
|
@@ -13506,7 +13596,7 @@ function XViewScene({
|
|
|
13506
13596
|
});
|
|
13507
13597
|
const timelineNodes = [];
|
|
13508
13598
|
const allTimePoints = /* @__PURE__ */ new Set();
|
|
13509
|
-
const
|
|
13599
|
+
const parseDate2 = (str) => {
|
|
13510
13600
|
const parts = str.split("/");
|
|
13511
13601
|
if (parts.length === 3) {
|
|
13512
13602
|
const day = parseInt(parts[0], 10);
|
|
@@ -13523,7 +13613,7 @@ function XViewScene({
|
|
|
13523
13613
|
let nodeInfo = { mesh, type: "point", label: "", isUndated: true };
|
|
13524
13614
|
if (dateProp) {
|
|
13525
13615
|
if (dateProp.date) {
|
|
13526
|
-
const date =
|
|
13616
|
+
const date = parseDate2(dateProp.date);
|
|
13527
13617
|
if (date) {
|
|
13528
13618
|
nodeInfo.startDate = date;
|
|
13529
13619
|
nodeInfo.endDate = date;
|
|
@@ -13669,7 +13759,7 @@ function XViewScene({
|
|
|
13669
13759
|
});
|
|
13670
13760
|
const timelineNodes = [];
|
|
13671
13761
|
const allTimePoints = /* @__PURE__ */ new Set();
|
|
13672
|
-
const
|
|
13762
|
+
const parseDate2 = (str) => {
|
|
13673
13763
|
const parts = str.split("/");
|
|
13674
13764
|
if (parts.length === 3) {
|
|
13675
13765
|
const day = parseInt(parts[0], 10);
|
|
@@ -13686,7 +13776,7 @@ function XViewScene({
|
|
|
13686
13776
|
if (!dateProp) return;
|
|
13687
13777
|
let nodeInfo = { mesh, type: "point", label: "" };
|
|
13688
13778
|
if (dateProp.date) {
|
|
13689
|
-
const date =
|
|
13779
|
+
const date = parseDate2(dateProp.date);
|
|
13690
13780
|
if (date) {
|
|
13691
13781
|
nodeInfo.startDate = date;
|
|
13692
13782
|
nodeInfo.endDate = date;
|
|
@@ -13928,16 +14018,8 @@ function XViewScene({
|
|
|
13928
14018
|
);
|
|
13929
14019
|
const handleActivateQuestLens = (0, import_react28.useCallback)(({ assigneeId, status: status2 }) => {
|
|
13930
14020
|
var _a2;
|
|
13931
|
-
const { nodeObjects, tweenGroup, graphGroup
|
|
14021
|
+
const { nodeObjects, tweenGroup, graphGroup } = stateRef.current;
|
|
13932
14022
|
if (!nodeObjects || !tweenGroup || !graphGroup) return;
|
|
13933
|
-
Object.values(nodeObjects).forEach((mesh) => {
|
|
13934
|
-
const oldLabel = mesh.getObjectByName("questDateLabel") || mesh.getObjectByName("timelineLabel");
|
|
13935
|
-
if (oldLabel) {
|
|
13936
|
-
mesh.remove(oldLabel);
|
|
13937
|
-
if (oldLabel.material.map) oldLabel.material.map.dispose();
|
|
13938
|
-
oldLabel.material.dispose();
|
|
13939
|
-
}
|
|
13940
|
-
});
|
|
13941
14023
|
const allQuests = ((_a2 = sceneDataRef.current) == null ? void 0 : _a2.quest_nodes) || [];
|
|
13942
14024
|
const filteredQuests = allQuests.filter((q) => {
|
|
13943
14025
|
const matchAssignee = !assigneeId || String(q.assignee_id) === String(assigneeId);
|
|
@@ -13959,61 +14041,39 @@ function XViewScene({
|
|
|
13959
14041
|
questsByStatus[q.status].push(q);
|
|
13960
14042
|
}
|
|
13961
14043
|
});
|
|
13962
|
-
const parseDate = (str) => {
|
|
13963
|
-
if (!str) return null;
|
|
13964
|
-
const parts = str.split("/");
|
|
13965
|
-
if (parts.length === 3) {
|
|
13966
|
-
const day = parseInt(parts[0], 10);
|
|
13967
|
-
const month = parseInt(parts[1], 10) - 1;
|
|
13968
|
-
const year = parseInt(parts[2], 10);
|
|
13969
|
-
if (!isNaN(day) && !isNaN(month) && !isNaN(year)) {
|
|
13970
|
-
return new Date(year, month, day);
|
|
13971
|
-
}
|
|
13972
|
-
}
|
|
13973
|
-
return null;
|
|
13974
|
-
};
|
|
13975
|
-
const timePoints = /* @__PURE__ */ new Set();
|
|
13976
14044
|
const questTimeInfos = /* @__PURE__ */ new Map();
|
|
14045
|
+
const allActiveTimePoints = /* @__PURE__ */ new Set();
|
|
13977
14046
|
filteredQuests.forEach((q) => {
|
|
13978
|
-
const
|
|
13979
|
-
|
|
13980
|
-
if (
|
|
13981
|
-
|
|
13982
|
-
|
|
13983
|
-
|
|
13984
|
-
info = { startDate: d, endDate: d, label: dateProp.date, isUndated: false };
|
|
13985
|
-
timePoints.add(d.getTime());
|
|
13986
|
-
}
|
|
13987
|
-
} else if (dateProp.year) {
|
|
13988
|
-
const y = parseInt(dateProp.year, 10);
|
|
13989
|
-
if (!isNaN(y)) {
|
|
13990
|
-
const d = new Date(y, 0, 1);
|
|
13991
|
-
info = { startDate: d, endDate: d, label: String(y), isUndated: false };
|
|
13992
|
-
timePoints.add(d.getTime());
|
|
13993
|
-
}
|
|
13994
|
-
} else if (dateProp.date_interval && dateProp.date_interval.start) {
|
|
13995
|
-
const sY = parseInt(dateProp.date_interval.start, 10);
|
|
13996
|
-
const eY = parseInt(dateProp.date_interval.end, 10) || sY;
|
|
13997
|
-
if (!isNaN(sY)) {
|
|
13998
|
-
const sd = new Date(sY, 0, 1);
|
|
13999
|
-
const ed = new Date(eY, 11, 31);
|
|
14000
|
-
info = { startDate: sd, endDate: ed, label: `${sY}-${eY}`, isUndated: false };
|
|
14001
|
-
timePoints.add(sd.getTime());
|
|
14002
|
-
timePoints.add(ed.getTime());
|
|
14003
|
-
}
|
|
14047
|
+
const info = parseDateProp(q.Date);
|
|
14048
|
+
questTimeInfos.set(String(q.id), info);
|
|
14049
|
+
if (!info.isUndated) {
|
|
14050
|
+
allActiveTimePoints.add(info.startDate.getTime());
|
|
14051
|
+
if (info.endDate && info.type === "interval") {
|
|
14052
|
+
allActiveTimePoints.add(info.endDate.getTime());
|
|
14004
14053
|
}
|
|
14005
14054
|
}
|
|
14006
|
-
questTimeInfos.set(String(q.id), info);
|
|
14007
14055
|
});
|
|
14008
|
-
const sortedTimePoints = Array.from(
|
|
14056
|
+
const sortedTimePoints = Array.from(allActiveTimePoints).sort((a, b) => a - b);
|
|
14009
14057
|
const timeToYMap = /* @__PURE__ */ new Map();
|
|
14010
|
-
|
|
14011
|
-
|
|
14012
|
-
|
|
14013
|
-
timeToYMap.set(t, (i - maxIdx) * (QUEST_LENS_ROW_SPACING || 30));
|
|
14014
|
-
});
|
|
14015
|
-
}
|
|
14058
|
+
sortedTimePoints.forEach((ms, idx) => {
|
|
14059
|
+
timeToYMap.set(ms, idx * TIMELINE_LAYER_SPACING_Y);
|
|
14060
|
+
});
|
|
14016
14061
|
const startX = -((QUEST_STATUS_ORDER.length - 1) * QUEST_LENS_COLUMN_SPACING) / 2;
|
|
14062
|
+
Object.values(nodeObjects).forEach((mesh) => {
|
|
14063
|
+
const oldLabel = mesh.getObjectByName("questDateLabel") || mesh.getObjectByName("timelineLabel");
|
|
14064
|
+
if (oldLabel) {
|
|
14065
|
+
mesh.remove(oldLabel);
|
|
14066
|
+
if (oldLabel.material) oldLabel.material.dispose();
|
|
14067
|
+
}
|
|
14068
|
+
if (mesh.userData.timelineIntervalBar) {
|
|
14069
|
+
if (graphGroup) graphGroup.remove(mesh.userData.timelineIntervalBar);
|
|
14070
|
+
mesh.userData.timelineIntervalBar = null;
|
|
14071
|
+
}
|
|
14072
|
+
if (mesh.userData.timelineEndLabel) {
|
|
14073
|
+
if (graphGroup) graphGroup.remove(mesh.userData.timelineEndLabel);
|
|
14074
|
+
mesh.userData.timelineEndLabel = null;
|
|
14075
|
+
}
|
|
14076
|
+
});
|
|
14017
14077
|
Object.keys(nodeObjects).forEach((id) => {
|
|
14018
14078
|
const mesh = nodeObjects[id];
|
|
14019
14079
|
const isFilteredQuest = filteredQuests.some(
|
|
@@ -14055,20 +14115,53 @@ function XViewScene({
|
|
|
14055
14115
|
targetY = timeToYMap.get(timeInfo.startDate.getTime());
|
|
14056
14116
|
} else {
|
|
14057
14117
|
const undatedOffset = sortedTimePoints.length > 0 ? sortedTimePoints.length * 5 : 0;
|
|
14058
|
-
targetY = -
|
|
14118
|
+
targetY = -40 - rowIndex * QUEST_LENS_ROW_SPACING - undatedOffset;
|
|
14059
14119
|
}
|
|
14060
14120
|
const lensTween = new import_tween2.Tween(mesh.position).to({ x: colX, y: targetY, z: 0 }, 1500).easing(import_tween2.Easing.Cubic.InOut);
|
|
14061
14121
|
tweenGroup.add(lensTween);
|
|
14062
14122
|
lensTween.start();
|
|
14063
|
-
if (!timeInfo.isUndated && timeInfo.label) {
|
|
14123
|
+
if (!timeInfo.isUndated && timeInfo.label && !mesh.getObjectByName("questDateLabel")) {
|
|
14064
14124
|
const dateSprite = createTextSprite(timeInfo.label, 36);
|
|
14065
14125
|
dateSprite.name = "questDateLabel";
|
|
14066
14126
|
dateSprite.position.set(0, -5.5, 0);
|
|
14067
14127
|
mesh.add(dateSprite);
|
|
14068
14128
|
}
|
|
14129
|
+
if (timeInfo.type === "interval" && timeToYMap.has(timeInfo.endDate.getTime())) {
|
|
14130
|
+
const endY = timeToYMap.get(timeInfo.endDate.getTime());
|
|
14131
|
+
if (Math.abs(endY - targetY) > 0.1) {
|
|
14132
|
+
const barHeight = Math.abs(endY - targetY);
|
|
14133
|
+
const barGeometry = new THREE3.CylinderGeometry(
|
|
14134
|
+
TIMELINE_INTERVAL_BAR_RADIUS,
|
|
14135
|
+
TIMELINE_INTERVAL_BAR_RADIUS,
|
|
14136
|
+
1,
|
|
14137
|
+
16
|
|
14138
|
+
);
|
|
14139
|
+
const barMaterial = new THREE3.MeshStandardMaterial({
|
|
14140
|
+
color: TIMELINE_GOLD_COLOR,
|
|
14141
|
+
emissive: 12092939,
|
|
14142
|
+
emissiveIntensity: 0.4,
|
|
14143
|
+
transparent: true,
|
|
14144
|
+
opacity: TIMELINE_INTERVAL_BAR_OPACITY,
|
|
14145
|
+
roughness: 0.3,
|
|
14146
|
+
metalness: 0.8
|
|
14147
|
+
});
|
|
14148
|
+
const intervalBar = new THREE3.Mesh(barGeometry, barMaterial);
|
|
14149
|
+
intervalBar.userData.associatedNodeId = mesh.userData.id;
|
|
14150
|
+
const endPosition = new THREE3.Vector3(colX, endY, -0.5);
|
|
14151
|
+
intervalBar.position.set(colX, (targetY + endY) / 2, -0.5);
|
|
14152
|
+
intervalBar.scale.y = barHeight;
|
|
14153
|
+
graphGroup.add(intervalBar);
|
|
14154
|
+
mesh.userData.timelineIntervalBar = intervalBar;
|
|
14155
|
+
const endLabel = createTextSprite(timeInfo.label.split(" - ")[1] || "", 30);
|
|
14156
|
+
endLabel.name = "timelineEndLabel";
|
|
14157
|
+
endLabel.position.set(colX, endY + 4, 0);
|
|
14158
|
+
graphGroup.add(endLabel);
|
|
14159
|
+
mesh.userData.timelineEndLabel = endLabel;
|
|
14160
|
+
}
|
|
14161
|
+
}
|
|
14069
14162
|
if (mesh.userData.labelObject) {
|
|
14070
14163
|
const labelTargetPos = new THREE3.Vector3(colX, targetY, 0).add(
|
|
14071
|
-
mesh.userData.labelOffset || new THREE3.Vector3(0,
|
|
14164
|
+
mesh.userData.labelOffset || new THREE3.Vector3(0, 3.8, 0)
|
|
14072
14165
|
);
|
|
14073
14166
|
const labelTween = new import_tween2.Tween(mesh.userData.labelObject.position).to(labelTargetPos, 1500).easing(import_tween2.Easing.Cubic.InOut);
|
|
14074
14167
|
tweenGroup.add(labelTween);
|
package/dist/index.mjs
CHANGED
|
@@ -1295,6 +1295,15 @@ var createNodeMesh = (nodeData, position, glowTexture) => {
|
|
|
1295
1295
|
label.name = "label";
|
|
1296
1296
|
mesh.userData.labelObject = label;
|
|
1297
1297
|
mesh.userData.labelOffset = new THREE.Vector3(0, 3.8, 0);
|
|
1298
|
+
if (nodeData.is_quest && nodeData.Date) {
|
|
1299
|
+
const timeInfo = parseDateProp(nodeData.Date);
|
|
1300
|
+
if (!timeInfo.isUndated && timeInfo.label) {
|
|
1301
|
+
const dateSprite = createTextSprite(timeInfo.label, 36);
|
|
1302
|
+
dateSprite.name = "questDateLabel";
|
|
1303
|
+
dateSprite.position.set(0, -5.5, 0);
|
|
1304
|
+
mesh.add(dateSprite);
|
|
1305
|
+
}
|
|
1306
|
+
}
|
|
1298
1307
|
return mesh;
|
|
1299
1308
|
};
|
|
1300
1309
|
var updateExistingNodeVisuals = (state, updatedNode) => {
|
|
@@ -3282,9 +3291,14 @@ var userActionHandlers = {
|
|
|
3282
3291
|
};
|
|
3283
3292
|
specificParentData.nodes.push(nextQuestNode);
|
|
3284
3293
|
if (stateRef.current.nodeObjects[String(nodeToSave.id)]) {
|
|
3285
|
-
const
|
|
3286
|
-
|
|
3287
|
-
|
|
3294
|
+
const oldMeshPosition = stateRef.current.nodeObjects[String(nodeToSave.id)].position.clone();
|
|
3295
|
+
setTimeout(() => {
|
|
3296
|
+
if (stateRef.current && stateRef.current.graphGroup) {
|
|
3297
|
+
const pos = oldMeshPosition.clone();
|
|
3298
|
+
pos.x += 12;
|
|
3299
|
+
addStandaloneNodeToScene(stateRef.current, nextQuestNode, pos);
|
|
3300
|
+
}
|
|
3301
|
+
}, 2e3);
|
|
3288
3302
|
}
|
|
3289
3303
|
}
|
|
3290
3304
|
}
|
|
@@ -4221,8 +4235,84 @@ function calculateNextRecurrenceDate(config) {
|
|
|
4221
4235
|
const d = String(nextDate.getDate()).padStart(2, "0");
|
|
4222
4236
|
const m = String(nextDate.getMonth() + 1).padStart(2, "0");
|
|
4223
4237
|
const y = nextDate.getFullYear();
|
|
4224
|
-
return {
|
|
4238
|
+
return {
|
|
4239
|
+
type: "Data",
|
|
4240
|
+
value: `${d}/${m}/${y}`,
|
|
4241
|
+
confirmed: true
|
|
4242
|
+
};
|
|
4225
4243
|
}
|
|
4244
|
+
var parseDate = (str) => {
|
|
4245
|
+
if (!str) return null;
|
|
4246
|
+
const parts = str.split("/");
|
|
4247
|
+
if (parts.length === 3) {
|
|
4248
|
+
const day = parseInt(parts[0], 10);
|
|
4249
|
+
const month = parseInt(parts[1], 10) - 1;
|
|
4250
|
+
const year = parseInt(parts[2], 10);
|
|
4251
|
+
if (!isNaN(day) && !isNaN(month) && !isNaN(year)) {
|
|
4252
|
+
return new Date(year, month, day);
|
|
4253
|
+
}
|
|
4254
|
+
}
|
|
4255
|
+
return null;
|
|
4256
|
+
};
|
|
4257
|
+
var parseDateProp = (dateProp) => {
|
|
4258
|
+
let info = { isUndated: true, label: "", type: "point" };
|
|
4259
|
+
if (!dateProp) return info;
|
|
4260
|
+
if (dateProp.type === "Data") {
|
|
4261
|
+
const d = parseDate(dateProp.value);
|
|
4262
|
+
if (d) {
|
|
4263
|
+
info = { startDate: d, endDate: d, label: dateProp.value, type: "point", isUndated: false };
|
|
4264
|
+
}
|
|
4265
|
+
} else if (dateProp.type === "Date Interval" || dateProp.type === "Date Range" || dateProp.type === "interval") {
|
|
4266
|
+
const sd = parseDate(dateProp.start || dateProp.value);
|
|
4267
|
+
const ed = parseDate(dateProp.end);
|
|
4268
|
+
if (sd) {
|
|
4269
|
+
info = {
|
|
4270
|
+
startDate: sd,
|
|
4271
|
+
endDate: ed || sd,
|
|
4272
|
+
label: `${dateProp.start || dateProp.value}${ed ? " - " + dateProp.end : ""}`,
|
|
4273
|
+
type: ed ? "interval" : "point",
|
|
4274
|
+
isUndated: false
|
|
4275
|
+
};
|
|
4276
|
+
}
|
|
4277
|
+
} else if (dateProp.date) {
|
|
4278
|
+
const d = parseDate(dateProp.date);
|
|
4279
|
+
if (d)
|
|
4280
|
+
info = {
|
|
4281
|
+
startDate: d,
|
|
4282
|
+
endDate: d,
|
|
4283
|
+
label: dateProp.date,
|
|
4284
|
+
type: "point",
|
|
4285
|
+
isUndated: false
|
|
4286
|
+
};
|
|
4287
|
+
} else if (dateProp.year) {
|
|
4288
|
+
const y = parseInt(dateProp.year, 10);
|
|
4289
|
+
if (!isNaN(y)) {
|
|
4290
|
+
const d = new Date(y, 0, 1);
|
|
4291
|
+
info = {
|
|
4292
|
+
startDate: d,
|
|
4293
|
+
endDate: d,
|
|
4294
|
+
label: String(y),
|
|
4295
|
+
type: "point",
|
|
4296
|
+
isUndated: false
|
|
4297
|
+
};
|
|
4298
|
+
}
|
|
4299
|
+
} else if (dateProp.date_interval && dateProp.date_interval.start) {
|
|
4300
|
+
const sY = parseInt(dateProp.date_interval.start, 10);
|
|
4301
|
+
const eY = parseInt(dateProp.date_interval.end, 10) || sY;
|
|
4302
|
+
if (!isNaN(sY)) {
|
|
4303
|
+
const sd = new Date(sY, 0, 1);
|
|
4304
|
+
const ed = new Date(eY, 11, 31);
|
|
4305
|
+
info = {
|
|
4306
|
+
startDate: sd,
|
|
4307
|
+
endDate: ed,
|
|
4308
|
+
label: `${sY} - ${eY}`,
|
|
4309
|
+
type: "interval",
|
|
4310
|
+
isUndated: false
|
|
4311
|
+
};
|
|
4312
|
+
}
|
|
4313
|
+
}
|
|
4314
|
+
return info;
|
|
4315
|
+
};
|
|
4226
4316
|
|
|
4227
4317
|
// src/components/CustomPropertyDisplay.jsx
|
|
4228
4318
|
import React3, { useState as useState4, useRef as useRef3, useEffect as useEffect3 } from "react";
|
|
@@ -9487,7 +9577,7 @@ function InSceneQuestForm({
|
|
|
9487
9577
|
textureImageUrl: null,
|
|
9488
9578
|
reviewStack,
|
|
9489
9579
|
timeline: initialTimeline,
|
|
9490
|
-
Date: questDate,
|
|
9580
|
+
Date: questDate ? { ...questDate, confirmed: true } : null,
|
|
9491
9581
|
recurrence_config: recurrenceConfig,
|
|
9492
9582
|
...additionalData
|
|
9493
9583
|
});
|
|
@@ -10963,7 +11053,7 @@ ${noteText}` : noteText : entry.notes,
|
|
|
10963
11053
|
description_sections: processedSections,
|
|
10964
11054
|
intensity,
|
|
10965
11055
|
recurrence_config: currentRecurrenceConfig,
|
|
10966
|
-
Date: questDate,
|
|
11056
|
+
Date: questDate ? { ...questDate, confirmed: true } : null,
|
|
10967
11057
|
useImageAsTexture: false,
|
|
10968
11058
|
textureImageUrl: null,
|
|
10969
11059
|
is_quest: true,
|
|
@@ -13539,7 +13629,7 @@ function XViewScene({
|
|
|
13539
13629
|
}
|
|
13540
13630
|
}
|
|
13541
13631
|
Object.values(nodeObjects).forEach((mesh) => {
|
|
13542
|
-
const oldLabel = mesh.getObjectByName("timelineLabel")
|
|
13632
|
+
const oldLabel = mesh.getObjectByName("timelineLabel");
|
|
13543
13633
|
if (oldLabel) {
|
|
13544
13634
|
mesh.remove(oldLabel);
|
|
13545
13635
|
if (oldLabel.material.map) oldLabel.material.map.dispose();
|
|
@@ -13550,7 +13640,7 @@ function XViewScene({
|
|
|
13550
13640
|
});
|
|
13551
13641
|
const timelineNodes = [];
|
|
13552
13642
|
const allTimePoints = /* @__PURE__ */ new Set();
|
|
13553
|
-
const
|
|
13643
|
+
const parseDate2 = (str) => {
|
|
13554
13644
|
const parts = str.split("/");
|
|
13555
13645
|
if (parts.length === 3) {
|
|
13556
13646
|
const day = parseInt(parts[0], 10);
|
|
@@ -13567,7 +13657,7 @@ function XViewScene({
|
|
|
13567
13657
|
let nodeInfo = { mesh, type: "point", label: "", isUndated: true };
|
|
13568
13658
|
if (dateProp) {
|
|
13569
13659
|
if (dateProp.date) {
|
|
13570
|
-
const date =
|
|
13660
|
+
const date = parseDate2(dateProp.date);
|
|
13571
13661
|
if (date) {
|
|
13572
13662
|
nodeInfo.startDate = date;
|
|
13573
13663
|
nodeInfo.endDate = date;
|
|
@@ -13713,7 +13803,7 @@ function XViewScene({
|
|
|
13713
13803
|
});
|
|
13714
13804
|
const timelineNodes = [];
|
|
13715
13805
|
const allTimePoints = /* @__PURE__ */ new Set();
|
|
13716
|
-
const
|
|
13806
|
+
const parseDate2 = (str) => {
|
|
13717
13807
|
const parts = str.split("/");
|
|
13718
13808
|
if (parts.length === 3) {
|
|
13719
13809
|
const day = parseInt(parts[0], 10);
|
|
@@ -13730,7 +13820,7 @@ function XViewScene({
|
|
|
13730
13820
|
if (!dateProp) return;
|
|
13731
13821
|
let nodeInfo = { mesh, type: "point", label: "" };
|
|
13732
13822
|
if (dateProp.date) {
|
|
13733
|
-
const date =
|
|
13823
|
+
const date = parseDate2(dateProp.date);
|
|
13734
13824
|
if (date) {
|
|
13735
13825
|
nodeInfo.startDate = date;
|
|
13736
13826
|
nodeInfo.endDate = date;
|
|
@@ -13972,16 +14062,8 @@ function XViewScene({
|
|
|
13972
14062
|
);
|
|
13973
14063
|
const handleActivateQuestLens = useCallback4(({ assigneeId, status: status2 }) => {
|
|
13974
14064
|
var _a2;
|
|
13975
|
-
const { nodeObjects, tweenGroup, graphGroup
|
|
14065
|
+
const { nodeObjects, tweenGroup, graphGroup } = stateRef.current;
|
|
13976
14066
|
if (!nodeObjects || !tweenGroup || !graphGroup) return;
|
|
13977
|
-
Object.values(nodeObjects).forEach((mesh) => {
|
|
13978
|
-
const oldLabel = mesh.getObjectByName("questDateLabel") || mesh.getObjectByName("timelineLabel");
|
|
13979
|
-
if (oldLabel) {
|
|
13980
|
-
mesh.remove(oldLabel);
|
|
13981
|
-
if (oldLabel.material.map) oldLabel.material.map.dispose();
|
|
13982
|
-
oldLabel.material.dispose();
|
|
13983
|
-
}
|
|
13984
|
-
});
|
|
13985
14067
|
const allQuests = ((_a2 = sceneDataRef.current) == null ? void 0 : _a2.quest_nodes) || [];
|
|
13986
14068
|
const filteredQuests = allQuests.filter((q) => {
|
|
13987
14069
|
const matchAssignee = !assigneeId || String(q.assignee_id) === String(assigneeId);
|
|
@@ -14003,61 +14085,39 @@ function XViewScene({
|
|
|
14003
14085
|
questsByStatus[q.status].push(q);
|
|
14004
14086
|
}
|
|
14005
14087
|
});
|
|
14006
|
-
const parseDate = (str) => {
|
|
14007
|
-
if (!str) return null;
|
|
14008
|
-
const parts = str.split("/");
|
|
14009
|
-
if (parts.length === 3) {
|
|
14010
|
-
const day = parseInt(parts[0], 10);
|
|
14011
|
-
const month = parseInt(parts[1], 10) - 1;
|
|
14012
|
-
const year = parseInt(parts[2], 10);
|
|
14013
|
-
if (!isNaN(day) && !isNaN(month) && !isNaN(year)) {
|
|
14014
|
-
return new Date(year, month, day);
|
|
14015
|
-
}
|
|
14016
|
-
}
|
|
14017
|
-
return null;
|
|
14018
|
-
};
|
|
14019
|
-
const timePoints = /* @__PURE__ */ new Set();
|
|
14020
14088
|
const questTimeInfos = /* @__PURE__ */ new Map();
|
|
14089
|
+
const allActiveTimePoints = /* @__PURE__ */ new Set();
|
|
14021
14090
|
filteredQuests.forEach((q) => {
|
|
14022
|
-
const
|
|
14023
|
-
|
|
14024
|
-
if (
|
|
14025
|
-
|
|
14026
|
-
|
|
14027
|
-
|
|
14028
|
-
info = { startDate: d, endDate: d, label: dateProp.date, isUndated: false };
|
|
14029
|
-
timePoints.add(d.getTime());
|
|
14030
|
-
}
|
|
14031
|
-
} else if (dateProp.year) {
|
|
14032
|
-
const y = parseInt(dateProp.year, 10);
|
|
14033
|
-
if (!isNaN(y)) {
|
|
14034
|
-
const d = new Date(y, 0, 1);
|
|
14035
|
-
info = { startDate: d, endDate: d, label: String(y), isUndated: false };
|
|
14036
|
-
timePoints.add(d.getTime());
|
|
14037
|
-
}
|
|
14038
|
-
} else if (dateProp.date_interval && dateProp.date_interval.start) {
|
|
14039
|
-
const sY = parseInt(dateProp.date_interval.start, 10);
|
|
14040
|
-
const eY = parseInt(dateProp.date_interval.end, 10) || sY;
|
|
14041
|
-
if (!isNaN(sY)) {
|
|
14042
|
-
const sd = new Date(sY, 0, 1);
|
|
14043
|
-
const ed = new Date(eY, 11, 31);
|
|
14044
|
-
info = { startDate: sd, endDate: ed, label: `${sY}-${eY}`, isUndated: false };
|
|
14045
|
-
timePoints.add(sd.getTime());
|
|
14046
|
-
timePoints.add(ed.getTime());
|
|
14047
|
-
}
|
|
14091
|
+
const info = parseDateProp(q.Date);
|
|
14092
|
+
questTimeInfos.set(String(q.id), info);
|
|
14093
|
+
if (!info.isUndated) {
|
|
14094
|
+
allActiveTimePoints.add(info.startDate.getTime());
|
|
14095
|
+
if (info.endDate && info.type === "interval") {
|
|
14096
|
+
allActiveTimePoints.add(info.endDate.getTime());
|
|
14048
14097
|
}
|
|
14049
14098
|
}
|
|
14050
|
-
questTimeInfos.set(String(q.id), info);
|
|
14051
14099
|
});
|
|
14052
|
-
const sortedTimePoints = Array.from(
|
|
14100
|
+
const sortedTimePoints = Array.from(allActiveTimePoints).sort((a, b) => a - b);
|
|
14053
14101
|
const timeToYMap = /* @__PURE__ */ new Map();
|
|
14054
|
-
|
|
14055
|
-
|
|
14056
|
-
|
|
14057
|
-
timeToYMap.set(t, (i - maxIdx) * (QUEST_LENS_ROW_SPACING || 30));
|
|
14058
|
-
});
|
|
14059
|
-
}
|
|
14102
|
+
sortedTimePoints.forEach((ms, idx) => {
|
|
14103
|
+
timeToYMap.set(ms, idx * TIMELINE_LAYER_SPACING_Y);
|
|
14104
|
+
});
|
|
14060
14105
|
const startX = -((QUEST_STATUS_ORDER.length - 1) * QUEST_LENS_COLUMN_SPACING) / 2;
|
|
14106
|
+
Object.values(nodeObjects).forEach((mesh) => {
|
|
14107
|
+
const oldLabel = mesh.getObjectByName("questDateLabel") || mesh.getObjectByName("timelineLabel");
|
|
14108
|
+
if (oldLabel) {
|
|
14109
|
+
mesh.remove(oldLabel);
|
|
14110
|
+
if (oldLabel.material) oldLabel.material.dispose();
|
|
14111
|
+
}
|
|
14112
|
+
if (mesh.userData.timelineIntervalBar) {
|
|
14113
|
+
if (graphGroup) graphGroup.remove(mesh.userData.timelineIntervalBar);
|
|
14114
|
+
mesh.userData.timelineIntervalBar = null;
|
|
14115
|
+
}
|
|
14116
|
+
if (mesh.userData.timelineEndLabel) {
|
|
14117
|
+
if (graphGroup) graphGroup.remove(mesh.userData.timelineEndLabel);
|
|
14118
|
+
mesh.userData.timelineEndLabel = null;
|
|
14119
|
+
}
|
|
14120
|
+
});
|
|
14061
14121
|
Object.keys(nodeObjects).forEach((id) => {
|
|
14062
14122
|
const mesh = nodeObjects[id];
|
|
14063
14123
|
const isFilteredQuest = filteredQuests.some(
|
|
@@ -14099,20 +14159,53 @@ function XViewScene({
|
|
|
14099
14159
|
targetY = timeToYMap.get(timeInfo.startDate.getTime());
|
|
14100
14160
|
} else {
|
|
14101
14161
|
const undatedOffset = sortedTimePoints.length > 0 ? sortedTimePoints.length * 5 : 0;
|
|
14102
|
-
targetY = -
|
|
14162
|
+
targetY = -40 - rowIndex * QUEST_LENS_ROW_SPACING - undatedOffset;
|
|
14103
14163
|
}
|
|
14104
14164
|
const lensTween = new Tween2(mesh.position).to({ x: colX, y: targetY, z: 0 }, 1500).easing(Easing2.Cubic.InOut);
|
|
14105
14165
|
tweenGroup.add(lensTween);
|
|
14106
14166
|
lensTween.start();
|
|
14107
|
-
if (!timeInfo.isUndated && timeInfo.label) {
|
|
14167
|
+
if (!timeInfo.isUndated && timeInfo.label && !mesh.getObjectByName("questDateLabel")) {
|
|
14108
14168
|
const dateSprite = createTextSprite(timeInfo.label, 36);
|
|
14109
14169
|
dateSprite.name = "questDateLabel";
|
|
14110
14170
|
dateSprite.position.set(0, -5.5, 0);
|
|
14111
14171
|
mesh.add(dateSprite);
|
|
14112
14172
|
}
|
|
14173
|
+
if (timeInfo.type === "interval" && timeToYMap.has(timeInfo.endDate.getTime())) {
|
|
14174
|
+
const endY = timeToYMap.get(timeInfo.endDate.getTime());
|
|
14175
|
+
if (Math.abs(endY - targetY) > 0.1) {
|
|
14176
|
+
const barHeight = Math.abs(endY - targetY);
|
|
14177
|
+
const barGeometry = new THREE3.CylinderGeometry(
|
|
14178
|
+
TIMELINE_INTERVAL_BAR_RADIUS,
|
|
14179
|
+
TIMELINE_INTERVAL_BAR_RADIUS,
|
|
14180
|
+
1,
|
|
14181
|
+
16
|
|
14182
|
+
);
|
|
14183
|
+
const barMaterial = new THREE3.MeshStandardMaterial({
|
|
14184
|
+
color: TIMELINE_GOLD_COLOR,
|
|
14185
|
+
emissive: 12092939,
|
|
14186
|
+
emissiveIntensity: 0.4,
|
|
14187
|
+
transparent: true,
|
|
14188
|
+
opacity: TIMELINE_INTERVAL_BAR_OPACITY,
|
|
14189
|
+
roughness: 0.3,
|
|
14190
|
+
metalness: 0.8
|
|
14191
|
+
});
|
|
14192
|
+
const intervalBar = new THREE3.Mesh(barGeometry, barMaterial);
|
|
14193
|
+
intervalBar.userData.associatedNodeId = mesh.userData.id;
|
|
14194
|
+
const endPosition = new THREE3.Vector3(colX, endY, -0.5);
|
|
14195
|
+
intervalBar.position.set(colX, (targetY + endY) / 2, -0.5);
|
|
14196
|
+
intervalBar.scale.y = barHeight;
|
|
14197
|
+
graphGroup.add(intervalBar);
|
|
14198
|
+
mesh.userData.timelineIntervalBar = intervalBar;
|
|
14199
|
+
const endLabel = createTextSprite(timeInfo.label.split(" - ")[1] || "", 30);
|
|
14200
|
+
endLabel.name = "timelineEndLabel";
|
|
14201
|
+
endLabel.position.set(colX, endY + 4, 0);
|
|
14202
|
+
graphGroup.add(endLabel);
|
|
14203
|
+
mesh.userData.timelineEndLabel = endLabel;
|
|
14204
|
+
}
|
|
14205
|
+
}
|
|
14113
14206
|
if (mesh.userData.labelObject) {
|
|
14114
14207
|
const labelTargetPos = new THREE3.Vector3(colX, targetY, 0).add(
|
|
14115
|
-
mesh.userData.labelOffset || new THREE3.Vector3(0,
|
|
14208
|
+
mesh.userData.labelOffset || new THREE3.Vector3(0, 3.8, 0)
|
|
14116
14209
|
);
|
|
14117
14210
|
const labelTween = new Tween2(mesh.userData.labelObject.position).to(labelTargetPos, 1500).easing(Easing2.Cubic.InOut);
|
|
14118
14211
|
tweenGroup.add(labelTween);
|
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.44",
|
|
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",
|