Implement schedule WYSIWYG and UTC dates
This commit is contained in:
@@ -4,6 +4,7 @@ const { fetchAdminData, fetchPlaylistsPage, fetchSlidesPage, fetchTemplatesPage,
|
||||
const { ANNOUNCEMENT_TYPES, ANNOUNCEMENT_COLORS, ANNOUNCEMENT_ICONS, DEFAULT_ANNOUNCEMENT_ICON, normalizeAnnouncementType, normalizeAnnouncementColor, normalizeAnnouncementIcon, fetchAnnouncementsPage, fetchAnnouncementById, fetchActiveAnnouncement, buildAnnouncementPayload } = require('./announcements');
|
||||
const { ANNOUNCEMENT_ICON_OPTIONS, ANNOUNCEMENT_ICON_LABELS } = require('./announcement-icons');
|
||||
const { fetchPlaylistById } = require('./playlists');
|
||||
const { normalizeDisplayMode, fetchSchedulesData, fetchScheduleGroupsPage, fetchScheduleGroupById, fetchScheduleEntriesByGroupId, buildScheduleGroupPayload } = require('./schedules');
|
||||
const { fetchApiSourcesData, fetchApiSourcesPage, fetchApiSourceById, fetchApiSourceResponse, buildApiSourcePayload } = require('./api-sources');
|
||||
const { fetchRssFeedsData, fetchRssFeedsPage, fetchRssFeedById, fetchRssFeedItemsByFeedId, normalizeRssFeedItem, buildRssFeedPayload, fetchRssFeedItems, replaceRssFeedItems } = require('./rss-feeds');
|
||||
const { slugify, uniqueScreenSlug, fetchScreenById, fetchScreenEditData, fetchScreenPlayerUrls, fetchScreenPlayerRecord } = require('./screens');
|
||||
@@ -36,6 +37,12 @@ module.exports = {
|
||||
fetchActiveAnnouncement,
|
||||
buildAnnouncementPayload,
|
||||
fetchPlaylistById,
|
||||
normalizeDisplayMode,
|
||||
fetchSchedulesData,
|
||||
fetchScheduleGroupsPage,
|
||||
fetchScheduleGroupById,
|
||||
fetchScheduleEntriesByGroupId,
|
||||
buildScheduleGroupPayload,
|
||||
fetchApiSourcesData,
|
||||
fetchApiSourcesPage,
|
||||
fetchApiSourceById,
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
// Schedule group and entry data access helpers.
|
||||
|
||||
const { fetchPagedRows } = require('./utils');
|
||||
|
||||
function normalizeDisplayMode(value) {
|
||||
const mode = String(value || 'upcoming').trim().toLowerCase();
|
||||
if (mode === 'current' || mode === 'both') {
|
||||
return mode;
|
||||
}
|
||||
return 'upcoming';
|
||||
}
|
||||
|
||||
async function fetchSchedulesData(pool) {
|
||||
const [scheduleGroups] = await pool.query(`
|
||||
SELECT g.id, g.name, g.short_description, g.created_at, g.modified_at, g.created_by, g.modified_by,
|
||||
(SELECT COUNT(*) FROM i_schedule_entries e WHERE e.schedule_group_id = g.id) AS entry_count,
|
||||
(SELECT MIN(e.start_datetime) FROM i_schedule_entries e WHERE e.schedule_group_id = g.id AND e.start_datetime IS NOT NULL) AS next_start_datetime
|
||||
FROM i_schedule_groups g
|
||||
ORDER BY g.modified_at DESC, g.id DESC
|
||||
`);
|
||||
const [scheduleEntries] = await pool.query(`
|
||||
SELECT id, schedule_group_id, title, short_description, start_datetime, end_datetime, created_at, modified_at, created_by, modified_by
|
||||
FROM i_schedule_entries
|
||||
ORDER BY schedule_group_id ASC, start_datetime ASC, id ASC
|
||||
`);
|
||||
|
||||
const entriesByGroupId = new Map();
|
||||
scheduleEntries.forEach(function (entry) {
|
||||
const groupId = Number(entry.schedule_group_id);
|
||||
if (!entriesByGroupId.has(groupId)) {
|
||||
entriesByGroupId.set(groupId, []);
|
||||
}
|
||||
entriesByGroupId.get(groupId).push(entry);
|
||||
});
|
||||
|
||||
const groups = scheduleGroups.map(function (group) {
|
||||
return Object.assign({}, group, {
|
||||
entries: entriesByGroupId.get(Number(group.id)) || []
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
scheduleGroups: groups,
|
||||
scheduleEntries: scheduleEntries
|
||||
};
|
||||
}
|
||||
|
||||
async function fetchScheduleGroupsPage(pool, page, pageSize, searchTerm, sortKey, sortDirection) {
|
||||
const paged = await fetchPagedRows(pool, {
|
||||
selectSql: `SELECT g.id, g.name, g.short_description, g.created_at, g.modified_at, g.created_by, g.modified_by,
|
||||
(SELECT COUNT(*) FROM i_schedule_entries e WHERE e.schedule_group_id = g.id) AS entry_count,
|
||||
(SELECT MIN(e.start_datetime) FROM i_schedule_entries e WHERE e.schedule_group_id = g.id AND e.start_datetime IS NOT NULL) AS next_start_datetime
|
||||
FROM i_schedule_groups g
|
||||
ORDER BY g.modified_at DESC, g.id DESC`,
|
||||
countSql: 'SELECT COUNT(*) AS count FROM i_schedule_groups',
|
||||
searchColumns: ['g.name', 'g.short_description'],
|
||||
searchTerm: searchTerm,
|
||||
sortColumns: {
|
||||
name: 'g.name',
|
||||
description: 'g.short_description',
|
||||
entries: 'entry_count',
|
||||
next_start: 'next_start_datetime',
|
||||
created: 'g.created_at',
|
||||
modified: 'g.modified_at'
|
||||
},
|
||||
sortKey: sortKey,
|
||||
sortDirection: sortDirection,
|
||||
page: page,
|
||||
pageSize: pageSize
|
||||
});
|
||||
|
||||
return Object.assign({ scheduleGroups: paged.rows }, paged);
|
||||
}
|
||||
|
||||
async function fetchScheduleGroupById(pool, id) {
|
||||
const [rows] = await pool.query(
|
||||
'SELECT id, name, short_description, created_at, modified_at, created_by, modified_by FROM i_schedule_groups WHERE id = ?',
|
||||
[id]
|
||||
);
|
||||
|
||||
return rows[0] || null;
|
||||
}
|
||||
|
||||
async function fetchScheduleEntriesByGroupId(pool, scheduleGroupId) {
|
||||
const [rows] = await pool.query(
|
||||
`SELECT id, schedule_group_id, title, short_description, start_datetime, end_datetime, created_at, modified_at, created_by, modified_by
|
||||
FROM i_schedule_entries
|
||||
WHERE schedule_group_id = ?
|
||||
ORDER BY start_datetime ASC, id ASC`,
|
||||
[scheduleGroupId]
|
||||
);
|
||||
|
||||
return rows;
|
||||
}
|
||||
|
||||
function buildScheduleGroupPayload(req, existingScheduleGroup) {
|
||||
const fallback = existingScheduleGroup || {};
|
||||
const name = String(req.body.name || fallback.name || '').trim();
|
||||
const shortDescription = String(req.body.short_description || req.body.shortDescription || fallback.short_description || '').trim();
|
||||
|
||||
if (!name) {
|
||||
const error = new Error('Schedule group name is required.');
|
||||
error.statusCode = 400;
|
||||
throw error;
|
||||
}
|
||||
|
||||
return {
|
||||
name: name,
|
||||
shortDescription: shortDescription
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
normalizeDisplayMode,
|
||||
fetchSchedulesData,
|
||||
fetchScheduleGroupsPage,
|
||||
fetchScheduleGroupById,
|
||||
fetchScheduleEntriesByGroupId,
|
||||
buildScheduleGroupPayload
|
||||
};
|
||||
Reference in New Issue
Block a user