fix(project): 드래그 후 모달 재오픈 방지 + 타임라인 한글 날짜·휠 좌우이동
- 드래그 이동 후 location.reload() 시 URL 의 ?task= 가 남아 업무 모달이 다시 뜨던 문제 수정: ?task 처리 직후 history.replaceState 로 파라미터 제거 - 타임라인 날짜 라벨 한글화(format minor/major 함수: 'M월 D일 (요일)', 'YYYY년 M월') - 타임라인 마우스 휠 = 좌우 이동(horizontalScroll), 확대/축소는 Ctrl+휠 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
{% extends "erp_base.html" %}
|
{% extends "erp_base.html" %}
|
||||||
|
|
||||||
{% block head_extra %}
|
{% block head_extra %}
|
||||||
<link rel="stylesheet" href="/static/project.css?v=20260625k" />
|
<link rel="stylesheet" href="/static/project.css?v=20260625l" />
|
||||||
<link rel="stylesheet" href="/static/vendor/material-symbols/material-symbols.css" />
|
<link rel="stylesheet" href="/static/vendor/material-symbols/material-symbols.css" />
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
@@ -45,5 +45,5 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="/static/project.js?v=20260625k" defer></script>
|
<script src="/static/project.js?v=20260625l" defer></script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{% extends "erp_base.html" %}
|
{% extends "erp_base.html" %}
|
||||||
|
|
||||||
{% block head_extra %}
|
{% block head_extra %}
|
||||||
<link rel="stylesheet" href="/static/project.css?v=20260625k" />
|
<link rel="stylesheet" href="/static/project.css?v=20260625l" />
|
||||||
<link rel="stylesheet" href="/static/vendor/material-symbols/material-symbols.css" />
|
<link rel="stylesheet" href="/static/vendor/material-symbols/material-symbols.css" />
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
@@ -100,5 +100,5 @@
|
|||||||
<script>
|
<script>
|
||||||
window.PJ_COLORS = {{ ["#4573d2","#37a3a3","#62a420","#e8a33d","#e8384f","#aa62e3","#f06a6a","#5a6772"] | tojson }};
|
window.PJ_COLORS = {{ ["#4573d2","#37a3a3","#62a420","#e8a33d","#e8384f","#aa62e3","#f06a6a","#5a6772"] | tojson }};
|
||||||
</script>
|
</script>
|
||||||
<script src="/static/project.js?v=20260625k" defer></script>
|
<script src="/static/project.js?v=20260625l" defer></script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{% extends "erp_base.html" %}
|
{% extends "erp_base.html" %}
|
||||||
|
|
||||||
{% block head_extra %}
|
{% block head_extra %}
|
||||||
<link rel="stylesheet" href="/static/project.css?v=20260625k" />
|
<link rel="stylesheet" href="/static/project.css?v=20260625l" />
|
||||||
<!-- 구글 머티리얼 심볼(담당자 아이콘 등) — self-host -->
|
<!-- 구글 머티리얼 심볼(담당자 아이콘 등) — self-host -->
|
||||||
<link rel="stylesheet" href="/static/vendor/material-symbols/material-symbols.css" />
|
<link rel="stylesheet" href="/static/vendor/material-symbols/material-symbols.css" />
|
||||||
<!-- 타임라인 vis-timeline — self-host -->
|
<!-- 타임라인 vis-timeline — self-host -->
|
||||||
@@ -290,5 +290,5 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script src="/static/vendor/vis-timeline/vis-timeline-graph2d.min.js"></script>
|
<script src="/static/vendor/vis-timeline/vis-timeline-graph2d.min.js"></script>
|
||||||
<script src="/static/project.js?v=20260625k" defer></script>
|
<script src="/static/project.js?v=20260625l" defer></script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
+39
-3
@@ -242,9 +242,39 @@
|
|||||||
});
|
});
|
||||||
if (timeline) { timeline.destroy(); timeline = null; }
|
if (timeline) { timeline.destroy(); timeline = null; }
|
||||||
if (!items.length) { node.innerHTML = '<div class="pj-empty">기간이 설정된 업무가 없습니다.</div>'; return; }
|
if (!items.length) { node.innerHTML = '<div class="pj-empty">기간이 설정된 업무가 없습니다.</div>'; return; }
|
||||||
|
const koWd = function (d) { return ["일", "월", "화", "수", "목", "금", "토"][d.getDay()]; };
|
||||||
|
const pad2 = function (n) { return ("0" + n).slice(-2); };
|
||||||
timeline = new vis.Timeline(node, new vis.DataSet(items), {
|
timeline = new vis.Timeline(node, new vis.DataSet(items), {
|
||||||
locale: "ko", stack: true, height: "520px", zoomKey: "ctrlKey",
|
stack: true, height: "520px",
|
||||||
|
horizontalScroll: true, // 마우스 휠 = 좌우 이동(패닝)
|
||||||
|
verticalScroll: false,
|
||||||
|
zoomKey: "ctrlKey", // 확대/축소는 Ctrl+휠
|
||||||
margin: { item: 8 },
|
margin: { item: 8 },
|
||||||
|
format: {
|
||||||
|
minorLabels: function (date, scale) {
|
||||||
|
const d = new Date(date.valueOf());
|
||||||
|
switch (scale) {
|
||||||
|
case "millisecond": case "second": case "minute": case "hour":
|
||||||
|
return pad2(d.getHours()) + ":" + pad2(d.getMinutes());
|
||||||
|
case "weekday": case "day": return d.getDate() + "일 (" + koWd(d) + ")";
|
||||||
|
case "week": return d.getDate() + "일";
|
||||||
|
case "month": return (d.getMonth() + 1) + "월";
|
||||||
|
case "year": return d.getFullYear() + "년";
|
||||||
|
default: return d.getDate() + "일";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
majorLabels: function (date, scale) {
|
||||||
|
const d = new Date(date.valueOf());
|
||||||
|
switch (scale) {
|
||||||
|
case "millisecond": case "second": case "minute": case "hour":
|
||||||
|
return (d.getMonth() + 1) + "월 " + d.getDate() + "일 (" + koWd(d) + ")";
|
||||||
|
case "weekday": case "day": case "week":
|
||||||
|
return d.getFullYear() + "년 " + (d.getMonth() + 1) + "월";
|
||||||
|
case "month": return d.getFullYear() + "년";
|
||||||
|
default: return "";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
timeline.on("select", function (props) {
|
timeline.on("select", function (props) {
|
||||||
if (!canManage || !props.items.length) return;
|
if (!canManage || !props.items.length) return;
|
||||||
@@ -709,9 +739,15 @@
|
|||||||
// 최초 렌더 — 달력은 서버 렌더, 클릭 핸들러만 연결
|
// 최초 렌더 — 달력은 서버 렌더, 클릭 핸들러만 연결
|
||||||
wireCalendar();
|
wireCalendar();
|
||||||
|
|
||||||
// 사이드 트리에서 업무 클릭(?task=ID)으로 들어오면 해당 업무 모달 자동 열기
|
// 사이드 트리에서 업무 클릭(?task=ID)으로 들어오면 해당 업무 모달 자동 열기.
|
||||||
const taskParam = new URLSearchParams(location.search).get("task");
|
// 단, 처리 후 URL 에서 task 파라미터를 제거한다 — 드래그 이동 후 location.reload()
|
||||||
|
// 시 이 파라미터가 남아 모달이 다시 뜨는 것을 방지.
|
||||||
|
const params = new URLSearchParams(location.search);
|
||||||
|
const taskParam = params.get("task");
|
||||||
if (taskParam) {
|
if (taskParam) {
|
||||||
|
params.delete("task");
|
||||||
|
const qs = params.toString();
|
||||||
|
history.replaceState({}, "", location.pathname + (qs ? "?" + qs : ""));
|
||||||
const t = tasks.find(function (x) { return String(x.id) === String(taskParam); });
|
const t = tasks.find(function (x) { return String(x.id) === String(taskParam); });
|
||||||
if (t) openTaskModal(t);
|
if (t) openTaskModal(t);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user