WikiEducationFoundation/WikiEduDashboard

View on GitHub
app/assets/javascripts/utils/statistic_update_info_utils.js

Summary

Maintainability
A
0 mins
Test Coverage
C
76%
import { addSeconds, formatDistanceToNow, isAfter } from 'date-fns';
import { toDate } from './date_utils';

const firstUpdateTime = (first_update) => {
  const latency = Math.round(first_update.queue_latency);
  const enqueuedAt = toDate(first_update.enqueued_at);
  return addSeconds(enqueuedAt, latency);
};

const lastSuccessfulUpdateMoment = (update_logs) => {
  const updateTimesLogs = Object.values(update_logs).filter(log => log.end_time !== undefined);
  if (updateTimesLogs.length === 0) return null;
  const lastSuccessfulUpdateTime = updateTimesLogs[updateTimesLogs.length - 1].end_time;
  return new Date(lastSuccessfulUpdateTime);
};

const isNextUpdateAfterUpdatesEnd = (nextUpdateExpectedTime, updatesEndMoment) => {
  return isAfter(nextUpdateExpectedTime, new Date()) && isAfter(updatesEndMoment, new Date());
};

const getLastUpdateMessage = (course) => {
  let lastUpdateMessage = '';
  let nextUpdateMessage = '';
  let isNextUpdateAfter = false;
  const lastUpdateMoment = lastSuccessfulUpdateMoment(course.flags.update_logs);
  const updatesEndMoment = toDate(course.update_until);
  if (lastUpdateMoment) {
    const averageDelay = course.updates.average_delay ?? 0;
    lastUpdateMessage = `${I18n.t('metrics.last_update')}: ${formatDistanceToNow(lastUpdateMoment, { addSuffix: true })}.`;
    const nextUpdateExpectedTime = addSeconds(lastUpdateMoment, averageDelay);
    isNextUpdateAfter = isNextUpdateAfterUpdatesEnd(nextUpdateExpectedTime, updatesEndMoment);
    nextUpdateMessage = `${I18n.t('metrics.next_update')}: ${formatDistanceToNow(nextUpdateExpectedTime, { addSuffix: true })}.`;
  }
  return [lastUpdateMessage, nextUpdateMessage, isNextUpdateAfter];
};

const nextUpdateExpected = (course) => {
  if (!course.flags.update_logs) {
   return formatDistanceToNow(firstUpdateTime(course.flags.first_update), { addSuffix: true });
  }
  if (lastSuccessfulUpdateMoment(course.flags.update_logs) === null) {
    return 'unknown';
  }
  const lastUpdateMoment = lastSuccessfulUpdateMoment(course.flags.update_logs);
  const averageDelay = course.updates.average_delay || 0;
  const nextUpdateTime = addSeconds(lastUpdateMoment, averageDelay);
  return formatDistanceToNow(nextUpdateTime, { addSuffix: true });
};


const getUpdateMessage = (course) => {
  if (!course.flags.update_logs) {
    return getFirstUpdateMessage(course);
  }
  const successfulUpdate = lastSuccessfulUpdateMoment(course.flags.update_logs);
  if (course.flags.update_logs && successfulUpdate !== null) {
    const ans = getLastUpdateMessage(course);
    return ans;
  }
  return [`${I18n.t('metrics.no_update')}`, '', ''];
};

const getFirstUpdateMessage = (course) => {
  let lastUpdateMessage = '';
  let nextUpdateMessage = '';
  let isNextUpdateAfter = false;
  const updatesEndMoment = toDate(course.update_until);
  if (course.flags.first_update) {
    const nextUpdateExpectedTime = firstUpdateTime(course.flags.first_update);
    isNextUpdateAfter = isNextUpdateAfterUpdatesEnd(nextUpdateExpectedTime, updatesEndMoment);
    nextUpdateMessage = `${I18n.t('metrics.first_update')}: ${formatDistanceToNow(nextUpdateExpectedTime, { addSuffix: true })}.`;
    lastUpdateMessage = `${I18n.t('metrics.enqueued_update')}`;
  } else {
    lastUpdateMessage = `${I18n.t('metrics.no_update')}`;
  }
  return [lastUpdateMessage, nextUpdateMessage, isNextUpdateAfter];
};

const getLastUpdateSummary = (course) => {
  if (course.updates.last_update === null || lastSuccessfulUpdateMoment(course.flags.update_logs) === null) {
    return I18n.t('metrics.no_update');
  }
  const errorCount = course.updates.last_update.error_count;
  if (errorCount === 0) {
    return `${I18n.t('metrics.last_update_success')}`;
  } else if (errorCount > 0) {
    return `${I18n.t('metrics.error_count_message', { error_count: errorCount })}`;
  } else if (course.updates.last_update.orphan_lock_failure) {
    return `${I18n.t('metrics.last_update_failed')}`;
  }
};

const getTotaUpdatesMessage = (course) => {
  if (!course.flags.update_logs) {
    return `${I18n.t('metrics.total_updates')}: 0.`;
  }
  const updateNumbers = Object.keys(course.flags.update_logs);
  return `${I18n.t('metrics.total_updates')}: ${updateNumbers[updateNumbers.length - 1]}.`;
};

const getUpdateLogs = (course) => {
  if (course.flags.update_logs) {
    return Object.values(course.flags.update_logs);
  }
  return [];
};
export { getUpdateMessage, getLastUpdateMessage, getFirstUpdateMessage, firstUpdateTime, lastSuccessfulUpdateMoment, nextUpdateExpected, getLastUpdateSummary, getTotaUpdatesMessage, getUpdateLogs };