| Line 51... |
Line 51... |
| 51 |
var uid = $('#bp-auth-user').val();
|
51 |
var uid = $('#bp-auth-user').val();
|
| 52 |
if (!uid) {
|
52 |
if (!uid) {
|
| 53 |
alert('Select a user');
|
53 |
alert('Select a user');
|
| 54 |
return;
|
54 |
return;
|
| 55 |
}
|
55 |
}
|
| - |
|
56 |
|
| - |
|
57 |
// Hard reset of any previous user's cached state so calendar chips,
|
| - |
|
58 |
// route lines, partner markers, and the route-detail view don't leak.
|
| 56 |
state.authUserId = parseInt(uid);
|
59 |
state.authUserId = parseInt(uid);
|
| 57 |
state.categoryId = parseInt($('#bp-category').val());
|
60 |
state.categoryId = parseInt($('#bp-category').val());
|
| - |
|
61 |
state.mode = 'list';
|
| - |
|
62 |
state.days = [];
|
| - |
|
63 |
state.partners = [];
|
| - |
|
64 |
state.currentDay = 1;
|
| - |
|
65 |
state.calMonth = null;
|
| - |
|
66 |
state.calData = null;
|
| - |
|
67 |
state.calSelectedBeat = null;
|
| - |
|
68 |
state.calPickedDates = [];
|
| - |
|
69 |
state.homeLat = null;
|
| - |
|
70 |
state.homeLng = null;
|
| - |
|
71 |
state.homeName = '';
|
| - |
|
72 |
state.activeBaseLocationId = null;
|
| - |
|
73 |
state.baseLocations = [];
|
| - |
|
74 |
state.viewDate = null;
|
| - |
|
75 |
state.originalDayCount = 0;
|
| - |
|
76 |
// Clear the rendered calendar grid + route map / panel so nothing from
|
| - |
|
77 |
// the previous user is briefly visible while the new fetch is in flight.
|
| - |
|
78 |
$('#cal-grid-content').empty();
|
| - |
|
79 |
$('#route-list').empty();
|
| - |
|
80 |
if (typeof clearRoute === 'function') {
|
| - |
|
81 |
try {
|
| - |
|
82 |
clearRoute();
|
| - |
|
83 |
} catch (e) {
|
| - |
|
84 |
}
|
| - |
|
85 |
}
|
| 58 |
state.mode = 'list'; // 'list' or 'create' or 'view'
|
86 |
if (typeof markers === 'object' && markers) {
|
| - |
|
87 |
for (var k in markers) {
|
| - |
|
88 |
try {
|
| - |
|
89 |
markers[k].setMap(null);
|
| - |
|
90 |
} catch (e) {
|
| - |
|
91 |
}
|
| - |
|
92 |
}
|
| - |
|
93 |
markers = {};
|
| - |
|
94 |
}
|
| - |
|
95 |
if (typeof homeMarker !== 'undefined' && homeMarker) {
|
| - |
|
96 |
try {
|
| - |
|
97 |
homeMarker.setMap(null);
|
| - |
|
98 |
} catch (e) {
|
| - |
|
99 |
}
|
| - |
|
100 |
homeMarker = null;
|
| - |
|
101 |
}
|
| - |
|
102 |
|
| 59 |
$('#bp-user-label').text($('#bp-auth-user option:selected').text());
|
103 |
$('#bp-user-label').text($('#bp-auth-user option:selected').text());
|
| 60 |
|
104 |
|
| 61 |
// Load all saved base locations — default goes in state.home*, the rest is
|
105 |
// Load all saved base locations — default goes in state.home*, the rest is
|
| 62 |
// exposed via a picker in the route panel so the planner can pick a
|
106 |
// exposed via a picker in the route panel so the planner can pick a
|
| 63 |
// different starting point for this one beat without changing the default.
|
107 |
// different starting point for this one beat without changing the default.
|
| Line 77... |
Line 121... |
| 77 |
state.activeBaseLocationId = def.id;
|
121 |
state.activeBaseLocationId = def.id;
|
| 78 |
} else {
|
122 |
} else {
|
| 79 |
state.activeBaseLocationId = null;
|
123 |
state.activeBaseLocationId = null;
|
| 80 |
}
|
124 |
}
|
| 81 |
showBeatList();
|
125 |
showBeatList();
|
| - |
|
126 |
// If the user is currently on the Calendar tab when Load is clicked,
|
| - |
|
127 |
// re-fetch immediately. Otherwise the calendar grid stays blank
|
| - |
|
128 |
// until they click the tab (which would auto-fetch on its own).
|
| - |
|
129 |
if ($('.panel-tab[data-tab="calendar"]').hasClass('active')) {
|
| - |
|
130 |
var now = new Date();
|
| - |
|
131 |
state.calMonth = now.getFullYear() + '-' + ('0' + (now.getMonth() + 1)).slice(-2);
|
| - |
|
132 |
loadCalendarData();
|
| - |
|
133 |
}
|
| 82 |
}
|
134 |
}
|
| 83 |
});
|
135 |
});
|
| 84 |
});
|
136 |
});
|
| 85 |
|
137 |
|
| 86 |
// Called from the picker → swap the start location for the beat being
|
138 |
// Called from the picker → swap the start location for the beat being
|
| Line 1921... |
Line 1973... |
| 1921 |
row += '<td class="' + cls.join(' ') + '" data-date="' + ds + '" data-hasbeat="' + (hasBeats ? '1' : '0') + '" style="' + style + '">';
|
1973 |
row += '<td class="' + cls.join(' ') + '" data-date="' + ds + '" data-hasbeat="' + (hasBeats ? '1' : '0') + '" style="' + style + '">';
|
| 1922 |
row += '<div class="cal-date">' + d.getDate() + '</div>';
|
1974 |
row += '<div class="cal-date">' + d.getDate() + '</div>';
|
| 1923 |
if (hol) row += '<div class="cal-holiday-label">' + holidayMap[ds] + '</div>';
|
1975 |
if (hol) row += '<div class="cal-holiday-label">' + holidayMap[ds] + '</div>';
|
| 1924 |
|
1976 |
|
| 1925 |
beats.forEach(function (b) {
|
1977 |
beats.forEach(function (b) {
|
| - |
|
1978 |
// The "running"/[live] state only applies to TODAY's chip — future
|
| - |
|
1979 |
// chips of the same beat are still freely editable (drag + ×).
|
| - |
|
1980 |
// Past chips are always locked.
|
| - |
|
1981 |
var isLiveChip = b.status === 'running' && isToday;
|
| - |
|
1982 |
var isLockedChip = isPast || isLiveChip;
|
| - |
|
1983 |
|
| 1926 |
var chipCls = 'cal-chip';
|
1984 |
var chipCls = 'cal-chip';
|
| 1927 |
if (b.status === 'running') chipCls += ' running';
|
1985 |
if (isLiveChip) chipCls += ' running';
|
| 1928 |
if (b.status === 'completed') chipCls += ' completed';
|
1986 |
if (b.status === 'completed') chipCls += ' completed';
|
| 1929 |
var removeBtn = (!isPast && b.status !== 'running' && b.status !== 'completed')
|
1987 |
var removeBtn = !isLockedChip
|
| 1930 |
? '<span class="cal-chip-remove" data-date="' + ds + '" data-plangroup="' + (b.planGroupId || '') + '" title="Remove">×</span>'
|
1988 |
? '<span class="cal-chip-remove" data-date="' + ds + '" data-plangroup="' + (b.planGroupId || '') + '" title="Remove">×</span>'
|
| 1931 |
: '';
|
1989 |
: '';
|
| 1932 |
var draggable = (!isPast && b.status !== 'running' && b.status !== 'completed') ? ' draggable="true"' : '';
|
1990 |
var draggable = !isLockedChip ? ' draggable="true"' : '';
|
| 1933 |
var cursor = draggable ? 'grab' : 'pointer';
|
1991 |
var cursor = draggable ? 'grab' : 'pointer';
|
| 1934 |
row += '<span class="' + chipCls + ' cal-chip-view"' + draggable + ' data-plangroup="' + (b.planGroupId || '') + '" data-date="' + ds + '" style="background:' + b.color + ';position:relative;cursor:' + cursor + ';" title="Drag to another date to shuffle">'
|
1992 |
row += '<span class="' + chipCls + ' cal-chip-view"' + draggable + ' data-plangroup="' + (b.planGroupId || '') + '" data-date="' + ds + '" style="background:' + b.color + ';position:relative;cursor:' + cursor + ';" title="Drag to another date to shuffle">'
|
| 1935 |
+ b.name + ' D' + b.day + (b.status === 'running' ? ' [live]' : '') + ' (' + b.visits + ')'
|
1993 |
+ b.name + ' D' + b.day + (isLiveChip ? ' [live]' : '') + ' (' + b.visits + ')'
|
| 1936 |
+ removeBtn + '</span>';
|
1994 |
+ removeBtn + '</span>';
|
| 1937 |
});
|
1995 |
});
|
| 1938 |
|
1996 |
|
| 1939 |
if (isPicked) {
|
1997 |
if (isPicked) {
|
| 1940 |
var idx = state.calPickedDates.indexOf(ds) + 1;
|
1998 |
var idx = state.calPickedDates.indexOf(ds) + 1;
|
| Line 2382... |
Line 2440... |
| 2382 |
$(this).css('opacity', '');
|
2440 |
$(this).css('opacity', '');
|
| 2383 |
});
|
2441 |
});
|
| 2384 |
|
2442 |
|
| 2385 |
$(document).on('dragover', '.cal-grid td', function (e) {
|
2443 |
$(document).on('dragover', '.cal-grid td', function (e) {
|
| 2386 |
var $td = $(this);
|
2444 |
var $td = $(this);
|
| - |
|
2445 |
// Today is the live/running slot — nothing can be shuffled onto it. The
|
| - |
|
2446 |
// shuffle is only valid between future dates.
|
| 2387 |
if ($td.hasClass('past') || $td.hasClass('blocked') || $td.hasClass('holiday') || $td.hasClass('sunday')) return;
|
2447 |
if ($td.hasClass('past') || $td.hasClass('blocked') || $td.hasClass('holiday') || $td.hasClass('sunday') || $td.hasClass('today')) return;
|
| 2388 |
e.preventDefault();
|
2448 |
e.preventDefault();
|
| 2389 |
e.originalEvent.dataTransfer.dropEffect = 'move';
|
2449 |
e.originalEvent.dataTransfer.dropEffect = 'move';
|
| 2390 |
$td.css('box-shadow', 'inset 0 0 0 2px #60a5fa');
|
2450 |
$td.css('box-shadow', 'inset 0 0 0 2px #60a5fa');
|
| 2391 |
});
|
2451 |
});
|
| 2392 |
|
2452 |
|
| Line 2395... |
Line 2455... |
| 2395 |
});
|
2455 |
});
|
| 2396 |
|
2456 |
|
| 2397 |
$(document).on('drop', '.cal-grid td', function (e) {
|
2457 |
$(document).on('drop', '.cal-grid td', function (e) {
|
| 2398 |
var $td = $(this);
|
2458 |
var $td = $(this);
|
| 2399 |
$td.css('box-shadow', '');
|
2459 |
$td.css('box-shadow', '');
|
| 2400 |
if ($td.hasClass('past') || $td.hasClass('blocked') || $td.hasClass('holiday') || $td.hasClass('sunday')) return;
|
2460 |
if ($td.hasClass('past') || $td.hasClass('blocked') || $td.hasClass('holiday') || $td.hasClass('sunday') || $td.hasClass('today')) return;
|
| 2401 |
e.preventDefault();
|
2461 |
e.preventDefault();
|
| 2402 |
|
2462 |
|
| 2403 |
var raw;
|
2463 |
var raw;
|
| 2404 |
try {
|
2464 |
try {
|
| 2405 |
raw = e.originalEvent.dataTransfer.getData('text/plain');
|
2465 |
raw = e.originalEvent.dataTransfer.getData('text/plain');
|