Commit aa227c5c by Torkel Ödegaard

Fix: reverted back to `import * as module` instead of using namespaces (#23069)

* Removed namespace declaration to prevent issues with external plugins.

* fixed imports and tests.

(cherry picked from commit f75387bd)
parent ba26ac34
import sinon, { SinonFakeTimers } from 'sinon'; import sinon, { SinonFakeTimers } from 'sinon';
import each from 'lodash/each'; import each from 'lodash/each';
import { dateMath } from './datemath'; import * as dateMath from './datemath';
import { dateTime, DurationUnit, DateTime } from './moment_wrapper'; import { dateTime, DurationUnit, DateTime } from './moment_wrapper';
describe('DateMath', () => { describe('DateMath', () => {
......
...@@ -5,9 +5,7 @@ import { TimeZone } from '../types/index'; ...@@ -5,9 +5,7 @@ import { TimeZone } from '../types/index';
const units: DurationUnit[] = ['y', 'M', 'w', 'd', 'h', 'm', 's']; const units: DurationUnit[] = ['y', 'M', 'w', 'd', 'h', 'm', 's'];
// eslint-disable-next-line @typescript-eslint/no-namespace export function isMathString(text: string | DateTime | Date): boolean {
export namespace dateMath {
export function isMathString(text: string | DateTime | Date): boolean {
if (!text) { if (!text) {
return false; return false;
} }
...@@ -17,16 +15,20 @@ export namespace dateMath { ...@@ -17,16 +15,20 @@ export namespace dateMath {
} else { } else {
return false; return false;
} }
} }
/** /**
* Parses different types input to a moment instance. There is a specific formatting language that can be used * Parses different types input to a moment instance. There is a specific formatting language that can be used
* if text arg is string. See unit tests for examples. * if text arg is string. See unit tests for examples.
* @param text * @param text
* @param roundUp See parseDateMath function. * @param roundUp See parseDateMath function.
* @param timezone Only string 'utc' is acceptable here, for anything else, local timezone is used. * @param timezone Only string 'utc' is acceptable here, for anything else, local timezone is used.
*/ */
export function parse(text: string | DateTime | Date, roundUp?: boolean, timezone?: TimeZone): DateTime | undefined { export function parse(
text?: string | DateTime | Date | null,
roundUp?: boolean,
timezone?: TimeZone
): DateTime | undefined {
if (!text) { if (!text) {
return undefined; return undefined;
} }
...@@ -68,14 +70,14 @@ export namespace dateMath { ...@@ -68,14 +70,14 @@ export namespace dateMath {
return parseDateMath(mathString, time, roundUp); return parseDateMath(mathString, time, roundUp);
} }
} }
/** /**
* Checks if text is a valid date which in this context means that it is either a Moment instance or it can be parsed * Checks if text is a valid date which in this context means that it is either a Moment instance or it can be parsed
* by parse function. See parse function to see what is considered acceptable. * by parse function. See parse function to see what is considered acceptable.
* @param text * @param text
*/ */
export function isValid(text: string | DateTime): boolean { export function isValid(text: string | DateTime): boolean {
const date = parse(text); const date = parse(text);
if (!date) { if (!date) {
return false; return false;
...@@ -86,16 +88,16 @@ export namespace dateMath { ...@@ -86,16 +88,16 @@ export namespace dateMath {
} }
return false; return false;
} }
/** /**
* Parses math part of the time string and shifts supplied time according to that math. See unit tests for examples. * Parses math part of the time string and shifts supplied time according to that math. See unit tests for examples.
* @param mathString * @param mathString
* @param time * @param time
* @param roundUp If true it will round the time to endOf time unit, otherwise to startOf time unit. * @param roundUp If true it will round the time to endOf time unit, otherwise to startOf time unit.
*/ */
// TODO: Had to revert Andrejs `time: moment.Moment` to `time: any` // TODO: Had to revert Andrejs `time: moment.Moment` to `time: any`
export function parseDateMath(mathString: string, time: any, roundUp?: boolean): DateTime | undefined { export function parseDateMath(mathString: string, time: any, roundUp?: boolean): DateTime | undefined {
const strippedMathString = mathString.replace(/\s/g, ''); const strippedMathString = mathString.replace(/\s/g, '');
const dateTime = time; const dateTime = time;
let i = 0; let i = 0;
...@@ -157,5 +159,4 @@ export namespace dateMath { ...@@ -157,5 +159,4 @@ export namespace dateMath {
} }
} }
return dateTime; return dateTime;
}
} }
// Names are too general to export globally // Names are too general to export globally
export { dateMath } from './datemath'; import * as dateMath from './datemath';
export { rangeUtil } from './rangeutil'; import * as rangeUtil from './rangeutil';
export * from './moment_wrapper'; export * from './moment_wrapper';
export * from './timezones'; export * from './timezones';
export * from './formats'; export * from './formats';
export { dateMath, rangeUtil };
...@@ -3,12 +3,10 @@ import groupBy from 'lodash/groupBy'; ...@@ -3,12 +3,10 @@ import groupBy from 'lodash/groupBy';
import { RawTimeRange } from '../types/time'; import { RawTimeRange } from '../types/time';
import { dateMath } from './datemath'; import * as dateMath from './datemath';
import { isDateTime, DateTime } from './moment_wrapper'; import { isDateTime, DateTime } from './moment_wrapper';
// eslint-disable-next-line @typescript-eslint/no-namespace const spans: { [key: string]: { display: string; section?: number } } = {
export namespace rangeUtil {
const spans: { [key: string]: { display: string; section?: number } } = {
s: { display: 'second' }, s: { display: 'second' },
m: { display: 'minute' }, m: { display: 'minute' },
h: { display: 'hour' }, h: { display: 'hour' },
...@@ -16,9 +14,9 @@ export namespace rangeUtil { ...@@ -16,9 +14,9 @@ export namespace rangeUtil {
w: { display: 'week' }, w: { display: 'week' },
M: { display: 'month' }, M: { display: 'month' },
y: { display: 'year' }, y: { display: 'year' },
}; };
const rangeOptions = [ const rangeOptions = [
{ from: 'now/d', to: 'now/d', display: 'Today', section: 2 }, { from: 'now/d', to: 'now/d', display: 'Today', section: 2 },
{ from: 'now/d', to: 'now', display: 'Today so far', section: 2 }, { from: 'now/d', to: 'now', display: 'Today so far', section: 2 },
{ from: 'now/w', to: 'now/w', display: 'This week', section: 2 }, { from: 'now/w', to: 'now/w', display: 'This week', section: 2 },
...@@ -61,16 +59,16 @@ export namespace rangeUtil { ...@@ -61,16 +59,16 @@ export namespace rangeUtil {
{ from: 'now-1y', to: 'now', display: 'Last 1 year', section: 0 }, { from: 'now-1y', to: 'now', display: 'Last 1 year', section: 0 },
{ from: 'now-2y', to: 'now', display: 'Last 2 years', section: 0 }, { from: 'now-2y', to: 'now', display: 'Last 2 years', section: 0 },
{ from: 'now-5y', to: 'now', display: 'Last 5 years', section: 0 }, { from: 'now-5y', to: 'now', display: 'Last 5 years', section: 0 },
]; ];
const absoluteFormat = 'YYYY-MM-DD HH:mm:ss'; const absoluteFormat = 'YYYY-MM-DD HH:mm:ss';
const rangeIndex: any = {}; const rangeIndex: any = {};
each(rangeOptions, (frame: any) => { each(rangeOptions, (frame: any) => {
rangeIndex[frame.from + ' to ' + frame.to] = frame; rangeIndex[frame.from + ' to ' + frame.to] = frame;
}); });
export function getRelativeTimesList(timepickerSettings: any, currentDisplay: any) { export function getRelativeTimesList(timepickerSettings: any, currentDisplay: any) {
const groups = groupBy(rangeOptions, (option: any) => { const groups = groupBy(rangeOptions, (option: any) => {
option.active = option.display === currentDisplay; option.active = option.display === currentDisplay;
return option.section; return option.section;
...@@ -84,19 +82,19 @@ export namespace rangeUtil { ...@@ -84,19 +82,19 @@ export namespace rangeUtil {
// }); // });
return groups; return groups;
} }
function formatDate(date: DateTime) { function formatDate(date: DateTime) {
return date.format(absoluteFormat); return date.format(absoluteFormat);
} }
// handles expressions like // handles expressions like
// 5m // 5m
// 5m to now/d // 5m to now/d
// now/d to now // now/d to now
// now/d // now/d
// if no to <expr> then to now is assumed // if no to <expr> then to now is assumed
export function describeTextRange(expr: any) { export function describeTextRange(expr: any) {
const isLast = expr.indexOf('+') !== 0; const isLast = expr.indexOf('+') !== 0;
if (expr.indexOf('now') === -1) { if (expr.indexOf('now') === -1) {
expr = (isLast ? 'now-' : 'now') + expr; expr = (isLast ? 'now-' : 'now') + expr;
...@@ -132,9 +130,9 @@ export namespace rangeUtil { ...@@ -132,9 +130,9 @@ export namespace rangeUtil {
} }
return opt; return opt;
} }
/** /**
* Use this function to get a properly formatted string representation of a {@link @grafana/data:RawTimeRange | range}. * Use this function to get a properly formatted string representation of a {@link @grafana/data:RawTimeRange | range}.
* *
* @example * @example
...@@ -146,7 +144,7 @@ export namespace rangeUtil { ...@@ -146,7 +144,7 @@ export namespace rangeUtil {
* @param range - a time range (usually specified by the TimePicker) * @param range - a time range (usually specified by the TimePicker)
* @alpha * @alpha
*/ */
export function describeTimeRange(range: RawTimeRange): string { export function describeTimeRange(range: RawTimeRange): string {
const option = rangeIndex[range.from.toString() + ' to ' + range.to.toString()]; const option = rangeIndex[range.from.toString() + ' to ' + range.to.toString()];
if (option) { if (option) {
return option.display; return option.display;
...@@ -172,14 +170,13 @@ export namespace rangeUtil { ...@@ -172,14 +170,13 @@ export namespace rangeUtil {
} }
return range.from.toString() + ' to ' + range.to.toString(); return range.from.toString() + ' to ' + range.to.toString();
} }
export const isValidTimeSpan = (value: string) => { export const isValidTimeSpan = (value: string) => {
if (value.indexOf('$') === 0 || value.indexOf('+$') === 0) { if (value.indexOf('$') === 0 || value.indexOf('+$') === 0) {
return true; return true;
} }
const info = describeTextRange(value); const info = describeTextRange(value);
return info.invalid !== true; return info.invalid !== true;
}; };
}
...@@ -5,11 +5,8 @@ export interface AppEvent<T> { ...@@ -5,11 +5,8 @@ export interface AppEvent<T> {
payload?: T; payload?: T;
} }
// eslint-disable-next-line @typescript-eslint/no-namespace export type AlertPayload = [string, string?];
export namespace AppEvents {
export type AlertPayload = [string, string?];
export const alertSuccess = eventFactory<AlertPayload>('alert-success'); export const alertSuccess = eventFactory<AlertPayload>('alert-success');
export const alertWarning = eventFactory<AlertPayload>('alert-warning'); export const alertWarning = eventFactory<AlertPayload>('alert-warning');
export const alertError = eventFactory<AlertPayload>('alert-error'); export const alertError = eventFactory<AlertPayload>('alert-error');
}
...@@ -24,5 +24,9 @@ export * from './theme'; ...@@ -24,5 +24,9 @@ export * from './theme';
export * from './orgs'; export * from './orgs';
export * from './flot'; export * from './flot';
export { AppEvent, AppEvents } from './appEvents'; import * as AppEvents from './appEvents';
export { PanelEvents } from './panelEvents'; import { AppEvent } from './appEvents';
export { AppEvent, AppEvents };
import * as PanelEvents from './panelEvents';
export { PanelEvents };
...@@ -2,28 +2,25 @@ import { eventFactory } from './utils'; ...@@ -2,28 +2,25 @@ import { eventFactory } from './utils';
import { DataQueryError, DataQueryResponseData } from './datasource'; import { DataQueryError, DataQueryResponseData } from './datasource';
import { AngularPanelMenuItem } from './panel'; import { AngularPanelMenuItem } from './panel';
// eslint-disable-next-line @typescript-eslint/no-namespace /** Payloads */
export namespace PanelEvents { export interface PanelChangeViewPayload {
/** Payloads */
export interface PanelChangeViewPayload {
fullscreen?: boolean; fullscreen?: boolean;
edit?: boolean; edit?: boolean;
panelId?: number; panelId?: number;
toggle?: boolean; toggle?: boolean;
}
/** Events */
export const refresh = eventFactory('refresh');
export const componentDidMount = eventFactory('component-did-mount');
export const dataError = eventFactory<DataQueryError>('data-error');
export const dataReceived = eventFactory<DataQueryResponseData[]>('data-received');
export const dataSnapshotLoad = eventFactory<DataQueryResponseData[]>('data-snapshot-load');
export const editModeInitialized = eventFactory('init-edit-mode');
export const initPanelActions = eventFactory<AngularPanelMenuItem[]>('init-panel-actions');
export const panelChangeView = eventFactory<PanelChangeViewPayload>('panel-change-view');
export const panelInitialized = eventFactory('panel-initialized');
export const panelSizeChanged = eventFactory('panel-size-changed');
export const panelTeardown = eventFactory('panel-teardown');
export const render = eventFactory<any>('render');
export const viewModeChanged = eventFactory('view-mode-changed');
} }
/** Events */
export const refresh = eventFactory('refresh');
export const componentDidMount = eventFactory('component-did-mount');
export const dataError = eventFactory<DataQueryError>('data-error');
export const dataReceived = eventFactory<DataQueryResponseData[]>('data-received');
export const dataSnapshotLoad = eventFactory<DataQueryResponseData[]>('data-snapshot-load');
export const editModeInitialized = eventFactory('init-edit-mode');
export const initPanelActions = eventFactory<AngularPanelMenuItem[]>('init-panel-actions');
export const panelChangeView = eventFactory<PanelChangeViewPayload>('panel-change-view');
export const panelInitialized = eventFactory('panel-initialized');
export const panelSizeChanged = eventFactory('panel-size-changed');
export const panelTeardown = eventFactory('panel-teardown');
export const render = eventFactory<any>('render');
export const viewModeChanged = eventFactory('view-mode-changed');
...@@ -3,4 +3,6 @@ import { getTheme, mockTheme } from './getTheme'; ...@@ -3,4 +3,6 @@ import { getTheme, mockTheme } from './getTheme';
import { selectThemeVariant } from './selectThemeVariant'; import { selectThemeVariant } from './selectThemeVariant';
export { stylesFactory } from './stylesFactory'; export { stylesFactory } from './stylesFactory';
export { ThemeContext, withTheme, mockTheme, getTheme, selectThemeVariant, useTheme, mockThemeContext }; export { ThemeContext, withTheme, mockTheme, getTheme, selectThemeVariant, useTheme, mockThemeContext };
export { styleMixins } from './mixins';
import * as styleMixins from './mixins';
export { styleMixins };
import { GrafanaTheme } from '@grafana/data'; import { GrafanaTheme } from '@grafana/data';
// eslint-disable-next-line @typescript-eslint/no-namespace export function cardChrome(theme: GrafanaTheme): string {
export namespace styleMixins {
export function cardChrome(theme: GrafanaTheme): string {
if (theme.isDark) { if (theme.isDark) {
return ` return `
background: linear-gradient(135deg, ${theme.colors.dark8}, ${theme.colors.dark6}); background: linear-gradient(135deg, ${theme.colors.dark8}, ${theme.colors.dark6});
...@@ -22,9 +20,9 @@ export namespace styleMixins { ...@@ -22,9 +20,9 @@ export namespace styleMixins {
box-shadow: -1px -1px 0 0 hsla(0, 0%, 100%, 0.1), 1px 1px 0 0 rgba(0, 0, 0, 0.1); box-shadow: -1px -1px 0 0 hsla(0, 0%, 100%, 0.1), 1px 1px 0 0 rgba(0, 0, 0, 0.1);
border-radius: ${theme.border.radius.md}; border-radius: ${theme.border.radius.md};
`; `;
} }
export function listItem(theme: GrafanaTheme): string { export function listItem(theme: GrafanaTheme): string {
if (theme.isDark) { if (theme.isDark) {
return ` return `
background: ${theme.colors.dark7}; background: ${theme.colors.dark7};
...@@ -44,5 +42,4 @@ export namespace styleMixins { ...@@ -44,5 +42,4 @@ export namespace styleMixins {
box-shadow: -1px -1px 0 0 hsla(0, 0%, 100%, 0.1), 1px 1px 0 0 rgba(0, 0, 0, 0.1); box-shadow: -1px -1px 0 0 hsla(0, 0%, 100%, 0.1), 1px 1px 0 0 rgba(0, 0, 0, 0.1);
border-radius: ${theme.border.radius.md}; border-radius: ${theme.border.radius.md};
`; `;
}
} }
// eslint-disable-next-line @typescript-eslint/no-namespace // Node.closest() polyfill
export namespace DOMUtil { if ('Element' in window && !Element.prototype.closest) {
// Node.closest() polyfill
if ('Element' in window && !Element.prototype.closest) {
Element.prototype.closest = function(this: any, s: string) { Element.prototype.closest = function(this: any, s: string) {
const matches = (this.document || this.ownerDocument).querySelectorAll(s); const matches = (this.document || this.ownerDocument).querySelectorAll(s);
let el = this; let el = this;
...@@ -15,9 +13,9 @@ export namespace DOMUtil { ...@@ -15,9 +13,9 @@ export namespace DOMUtil {
} while (i < 0 && el); } while (i < 0 && el);
return el; return el;
}; };
} }
export function getPreviousCousin(node: any, selector: string) { export function getPreviousCousin(node: any, selector: string) {
let sibling = node.parentElement.previousSibling; let sibling = node.parentElement.previousSibling;
let el; let el;
while (sibling) { while (sibling) {
...@@ -28,9 +26,9 @@ export namespace DOMUtil { ...@@ -28,9 +26,9 @@ export namespace DOMUtil {
sibling = sibling.previousSibling; sibling = sibling.previousSibling;
} }
return undefined; return undefined;
} }
export function getNextCharacter(global?: any) { export function getNextCharacter(global?: any) {
const selection = (global || window).getSelection(); const selection = (global || window).getSelection();
if (!selection || !selection.anchorNode) { if (!selection || !selection.anchorNode) {
return null; return null;
...@@ -40,5 +38,4 @@ export namespace DOMUtil { ...@@ -40,5 +38,4 @@ export namespace DOMUtil {
const text = selection.anchorNode.textContent; const text = selection.anchorNode.textContent;
const offset = range.startOffset; const offset = range.startOffset;
return text!.substr(offset, 1); return text!.substr(offset, 1);
}
} }
...@@ -6,5 +6,5 @@ export * from './tags'; ...@@ -6,5 +6,5 @@ export * from './tags';
export * from './measureText'; export * from './measureText';
export { default as ansicolor } from './ansicolor'; export { default as ansicolor } from './ansicolor';
// Export with a namespace import * as DOMUtil from './dom'; // includes Element.closest polyfil
export { DOMUtil } from './dom'; // includes Element.closest polyfil export { DOMUtil };
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment