rails_error_dashboard 0.11.3 → 0.11.4

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ca64d9f0169fc1dd0b900fbd5460377d5b086d45849e61ca1945045db6c10e4e
4
- data.tar.gz: e9c09c9c4d5c9b716bf4da5aec37d28780aa2bcbd8d2d80cdacbdd9fb171a0b4
3
+ metadata.gz: 1641d82898e05eb9bd08a04a01516952e0c8c08cec1f20ad7385894c2abcc0b8
4
+ data.tar.gz: 3612aecf1b1ea06f75258ea9adbdbef68a5079d338061e3ad08ddb8fa571d37a
5
5
  SHA512:
6
- metadata.gz: 51d6dc61b08748427205b7d3a838ec14e968f01898b395fa9f678c7aca3dd4647b32bc37f0e91fa1d99782b89242707d20604441a81ce7c7ca8bc2cbaa47d1e4
7
- data.tar.gz: da69121a17eff452ea3b0d31c909b765da9e607cb1a80c5ae304a6fbb4c45473a88d3c6d7c927762d64ed1dd76630ca2dc4b9b37813cdd5213fbec9b7063fe29
6
+ metadata.gz: ad234969bb94a719add01ad7453bd265209c07aa1b7502b74b6cbddf6180fea772017fc67991b6e9bfd7b08d6b9ff24d8ca1cea3502a5e25723022f742511a80
7
+ data.tar.gz: d687753f2eaea1bb9b9fe2eefa7c5f1f4810770a4ca1b93779e9b7e1203ffbeecc66cf488c7b1c4e649044ba84171be4f07eafd30193e4169711a7665aa3cf16
@@ -164,17 +164,30 @@ module RailsErrorDashboard
164
164
  # Same formatter the mailers and the Slack/Discord payloads use, so a chart
165
165
  # axis and an email agree about what a date looks like.
166
166
  #
167
+ # The pattern defaults to the locale's own axis_day rather than being passed
168
+ # in. Every caller used to hardcode "%b %d", which is US ordering: the
169
+ # formatter translates the WORDS but never reorders, so French read
170
+ # "août 06" where it should read "6 août", and ja/zh-CN read "8月 06"
171
+ # instead of "8月6日". Ten of eleven locales were wrong, and the ordering
172
+ # each one needs already lives in red.time.formats.
173
+ #
167
174
  # @param time [Time, Date, nil]
168
- # @param pattern [String] a strftime pattern
175
+ # @param pattern [String, Symbol] a strftime pattern, or one of
176
+ # red.time.formats' presets — defaults to :axis_day
169
177
  # @return [String] "" for nil — an axis label must never read "undefined"
170
- def red_chart_date(time, pattern)
178
+ def red_chart_date(time, pattern = :axis_day)
171
179
  return "" if time.nil?
172
180
 
181
+ pattern = red_time_format(pattern) if pattern.is_a?(Symbol)
173
182
  time = time.to_time if time.respond_to?(:to_time) && !time.is_a?(Time)
174
183
  Services::LocalizedTimeFormatter.call(time, pattern: pattern, locale: red_locale)
175
184
  rescue StandardError
176
- # A chart with an English axis beats a chart that fails to render.
177
- time.respond_to?(:strftime) ? time.strftime(pattern) : time.to_s
185
+ # A chart with an English axis beats a chart that fails to render. If the
186
+ # failure was red_time_format itself, `pattern` is still the Symbol, and
187
+ # strftime(":axis_day") would print that verbatim on the axis — so fall
188
+ # back to a real pattern rather than to the preset's name.
189
+ fallback = pattern.is_a?(Symbol) ? "%b %-d" : pattern.to_s
190
+ time.respond_to?(:strftime) ? time.strftime(fallback) : time.to_s
178
191
  end
179
192
  end
180
193
  end
@@ -1590,7 +1590,10 @@ document.addEventListener('DOMContentLoaded', function() {
1590
1590
  });
1591
1591
  observer.observe(document.body, { childList: true, subtree: true });
1592
1592
 
1593
- document.addEventListener('chartkick:load', function() { applyChartTheme(); });
1593
+ // On window, not document: Chartkick dispatches `new Event("chartkick:load")`
1594
+ // on window, and a bare Event does not bubble — so a document listener here
1595
+ // never ran, and the theme was never re-applied when charts finished loading.
1596
+ window.addEventListener('chartkick:load', function() { applyChartTheme(); });
1594
1597
 
1595
1598
  // Force-apply a few times on page load for lazy-loaded charts
1596
1599
  var attempts = 0;
@@ -1776,9 +1779,82 @@ document.addEventListener('DOMContentLoaded', function() {
1776
1779
  var am = typeof meridian.am === 'string' ? meridian.am : RED_DATE_EN.meridian.am;
1777
1780
  var h12 = h % 12 || 12, ampm = h >= 12 ? pm : am;
1778
1781
  var pad = function(n) { return n.toString().padStart(2, '0'); };
1779
- return fmt.replace('%Y',y).replace('%y',y.toString().substr(2)).replace('%B',months[mo]).replace('%b',monthsShort[mo])
1780
- .replace('%m',pad(mo+1)).replace('%d',pad(d)).replace('%e',d).replace('%A',days[dow]).replace('%a',daysShort[dow])
1781
- .replace('%H',pad(h)).replace('%I',pad(h12)).replace('%M',pad(mi)).replace('%S',pad(s)).replace('%p',ampm).replace('%P',ampm.toLowerCase());
1782
+
1783
+ // One regex pass, not a chain of .replace('%d',). Two reasons:
1784
+ //
1785
+ // * String-argument replace() substitutes only the FIRST match, so a
1786
+ // pattern that repeats a directive — "%d/%m/%d" — left the second one
1787
+ // as literal text.
1788
+ // * The chain is order-sensitive in a way that breaks %-d: '%d' matches
1789
+ // inside '%-d', so "%-d %b" became "%-<day> %b".
1790
+ //
1791
+ // %-d and %-m (unpadded day and month) are needed because a chart axis
1792
+ // reads "6 août", not "06 août". Ruby's strftime already supports them, so
1793
+ // this also closes a gap between the two formatters — a locale's pattern
1794
+ // must mean the same thing server-side and in the browser.
1795
+ var TABLE = {
1796
+ '%Y': y,
1797
+ '%y': y.toString().substr(2),
1798
+ '%B': months[mo],
1799
+ '%b': monthsShort[mo],
1800
+ '%m': pad(mo + 1),
1801
+ '%-m': mo + 1,
1802
+ '%d': pad(d),
1803
+ '%-d': d,
1804
+ '%e': d,
1805
+ '%A': days[dow],
1806
+ '%a': daysShort[dow],
1807
+ '%H': pad(h),
1808
+ '%-H': h,
1809
+ '%I': pad(h12),
1810
+ '%-I': h12,
1811
+ '%M': pad(mi),
1812
+ '%S': pad(s),
1813
+ '%p': ampm,
1814
+ '%P': ampm.toLowerCase()
1815
+ };
1816
+
1817
+ // %-? before the letter so '%-d' wins over '%d'. An unknown directive is
1818
+ // left verbatim rather than becoming "undefined", matching the old chain's
1819
+ // behaviour for anything it did not list.
1820
+ return fmt.replace(/%-?[A-Za-z]/g, function(token) {
1821
+ var value = TABLE[token];
1822
+ return value === undefined ? token : String(value);
1823
+ });
1824
+ }
1825
+
1826
+ // English chart-axis patterns, and the shape every locale must match.
1827
+ // Deliberately not the same strings as red.time.formats' other presets: an
1828
+ // axis needs month+day with no year, and a year cannot simply be stripped
1829
+ // from "%Y年%m月%d日" or "%d de %B de %Y" without leaving a dangling word.
1830
+ var RED_AXIS_EN = {
1831
+ axis_day: '%b %-d',
1832
+ axis_month: '%b %Y',
1833
+ axis_datetime: '%b %-d, %-I:%M %p',
1834
+ axis_full: '%b %-d, %Y',
1835
+ axis_time: '%-I:%M %p',
1836
+ axis_hour: '%-I %p'
1837
+ };
1838
+
1839
+ // The locale's chart-axis patterns, falling back per key. Same total-lookup
1840
+ // discipline as redDate(): a locale missing one key still gets a usable axis
1841
+ // rather than "undefined" drawn across the bottom of the chart.
1842
+ function axisFormats() {
1843
+ var out = {};
1844
+ var source;
1845
+ try {
1846
+ source = (window.RED_I18N && window.RED_I18N.formats) ? window.RED_I18N.formats : null;
1847
+ } catch (e) {
1848
+ source = null;
1849
+ }
1850
+ for (var key in RED_AXIS_EN) {
1851
+ if (!Object.prototype.hasOwnProperty.call(RED_AXIS_EN, key)) continue;
1852
+ var value = source ? source[key] : undefined;
1853
+ // A pattern with no % directive is not a pattern — most likely i18n
1854
+ // returned humanized key text for a miss.
1855
+ out[key] = (typeof value === 'string' && value.indexOf('%') !== -1) ? value : RED_AXIS_EN[key];
1856
+ }
1857
+ return out;
1782
1858
  }
1783
1859
 
1784
1860
  // Chart.js renders date axes through chartjs-adapter-date-fns, whose bundle
@@ -1794,26 +1870,71 @@ document.addEventListener('DOMContentLoaded', function() {
1794
1870
  // week "PP" month "MMM yyyy" quarter "qqq - yyyy" year "yyyy"
1795
1871
  // Anything else — a caller-supplied pattern, a future adapter version — is
1796
1872
  // handed back to the original implementation rather than half-translated.
1873
+ //
1874
+ // redChartDateWrapper holds the function installed below, so a re-assert can
1875
+ // tell "already ours" from "ours was overwritten". A boolean flag cannot:
1876
+ // chartjs-adapter-date-fns installs itself with
1877
+ //
1878
+ // Chart._adapters._date.override(t) { Object.assign(En.prototype, t) }
1879
+ //
1880
+ // which REPLACES format() while leaving any separate flag property standing.
1881
+ // So whenever this ran before the adapter script — three CDN scripts, three
1882
+ // chances to lose that race — the patch was silently wiped and the flag then
1883
+ // reported "already patched" forever, which is why #178 came back reading
1884
+ // "Aug 21" on some loads and "août 21" on others.
1885
+ var redChartDateWrapper = null;
1886
+
1797
1887
  function installRedChartDateAdapter() {
1798
1888
  if (typeof Chart === 'undefined' || !Chart._adapters || !Chart._adapters._date) return;
1799
1889
  var proto = Chart._adapters._date.prototype;
1800
- if (!proto || typeof proto.format !== 'function' || proto._redPatched) return;
1890
+ if (!proto || typeof proto.format !== 'function') return;
1891
+ // Identity, not a flag: this is a no-op when the live format() is still the
1892
+ // wrapper, and reinstalls when something has replaced it.
1893
+ if (proto.format === redChartDateWrapper) return;
1801
1894
 
1802
1895
  // date-fns token -> strftime, for the patterns the adapter actually uses.
1896
+ //
1897
+ // Read from the locale rather than hardcoded, because these patterns carry
1898
+ // ORDER as well as vocabulary. The literals here used to be US English —
1899
+ // 'MMM d' -> '%b %d' — and formatDateTime only swaps words, so French
1900
+ // rendered "août 06" instead of "6 août" and ja/zh-CN "8月 06" instead of
1901
+ // "8月6日". Ten of eleven locales were wrong on every chart, deterministically,
1902
+ // and the correct ordering already existed in red.time.formats.
1903
+ // The time-of-day patterns are the locale's too. They used to be hardcoded
1904
+ // %I:%M %p, which put "03 PM" on a French hour axis — a 12-hour clock with
1905
+ // an English meridian, contradicting that same locale's own time_only
1906
+ // ("%H:%M:%S") elsewhere on the page. Only en declares a 12-hour clock;
1907
+ // seven of the other ten never translated meridian at all, so AM/PM was
1908
+ // being drawn on charts in languages that do not use it.
1909
+ var AXIS = axisFormats();
1803
1910
  var TOKENS = {
1804
- 'MMM d, yyyy, h:mm:ss aaaa': '%b %d, %Y, %I:%M:%S %p',
1805
- 'h:mm:ss.SSS aaaa': '%I:%M:%S %p',
1806
- 'h:mm:ss aaaa': '%I:%M:%S %p',
1807
- 'h:mm aaaa': '%I:%M %p',
1808
- 'ha': '%I %p',
1809
- 'MMM d': '%b %d',
1810
- 'PP': '%b %d, %Y',
1811
- 'MMM yyyy': '%b %Y',
1812
- 'yyyy': '%Y'
1911
+ // chartjs-adapter-date-fns' own format table.
1912
+ 'MMM d, yyyy, h:mm:ss aaaa': AXIS.axis_datetime,
1913
+ 'h:mm:ss.SSS aaaa': AXIS.axis_time,
1914
+ 'h:mm:ss aaaa': AXIS.axis_time,
1915
+ 'h:mm aaaa': AXIS.axis_time,
1916
+ 'ha': AXIS.axis_hour,
1917
+ 'MMM d': AXIS.axis_day,
1918
+ 'PP': AXIS.axis_full,
1919
+ 'MMM yyyy': AXIS.axis_month,
1920
+ 'qqq - yyyy': AXIS.axis_month,
1921
+ 'yyyy': '%Y',
1922
+
1923
+ // Chartkick overrides displayFormats and tooltipFormat with patterns of
1924
+ // its own, which the adapter's table never mentions. Missing them meant
1925
+ // hour-granularity axes and their tooltips stayed English even in a
1926
+ // locale whose day axis was already translated.
1927
+ 'MMM d, h a': AXIS.axis_datetime,
1928
+ 'h:mm a': AXIS.axis_time
1813
1929
  };
1814
1930
 
1931
+ // Read afresh on every install, never from a previous call: after the
1932
+ // adapter has overwritten format(), the current value IS the adapter's real
1933
+ // implementation. Capturing a stale wrapper here would nest wrappers on
1934
+ // each re-assert and, worse, delegate to a function that no longer exists
1935
+ // on the prototype.
1815
1936
  var original = proto.format;
1816
- proto.format = function(time, fmt) {
1937
+ redChartDateWrapper = function(time, fmt) {
1817
1938
  try {
1818
1939
  var strf = TOKENS[fmt];
1819
1940
  if (strf) return formatDateTime(new Date(time), strf);
@@ -1822,7 +1943,7 @@ document.addEventListener('DOMContentLoaded', function() {
1822
1943
  }
1823
1944
  return original.call(this, time, fmt);
1824
1945
  };
1825
- proto._redPatched = true;
1946
+ proto.format = redChartDateWrapper;
1826
1947
  }
1827
1948
 
1828
1949
 
@@ -1844,10 +1965,76 @@ document.addEventListener('DOMContentLoaded', function() {
1844
1965
  // Plural selection. English needs one/other; other languages need more, and
1845
1966
  // some need only one form. Falling back to 'other' means a locale that ships
1846
1967
  // a partial set still renders rather than showing "undefined".
1968
+ // CLDR plural category for a count, mirroring PrivateBackend::PLURAL_RULES.
1969
+ // Kept as a parallel implementation on purpose: the server picks the form for
1970
+ // strings it renders, and this picks it for strings JS renders, so the two
1971
+ // must agree about what "5 seconds ago" is in Russian.
1972
+ //
1973
+ // The %100 guards are the part that is easy to get wrong: 11 is `many`, not
1974
+ // `one`, and 12-14 are `many`, not `few`, even though 1 and 2-4 are. And
1975
+ // Polish is NOT Russian — pl `one` is exactly 1, so 21 takes `many` where
1976
+ // ru/uk take `one`. Copying one rule to the other language is the specific
1977
+ // mistake the server's table documents.
1978
+ function redPluralCategory(locale, count) {
1979
+ if (typeof count !== 'number' || !isFinite(count) || Math.floor(count) !== count) return 'other';
1980
+ var i = Math.abs(count), mod10 = i % 10, mod100 = i % 100;
1981
+
1982
+ switch (locale) {
1983
+ case 'ja':
1984
+ case 'zh-CN':
1985
+ return 'other';
1986
+ case 'fr':
1987
+ case 'pt-BR':
1988
+ return i < 2 ? 'one' : 'other';
1989
+ case 'es':
1990
+ case 'it':
1991
+ return count === 1 ? 'one' : 'other';
1992
+ case 'ru':
1993
+ case 'uk':
1994
+ if (mod10 === 1 && mod100 !== 11) return 'one';
1995
+ if (mod10 >= 2 && mod10 <= 4 && !(mod100 >= 12 && mod100 <= 14)) return 'few';
1996
+ return 'many';
1997
+ case 'pl':
1998
+ if (i === 1) return 'one';
1999
+ if (mod10 >= 2 && mod10 <= 4 && !(mod100 >= 12 && mod100 <= 14)) return 'few';
2000
+ return 'many';
2001
+ default:
2002
+ // en, de and anything unlisted keep the English one/other split, which
2003
+ // is also upstream i18n's behaviour for a locale it has no rule for.
2004
+ return count === 1 ? 'one' : 'other';
2005
+ }
2006
+ }
2007
+
2008
+ // Plural selection. English needs one/other; ru/uk/pl need four categories
2009
+ // and ship them, but this only ever read `one` and `other` — so Russian
2010
+ // rendered "5 секунды" (few) where it should read "5 секунд" (many), using a
2011
+ // form the locale file had supplied all along.
2012
+ //
2013
+ // Falls back through the categories rather than to `other` alone, because for
2014
+ // ru/uk/pl CLDR assigns `other` to fractional counts only: a locale that
2015
+ // ships one/few/many and no `other` must still render.
1847
2016
  function redPluralize(forms, count) {
1848
2017
  if (!forms || typeof forms !== 'object') return String(count);
1849
- var form = (count === 1 && typeof forms.one === 'string') ? forms.one : forms.other;
1850
- if (typeof form !== 'string') form = forms.one;
2018
+
2019
+ var locale;
2020
+ try {
2021
+ locale = (window.RED_I18N && typeof window.RED_I18N.locale === 'string') ? window.RED_I18N.locale : 'en';
2022
+ } catch (e) {
2023
+ locale = 'en';
2024
+ }
2025
+
2026
+ var category = redPluralCategory(locale, count);
2027
+ var form = forms[category];
2028
+
2029
+ // Ordered fallback: the requested category, then the ones most likely to
2030
+ // carry a usable string, and finally anything the entry does supply.
2031
+ if (typeof form !== 'string') {
2032
+ var order = [ category, 'other', 'many', 'few', 'one' ];
2033
+ for (var i = 0; i < order.length; i++) {
2034
+ if (typeof forms[order[i]] === 'string') { form = forms[order[i]]; break; }
2035
+ }
2036
+ }
2037
+
1851
2038
  if (typeof form !== 'string') return String(count);
1852
2039
  return form.replace(/%\{count\}/g, String(count));
1853
2040
  }
@@ -1882,9 +2069,20 @@ document.addEventListener('DOMContentLoaded', function() {
1882
2069
  // `document` is a stub, so it must contain definitions only — no top-level
1883
2070
  // browser calls. The adapter is patched on the prototype, so charts drawn
1884
2071
  // later pick it up; chartkick:load re-asserts for page scripts whose own
1885
- // DOMContentLoaded handler beat this one, and _redPatched makes that a no-op.
2072
+ // DOMContentLoaded handler beat this one, and the identity check inside
2073
+ // makes that a no-op unless the patch has actually been overwritten.
2074
+ //
2075
+ // That re-assert is what repairs the lost race described above, so it has to
2076
+ // be reachable: Chartkick dispatches `new Event("chartkick:load")` on window,
2077
+ // and a bare Event has bubbles:false, so a document listener never sees it.
2078
+ // Registered on document — as it was — this never ran at all.
2079
+ //
2080
+ // Ordering is on our side. Chartkick dispatches from a setTimeout(…, 0)
2081
+ // scheduled while it parses, which runs after every DOMContentLoaded handler,
2082
+ // and Chart.js draws on a requestAnimationFrame after that. So the re-assert
2083
+ // lands after any possible clobber and before the first paint.
1886
2084
  installRedChartDateAdapter();
1887
- document.addEventListener('chartkick:load', installRedChartDateAdapter);
2085
+ window.addEventListener('chartkick:load', installRedChartDateAdapter);
1888
2086
 
1889
2087
  if (typeof Turbo !== 'undefined') {
1890
2088
  document.addEventListener('turbo:load', convertToLocalTime);
@@ -36,8 +36,8 @@
36
36
  <div class="display-6"><%= @period_comparison[:current_period][:count] %></div>
37
37
  <small class="text-muted">
38
38
  <%= red_t("red.analytics.correlation.trend_analysis.period_range",
39
- start: red_chart_date(@period_comparison[:current_period][:start], "%b %d"),
40
- end: red_chart_date(@period_comparison[:current_period][:end], "%b %d")) %>
39
+ start: red_chart_date(@period_comparison[:current_period][:start]),
40
+ end: red_chart_date(@period_comparison[:current_period][:end])) %>
41
41
  </small>
42
42
  </div>
43
43
  <div class="col-md-4">
@@ -45,8 +45,8 @@
45
45
  <div class="display-6"><%= @period_comparison[:previous_period][:count] %></div>
46
46
  <small class="text-muted">
47
47
  <%= red_t("red.analytics.correlation.trend_analysis.period_range",
48
- start: red_chart_date(@period_comparison[:previous_period][:start], "%b %d"),
49
- end: red_chart_date(@period_comparison[:previous_period][:end], "%b %d")) %>
48
+ start: red_chart_date(@period_comparison[:previous_period][:start]),
49
+ end: red_chart_date(@period_comparison[:previous_period][:end])) %>
50
50
  </small>
51
51
  </div>
52
52
  <div class="col-md-4">
@@ -358,7 +358,7 @@
358
358
  new Chart(dailyTrendCtx, {
359
359
  type: 'line',
360
360
  data: {
361
- labels: <%= raw @daily_trends.values.first&.keys&.map { |d| red_chart_date(d, '%b %d') }&.to_json || [].to_json %>,
361
+ labels: <%= raw @daily_trends.values.first&.keys&.map { |d| red_chart_date(d) }&.to_json || [].to_json %>,
362
362
  datasets: datasets
363
363
  },
364
364
  options: {
@@ -1370,6 +1370,12 @@ de:
1370
1370
  date_only: "%d. %B %Y"
1371
1371
  time_only: "%H:%M:%S"
1372
1372
  datetime: "%d. %b %Y %H:%M"
1373
+ axis_day: "%-d. %b"
1374
+ axis_month: "%b %Y"
1375
+ axis_datetime: "%-d. %b %H:%M"
1376
+ axis_full: "%-d. %b %Y"
1377
+ axis_time: "%H:%M"
1378
+ axis_hour: "%H Uhr"
1373
1379
  health:
1374
1380
  columns:
1375
1381
  error: Fehler
@@ -1897,6 +1897,12 @@ en:
1897
1897
  date_only: "%B %d, %Y"
1898
1898
  time_only: "%I:%M:%S %p"
1899
1899
  datetime: "%b %d, %Y %H:%M"
1900
+ axis_day: "%b %-d"
1901
+ axis_month: "%b %Y"
1902
+ axis_datetime: "%b %-d, %-I:%M %p"
1903
+ axis_full: "%b %-d, %Y"
1904
+ axis_time: "%-I:%M %p"
1905
+ axis_hour: "%-I %p"
1900
1906
 
1901
1907
  health:
1902
1908
  # Table column headers repeated on more than one health page.
@@ -1424,6 +1424,12 @@ es:
1424
1424
  date_only: "%d de %B de %Y"
1425
1425
  time_only: "%H:%M:%S"
1426
1426
  datetime: "%d %b %Y %H:%M"
1427
+ axis_day: "%-d %b"
1428
+ axis_month: "%b %Y"
1429
+ axis_datetime: "%-d %b %H:%M"
1430
+ axis_full: "%-d %b %Y"
1431
+ axis_time: "%H:%M"
1432
+ axis_hour: "%H:00"
1427
1433
  health:
1428
1434
  columns:
1429
1435
  error: Error
@@ -1423,6 +1423,12 @@ fr:
1423
1423
  date_only: "%d %B %Y"
1424
1424
  time_only: "%H:%M:%S"
1425
1425
  datetime: "%d %b %Y %H:%M"
1426
+ axis_day: "%-d %b"
1427
+ axis_month: "%b %Y"
1428
+ axis_datetime: "%-d %b %H:%M"
1429
+ axis_full: "%-d %b %Y"
1430
+ axis_time: "%H:%M"
1431
+ axis_hour: "%Hh"
1426
1432
  health:
1427
1433
  columns:
1428
1434
  error: Erreur
@@ -1412,6 +1412,12 @@ it:
1412
1412
  date_only: "%d %B %Y"
1413
1413
  time_only: "%H:%M:%S"
1414
1414
  datetime: "%d %b %Y %H:%M"
1415
+ axis_day: "%-d %b"
1416
+ axis_month: "%b %Y"
1417
+ axis_datetime: "%-d %b %H:%M"
1418
+ axis_full: "%-d %b %Y"
1419
+ axis_time: "%H:%M"
1420
+ axis_hour: "%H:00"
1415
1421
  health:
1416
1422
  columns:
1417
1423
  error: Errore
@@ -1218,6 +1218,12 @@ ja:
1218
1218
  date_only: "%Y年%m月%d日"
1219
1219
  time_only: "%H:%M:%S"
1220
1220
  datetime: "%Y年%m月%d日 %H:%M"
1221
+ axis_day: "%-m月%-d日"
1222
+ axis_month: "%Y年%-m月"
1223
+ axis_datetime: "%-m月%-d日 %H:%M"
1224
+ axis_full: "%Y年%-m月%-d日"
1225
+ axis_time: "%H:%M"
1226
+ axis_hour: "%-H時"
1221
1227
  health:
1222
1228
  columns:
1223
1229
  error: エラー
@@ -1449,6 +1449,12 @@ pl:
1449
1449
  date_only: "%d %B %Y"
1450
1450
  time_only: "%H:%M:%S"
1451
1451
  datetime: "%d %b %Y %H:%M"
1452
+ axis_day: "%-d %b"
1453
+ axis_month: "%b %Y"
1454
+ axis_datetime: "%-d %b %H:%M"
1455
+ axis_full: "%-d %b %Y"
1456
+ axis_time: "%H:%M"
1457
+ axis_hour: "%H:00"
1452
1458
  health:
1453
1459
  columns:
1454
1460
  error: Błąd
@@ -1413,6 +1413,12 @@ pt-BR:
1413
1413
  date_only: "%d de %B de %Y"
1414
1414
  time_only: "%H:%M:%S"
1415
1415
  datetime: "%d %b %Y %H:%M"
1416
+ axis_day: "%-d %b"
1417
+ axis_month: "%b %Y"
1418
+ axis_datetime: "%-d %b %H:%M"
1419
+ axis_full: "%-d %b %Y"
1420
+ axis_time: "%H:%M"
1421
+ axis_hour: "%H:00"
1416
1422
  health:
1417
1423
  columns:
1418
1424
  error: Erro
@@ -1449,6 +1449,12 @@ ru:
1449
1449
  date_only: "%d %B %Y"
1450
1450
  time_only: "%H:%M:%S"
1451
1451
  datetime: "%d %b %Y, %H:%M"
1452
+ axis_day: "%-d %b"
1453
+ axis_month: "%b %Y"
1454
+ axis_datetime: "%-d %b %H:%M"
1455
+ axis_full: "%-d %b %Y"
1456
+ axis_time: "%H:%M"
1457
+ axis_hour: "%H:00"
1452
1458
  health:
1453
1459
  columns:
1454
1460
  error: Ошибка
@@ -1447,6 +1447,12 @@ uk:
1447
1447
  date_only: "%d %B %Y"
1448
1448
  time_only: "%H:%M:%S"
1449
1449
  datetime: "%d %b %Y %H:%M"
1450
+ axis_day: "%-d %b"
1451
+ axis_month: "%b %Y"
1452
+ axis_datetime: "%-d %b %H:%M"
1453
+ axis_full: "%-d %b %Y"
1454
+ axis_time: "%H:%M"
1455
+ axis_hour: "%H:00"
1450
1456
  health:
1451
1457
  columns:
1452
1458
  error: Помилка
@@ -1210,6 +1210,12 @@ zh-CN:
1210
1210
  date_only: "%Y年%m月%d日"
1211
1211
  time_only: "%H:%M:%S"
1212
1212
  datetime: "%Y年%m月%d日 %H:%M"
1213
+ axis_day: "%-m月%-d日"
1214
+ axis_month: "%Y年%-m月"
1215
+ axis_datetime: "%-m月%-d日 %H:%M"
1216
+ axis_full: "%Y年%-m月%-d日"
1217
+ axis_time: "%H:%M"
1218
+ axis_hour: "%-H时"
1213
1219
  health:
1214
1220
  columns:
1215
1221
  error: 错误
@@ -1,3 +1,3 @@
1
1
  module RailsErrorDashboard
2
- VERSION = "0.11.3"
2
+ VERSION = "0.11.4"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_error_dashboard
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.3
4
+ version: 0.11.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Anjan Jagirdar
@@ -575,7 +575,7 @@ metadata:
575
575
  funding_uri: https://github.com/sponsors/AnjanJ
576
576
  post_install_message: |
577
577
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
578
- RED (Rails Error Dashboard) v0.11.3
578
+ RED (Rails Error Dashboard) v0.11.4
579
579
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
580
580
 
581
581
  First install: