<commit_before>/**
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow
 * @format
 */

import ReactNativeViewAttributes from '../Components/View/ReactNativeViewAttributes';
import UIManager from '../ReactNative/UIManager';
import {type HostComponent} from '../Renderer/shims/ReactNativeTypes';
import createReactNativeComponentClass from '../Renderer/shims/createReactNativeComponentClass';
import {type ProcessedColorValue} from '../StyleSheet/processColor';
import {type TextProps} from './TextProps';
import {type PressEvent} from '../Types/CoreEventTypes';

type NativeTextProps = $ReadOnly<{
  ...TextProps,
  isHighlighted?: ?boolean,
  selectionColor?: ?ProcessedColorValue,
  onClick?: ?(event: PressEvent) => mixed,
  // This is only needed for platforms that optimize text hit testing, e.g.,
  // react-native-windows. It can be used to only hit test virtual text spans
  // that have pressable events attached to them.
  isPressable?: ?boolean,
}>;

export const NativeText: HostComponent<NativeTextProps> =
  (createReactNativeComponentClass('RCTText', () => ({
    validAttributes: {
      ...ReactNativeViewAttributes.UIView,
      isHighlighted: true,
      isPressable: true,
      numberOfLines: true,
      ellipsizeMode: true,
      allowFontScaling: true,
      maxFontSizeMultiplier: true,
      disabled: true,
      selectable: true,
      selectionColor: true,
      adjustsFontSizeToFit: true,
      minimumFontScale: true,
      textBreakStrategy: true,
      onTextLayout: true,
      onInlineViewLayout: true,
      dataDetectorType: true,
      android_hyphenationFrequency: true,
    },
    directEventTypes: {
      topTextLayout: {
        registrationName: 'onTextLayout',
      },
      topInlineViewLayout: {
        registrationName: 'onInlineViewLayout',
      },
    },
    uiViewClassName: 'RCTText',
  })): any);

export const NativeVirtualText: HostComponent<NativeTextProps> =
  !global.RN$Bridgeless && !UIManager.hasViewManagerConfig('RCTVirtualText')
    ? NativeText
    : (createReactNativeComponentClass('RCTVirtualText', () => ({
        validAttributes: {
          ...ReactNativeViewAttributes.UIView,
          isHighlighted: true,
          isPressable: true,
          maxFontSizeMultiplier: true,
        },
        uiViewClassName: 'RCTVirtualText',
      })): any);
<commit_msg>Add pointer events to text view config<commit_after>/**
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow
 * @format
 */

import UIManager from '../ReactNative/UIManager';
import {type HostComponent} from '../Renderer/shims/ReactNativeTypes';
import createReactNativeComponentClass from '../Renderer/shims/createReactNativeComponentClass';
import {type ProcessedColorValue} from '../StyleSheet/processColor';
import {type TextProps} from './TextProps';
import {type PressEvent} from '../Types/CoreEventTypes';
import {createViewConfig} from '../NativeComponent/ViewConfig';

type NativeTextProps = $ReadOnly<{
  ...TextProps,
  isHighlighted?: ?boolean,
  selectionColor?: ?ProcessedColorValue,
  onClick?: ?(event: PressEvent) => mixed,
  // This is only needed for platforms that optimize text hit testing, e.g.,
  // react-native-windows. It can be used to only hit test virtual text spans
  // that have pressable events attached to them.
  isPressable?: ?boolean,
}>;

const textViewConfig = {
  validAttributes: {
    isHighlighted: true,
    isPressable: true,
    numberOfLines: true,
    ellipsizeMode: true,
    allowFontScaling: true,
    maxFontSizeMultiplier: true,
    disabled: true,
    selectable: true,
    selectionColor: true,
    adjustsFontSizeToFit: true,
    minimumFontScale: true,
    textBreakStrategy: true,
    onTextLayout: true,
    onInlineViewLayout: true,
    dataDetectorType: true,
    android_hyphenationFrequency: true,
  },
  directEventTypes: {
    topTextLayout: {
      registrationName: 'onTextLayout',
    },
    topInlineViewLayout: {
      registrationName: 'onInlineViewLayout',
    },
  },
  uiViewClassName: 'RCTText',
};

const virtualTextViewConfig = {
  validAttributes: {
    isHighlighted: true,
    isPressable: true,
    maxFontSizeMultiplier: true,
  },
  uiViewClassName: 'RCTVirtualText',
};

export const NativeText: HostComponent<NativeTextProps> =
  (createReactNativeComponentClass('RCTText', () =>
    createViewConfig(textViewConfig),
  ): any);

export const NativeVirtualText: HostComponent<NativeTextProps> =
  !global.RN$Bridgeless && !UIManager.hasViewManagerConfig('RCTVirtualText')
    ? NativeText
    : (createReactNativeComponentClass('RCTVirtualText', () =>
        createViewConfig(virtualTextViewConfig),
      ): any);
<|endoftext|>


<commit_before>const mdxToJsx = require('@mdx-js/mdx/mdx-hast-to-jsx');
const parser = require('@babel/parser');
const generate = require('@babel/generator').default;
const camelCase = require('lodash/camelCase');
const jsStringEscape = require('js-string-escape');
const { toId } = require('@storybook/router');

// Generate the MDX as is, but append named exports for every
// story in the contents

const STORY_REGEX = /^<Story[\s>]/;
const PREVIEW_REGEX = /^<Preview[\s>]/;
const META_REGEX = /^<Meta[\s>]/;
const RESERVED = /^(?:do|if|in|for|let|new|try|var|case|else|enum|eval|false|null|this|true|void|with|await|break|catch|class|const|super|throw|while|yield|delete|export|import|public|return|static|switch|typeof|default|extends|finally|package|private|continue|debugger|function|arguments|interface|protected|implements|instanceof)$/;

function getAttr(elt, what) {
  const attr = elt.attributes.find(n => n.name.name === what);
  return attr && attr.value;
}

const isReserved = name => RESERVED.exec(name);

const sanitizeName = name => {
  let key = camelCase(name);
  if (isReserved(key)) {
    key = `${key}Story`;
  }
  return key;
};

const getStoryKey = (name, counter) => (name ? sanitizeName(name) : `story${counter}`);

function genStoryExport(ast, context) {
  let storyName = getAttr(ast.openingElement, 'name');
  let storyId = getAttr(ast.openingElement, 'id');
  storyName = storyName && storyName.value;
  storyId = storyId && storyId.value;

  if (!storyId && !storyName) {
    throw new Error('Expected a story name or ID attribute');
  }

  // We don't generate exports for story references or the smart "current story"
  if (storyId || !storyName) {
    return null;
  }

  // console.log('genStoryExport', JSON.stringify(ast, null, 2));

  const statements = [];
  const storyKey = getStoryKey(storyName, context.counter);

  let body = ast.children.find(n => n.type !== 'JSXText');
  let storyCode = null;
  if (!body) {
    // plain text node
    const { code } = generate(ast.children[0], {});
    storyCode = `'${code}'`;
  } else {
    if (body.type === 'JSXExpressionContainer') {
      // FIXME: handle fragments
      body = body.expression;
    }
    const { code } = generate(body, {});
    storyCode = code;
  }
  if (storyCode.trim().startsWith('() =>')) {
    statements.push(`export const ${storyKey} = ${storyCode}`);
  } else {
    statements.push(
      `export const ${storyKey} = () => (
        ${storyCode}
      );`
    );
  }
  statements.push(`${storyKey}.story = {};`);

  // always preserve the name, since CSF exports can get modified by displayName
  statements.push(`${storyKey}.story.name = '${storyName}';`);

  let parameters = getAttr(ast.openingElement, 'parameters');
  parameters = parameters && parameters.expression;
  const source = jsStringEscape(storyCode);
  if (parameters) {
    const { code: params } = generate(parameters, {});
    // FIXME: hack in the story's source as a parameter
    statements.push(`${storyKey}.story.parameters = { mdxSource: '${source}', ...${params} };`);
  } else {
    statements.push(`${storyKey}.story.parameters = { mdxSource: '${source}' };`);
  }

  let decorators = getAttr(ast.openingElement, 'decorators');
  decorators = decorators && decorators.expression;
  if (decorators) {
    const { code: decos } = generate(decorators, {});
    statements.push(`${storyKey}.story.decorators = ${decos};`);
  }

  // eslint-disable-next-line no-param-reassign
  context.storyNameToKey[storyName] = storyKey;

  return {
    [storyKey]: statements.join('\n'),
  };
}

function genPreviewExports(ast, context) {
  // console.log('genPreviewExports', JSON.stringify(ast, null, 2));

  const previewExports = {};
  for (let i = 0; i < ast.children.length; i += 1) {
    const child = ast.children[i];
    if (child.type === 'JSXElement' && child.openingElement.name.name === 'Story') {
      const storyExport = genStoryExport(child, context);
      if (storyExport) {
        Object.assign(previewExports, storyExport);
        // eslint-disable-next-line no-param-reassign
        context.counter += 1;
      }
    }
  }
  return previewExports;
}

function genMeta(ast) {
  let title = getAttr(ast.openingElement, 'title');
  let parameters = getAttr(ast.openingElement, 'parameters');
  let decorators = getAttr(ast.openingElement, 'decorators');
  title = title && `'${title.value}'`;
  if (parameters && parameters.expression) {
    const { code: params } = generate(parameters.expression, {});
    parameters = params;
  }
  if (decorators && decorators.expression) {
    const { code: decos } = generate(decorators.expression, {});
    decorators = decos;
  }
  return {
    title,
    parameters,
    decorators,
  };
}

function getExports(node, counter) {
  const { value, type } = node;
  if (type === 'jsx') {
    if (STORY_REGEX.exec(value)) {
      // Single story
      const ast = parser.parseExpression(value, { plugins: ['jsx'] });
      const storyExport = genStoryExport(ast, counter);
      return storyExport && { stories: storyExport };
    }
    if (PREVIEW_REGEX.exec(value)) {
      // Preview, possibly containing multiple stories
      const ast = parser.parseExpression(value, { plugins: ['jsx'] });
      return { stories: genPreviewExports(ast, counter) };
    }
    if (META_REGEX.exec(value)) {
      // Preview, possibly containing multiple stories
      const ast = parser.parseExpression(value, { plugins: ['jsx'] });
      return { meta: genMeta(ast) };
    }
  }
  return null;
}

// insert `mdxKind` into the context so that we can know what "kind" we're rendering into
// when we render <Story name="xxx">...</Story>, since this MDX can be attached to any `selectedKind`!
const wrapperJs = `
componentMeta.parameters = componentMeta.parameters || {};
componentMeta.parameters.docs = {
  container: ({ context, children }) => <DocsContainer context={{...context, mdxStoryNameToId}}>{children}</DocsContainer>,
  page: MDXContent,
};
`.trim();

function stringifyMeta(meta) {
  let result = '{ ';
  Object.entries(meta).forEach(([key, val]) => {
    if (val) {
      result += `'${key}': ${val}, `;
    }
  });
  result += ' }';
  return result;
}

function extractExports(node, options) {
  // we're overriding default export
  const defaultJsx = mdxToJsx.toJSX(node, {}, { ...options, skipExport: true });
  const storyExports = [];
  const includeStories = [];
  let metaExport = null;
  const context = {
    counter: 0,
    storyNameToKey: {},
  };
  node.children.forEach(n => {
    const exports = getExports(n, context);
    if (exports) {
      const { stories, meta } = exports;
      if (stories) {
        Object.entries(stories).forEach(([key, story]) => {
          includeStories.push(key);
          storyExports.push(story);
        });
      }
      if (meta) {
        if (metaExport) {
          throw new Error('Meta can only be declared once');
        }
        metaExport = meta;
      }
    }
  });
  if (metaExport) {
    if (!storyExports.length) {
      storyExports.push(
        'export const storybookDocsOnly = () => { throw new Error("Docs-only story"); };'
      );
      storyExports.push('storybookDocsOnly.story = { parameters: { docsOnly: true } };');
      includeStories.push('storybookDocsOnly');
    }
  } else {
    metaExport = {};
  }
  metaExport.includeStories = JSON.stringify(includeStories);

  const { title } = metaExport;
  const mdxStoryNameToId = Object.entries(context.storyNameToKey).reduce(
    (acc, [storyName, storyKey]) => {
      if (title) {
        acc[storyName] = toId(title, storyKey);
      }
      return acc;
    },
    {}
  );

  const fullJsx = [
    'import { DocsContainer } from "@storybook/addon-docs/blocks";',
    defaultJsx,
    ...storyExports,
    `const componentMeta = ${stringifyMeta(metaExport)};`,
    `const mdxStoryNameToId = ${JSON.stringify(mdxStoryNameToId)};`,
    wrapperJs,
    'export default componentMeta;',
  ].join('\n\n');

  return fullJsx;
}

function createCompiler(mdxOptions) {
  return function compiler(options = {}) {
    this.Compiler = tree => extractExports(tree, options, mdxOptions);
  };
}

module.exports = createCompiler;
<commit_msg>Add comment & remove unnecssary quotes<commit_after>const mdxToJsx = require('@mdx-js/mdx/mdx-hast-to-jsx');
const parser = require('@babel/parser');
const generate = require('@babel/generator').default;
const camelCase = require('lodash/camelCase');
const jsStringEscape = require('js-string-escape');
const { toId } = require('@storybook/router');

// Generate the MDX as is, but append named exports for every
// story in the contents

const STORY_REGEX = /^<Story[\s>]/;
const PREVIEW_REGEX = /^<Preview[\s>]/;
const META_REGEX = /^<Meta[\s>]/;
const RESERVED = /^(?:do|if|in|for|let|new|try|var|case|else|enum|eval|false|null|this|true|void|with|await|break|catch|class|const|super|throw|while|yield|delete|export|import|public|return|static|switch|typeof|default|extends|finally|package|private|continue|debugger|function|arguments|interface|protected|implements|instanceof)$/;

function getAttr(elt, what) {
  const attr = elt.attributes.find(n => n.name.name === what);
  return attr && attr.value;
}

const isReserved = name => RESERVED.exec(name);

const sanitizeName = name => {
  let key = camelCase(name);
  if (isReserved(key)) {
    key = `${key}Story`;
  }
  return key;
};

const getStoryKey = (name, counter) => (name ? sanitizeName(name) : `story${counter}`);

function genStoryExport(ast, context) {
  let storyName = getAttr(ast.openingElement, 'name');
  let storyId = getAttr(ast.openingElement, 'id');
  storyName = storyName && storyName.value;
  storyId = storyId && storyId.value;

  if (!storyId && !storyName) {
    throw new Error('Expected a story name or ID attribute');
  }

  // We don't generate exports for story references or the smart "current story"
  if (storyId || !storyName) {
    return null;
  }

  // console.log('genStoryExport', JSON.stringify(ast, null, 2));

  const statements = [];
  const storyKey = getStoryKey(storyName, context.counter);

  let body = ast.children.find(n => n.type !== 'JSXText');
  let storyCode = null;
  if (!body) {
    // plain text node
    const { code } = generate(ast.children[0], {});
    storyCode = `'${code}'`;
  } else {
    if (body.type === 'JSXExpressionContainer') {
      // FIXME: handle fragments
      body = body.expression;
    }
    const { code } = generate(body, {});
    storyCode = code;
  }
  if (storyCode.trim().startsWith('() =>')) {
    statements.push(`export const ${storyKey} = ${storyCode}`);
  } else {
    statements.push(
      `export const ${storyKey} = () => (
        ${storyCode}
      );`
    );
  }
  statements.push(`${storyKey}.story = {};`);

  // always preserve the name, since CSF exports can get modified by displayName
  statements.push(`${storyKey}.story.name = '${storyName}';`);

  let parameters = getAttr(ast.openingElement, 'parameters');
  parameters = parameters && parameters.expression;
  const source = jsStringEscape(storyCode);
  if (parameters) {
    const { code: params } = generate(parameters, {});
    // FIXME: hack in the story's source as a parameter
    statements.push(`${storyKey}.story.parameters = { mdxSource: '${source}', ...${params} };`);
  } else {
    statements.push(`${storyKey}.story.parameters = { mdxSource: '${source}' };`);
  }

  let decorators = getAttr(ast.openingElement, 'decorators');
  decorators = decorators && decorators.expression;
  if (decorators) {
    const { code: decos } = generate(decorators, {});
    statements.push(`${storyKey}.story.decorators = ${decos};`);
  }

  // eslint-disable-next-line no-param-reassign
  context.storyNameToKey[storyName] = storyKey;

  return {
    [storyKey]: statements.join('\n'),
  };
}

function genPreviewExports(ast, context) {
  // console.log('genPreviewExports', JSON.stringify(ast, null, 2));

  const previewExports = {};
  for (let i = 0; i < ast.children.length; i += 1) {
    const child = ast.children[i];
    if (child.type === 'JSXElement' && child.openingElement.name.name === 'Story') {
      const storyExport = genStoryExport(child, context);
      if (storyExport) {
        Object.assign(previewExports, storyExport);
        // eslint-disable-next-line no-param-reassign
        context.counter += 1;
      }
    }
  }
  return previewExports;
}

function genMeta(ast) {
  let title = getAttr(ast.openingElement, 'title');
  let parameters = getAttr(ast.openingElement, 'parameters');
  let decorators = getAttr(ast.openingElement, 'decorators');
  title = title && `'${title.value}'`;
  if (parameters && parameters.expression) {
    const { code: params } = generate(parameters.expression, {});
    parameters = params;
  }
  if (decorators && decorators.expression) {
    const { code: decos } = generate(decorators.expression, {});
    decorators = decos;
  }
  return {
    title,
    parameters,
    decorators,
  };
}

function getExports(node, counter) {
  const { value, type } = node;
  if (type === 'jsx') {
    if (STORY_REGEX.exec(value)) {
      // Single story
      const ast = parser.parseExpression(value, { plugins: ['jsx'] });
      const storyExport = genStoryExport(ast, counter);
      return storyExport && { stories: storyExport };
    }
    if (PREVIEW_REGEX.exec(value)) {
      // Preview, possibly containing multiple stories
      const ast = parser.parseExpression(value, { plugins: ['jsx'] });
      return { stories: genPreviewExports(ast, counter) };
    }
    if (META_REGEX.exec(value)) {
      // Preview, possibly containing multiple stories
      const ast = parser.parseExpression(value, { plugins: ['jsx'] });
      return { meta: genMeta(ast) };
    }
  }
  return null;
}

// insert `mdxKind` into the context so that we can know what "kind" we're rendering into
// when we render <Story name="xxx">...</Story>, since this MDX can be attached to any `selectedKind`!
const wrapperJs = `
componentMeta.parameters = componentMeta.parameters || {};
componentMeta.parameters.docs = {
  container: ({ context, children }) => <DocsContainer context={{...context, mdxStoryNameToId}}>{children}</DocsContainer>,
  page: MDXContent,
};
`.trim();

// Use this rather than JSON.stringify because `Meta`'s attributes
// are already valid code strings, so we want to insert them raw
// rather than add an extra set of quotes
function stringifyMeta(meta) {
  let result = '{ ';
  Object.entries(meta).forEach(([key, val]) => {
    if (val) {
      result += `${key}: ${val}, `;
    }
  });
  result += ' }';
  return result;
}

function extractExports(node, options) {
  // we're overriding default export
  const defaultJsx = mdxToJsx.toJSX(node, {}, { ...options, skipExport: true });
  const storyExports = [];
  const includeStories = [];
  let metaExport = null;
  const context = {
    counter: 0,
    storyNameToKey: {},
  };
  node.children.forEach(n => {
    const exports = getExports(n, context);
    if (exports) {
      const { stories, meta } = exports;
      if (stories) {
        Object.entries(stories).forEach(([key, story]) => {
          includeStories.push(key);
          storyExports.push(story);
        });
      }
      if (meta) {
        if (metaExport) {
          throw new Error('Meta can only be declared once');
        }
        metaExport = meta;
      }
    }
  });
  if (metaExport) {
    if (!storyExports.length) {
      storyExports.push(
        'export const storybookDocsOnly = () => { throw new Error("Docs-only story"); };'
      );
      storyExports.push('storybookDocsOnly.story = { parameters: { docsOnly: true } };');
      includeStories.push('storybookDocsOnly');
    }
  } else {
    metaExport = {};
  }
  metaExport.includeStories = JSON.stringify(includeStories);

  const { title } = metaExport;
  const mdxStoryNameToId = Object.entries(context.storyNameToKey).reduce(
    (acc, [storyName, storyKey]) => {
      if (title) {
        acc[storyName] = toId(title, storyKey);
      }
      return acc;
    },
    {}
  );

  const fullJsx = [
    'import { DocsContainer } from "@storybook/addon-docs/blocks";',
    defaultJsx,
    ...storyExports,
    `const componentMeta = ${stringifyMeta(metaExport)};`,
    `const mdxStoryNameToId = ${JSON.stringify(mdxStoryNameToId)};`,
    wrapperJs,
    'export default componentMeta;',
  ].join('\n\n');

  return fullJsx;
}

function createCompiler(mdxOptions) {
  return function compiler(options = {}) {
    this.Compiler = tree => extractExports(tree, options, mdxOptions);
  };
}

module.exports = createCompiler;
<|endoftext|>


<commit_before>class RcdMaterialDialogContentArea extends RcdDivElement {
    constructor(title) {
        super();
        this.title = title ? new RcdTextDivElement(title).init().
            addClass('rcd-material-dialog-title') : undefined;
        this.body = new RcdDivElement().init().
            addClass('rcd-material-dialog-body');
    }

    init() {
        super.init().
            addClass('rcd-material-dialog-content-area');
        if (this.title) {
            this.addChild(this.title);
        }
        return this.addChild(this.body);
    }

    addItem(item) {
        this.body.addChild(item);
        return this;
    }
}

class RcdMaterialDialog extends RcdDivElement {
    constructor(title, text) {
        super();
        this.contentArea = new RcdMaterialDialogContentArea(title).init();
        if (text) {
            const textItem = new RcdTextElement(text).init();
            this.contentArea.addItem(textItem);
        }
        this.actions = new RcdDivElement().init().
            addClass('rcd-material-dialog-actions');
    }

    init() {
        return this.addClass('rcd-material-dialog').
            addChild(this.contentArea).
            addChild(this.actions);
    }

    addItem(item) {
        this.contentArea.addChild(item);
    }

    addAction(label, callback) {
        const action = new RcdMaterialButtonArea(label, callback, RcdMaterialButtonType.FLAT).init().
            addClass('rcd-material-dialog-action');
        this.actions.addChild(action);
        return this;
    }
}

class RcdMaterialModalDialog extends RcdDivElement {
    constructor(title, text, overlay) {
        super();
        this.overlay = overlay;
        this.dialog = new RcdMaterialDialog(title, text).init();
    }

    init() {
        if (this.overlay) {
            this.addClass('rcd-material-overlay');
        }
        return this.addClass('rcd-material-cache').
            addClass('rcd-body'). //Workaround for widget
            addChild(this.dialog);
    }

    addItem(item) {
        this.dialog.addItem(item);
        return this;
    }

    addAction(label, callback) {
        this.dialog.addAction(label, callback);
        return this;
    }

    open(parent) {
        return this.setParent(parent).
            focus();
    }

    close() {
        this.removeParent();
    }
}

class RcdMaterialInfoDialog extends RcdMaterialModalDialog {
    constructor(params) {
        super(params.title, params.text, false);
    }
}

class RcdMaterialDetailsDialog extends RcdMaterialModalDialog {
    constructor(params) {
        super(params.title, params.text, true);
    }

    init() {
        const closeCallback = () => this.close();
        super.init().
            addAction('CLOSE', closeCallback).
            addKeyUpListener('Enter', closeCallback).
            addKeyUpListener('Escape', closeCallback);
        return this;
    }
}

class RcdMaterialConfirmationDialog extends RcdMaterialModalDialog {
    constructor(params) {
        super(params.title, params.text, true);
        this.callback = params.callback;
        this.confirmationLabel = params.confirmationLabel || 'OK';
    }

    init() {
        const closeCallback = () => this.close();
        const confirmationCallback = (source, event) => {
            this.close();
            this.callback();
            event.stopPropagation();
        };
        return super.init().
            addAction('CANCEL', closeCallback).
            addAction(this.confirmationLabel, confirmationCallback).
            addKeyUpListener('Enter', confirmationCallback).
            addKeyUpListener('Escape', closeCallback);
    }
}

class RcdMaterialSelectionDialog extends RcdMaterialModalDialog {
    constructor(params) {
        super(params.title, params.text, true);
        this.callback = params.callback;
        this.dropdownField = new RcdMaterialDropdown(params.label, params.options).init();
        this.confirmationLabel = params.confirmationLabel || 'OK';
    }

    init() {
        const closeCallback = () => this.close();
        const confirmationCallback = (source, event) => {
            this.close();
            this.callback(this.dropdownField.getValue());
            event.stopPropagation();
        };
        return super.init().
            addAction('CANCEL', closeCallback).
            addAction(this.confirmationLabel, confirmationCallback).
            addKeyUpListener('Enter', confirmationCallback).
            addKeyUpListener('Escape', closeCallback).
            addItem(this.dropdownField);
    }

    open(parent) {
        super.open(parent);
        this.dropdownField.focus();
        return this;
    }
}

class RcdMaterialInputDialog extends RcdMaterialModalDialog {
    constructor(params) {
        super(params.title, params.text, true);
        this.callback = params.callback;
        this.inputField = new RcdMaterialTextField(params.label, params.placeholder).init().
            setValue(params.value || '');
        this.confirmationLabel = params.confirmationLabel || 'OK';
    }

    init() {
        const closeCallback = () => this.close();
        const confirmationCallback = (source, event) => {
            this.close();
            this.callback(this.inputField.getValue());
            event.stopPropagation();
        };
        return super.init().
            addAction('CANCEL', closeCallback).
            addAction(this.confirmationLabel, confirmationCallback).
            addKeyUpListener('Enter', confirmationCallback).
            addKeyUpListener('Escape', closeCallback).
            addItem(this.inputField);
    }

    open(parent) {
        super.open(parent);
        this.inputField.focus().select();
        return this;
    }
}<commit_msg>Details callback<commit_after>class RcdMaterialDialogContentArea extends RcdDivElement {
    constructor(title) {
        super();
        this.title = title ? new RcdTextDivElement(title).init().
            addClass('rcd-material-dialog-title') : undefined;
        this.body = new RcdDivElement().init().
            addClass('rcd-material-dialog-body');
    }

    init() {
        super.init().
            addClass('rcd-material-dialog-content-area');
        if (this.title) {
            this.addChild(this.title);
        }
        return this.addChild(this.body);
    }

    addItem(item) {
        this.body.addChild(item);
        return this;
    }
}

class RcdMaterialDialog extends RcdDivElement {
    constructor(title, text) {
        super();
        this.contentArea = new RcdMaterialDialogContentArea(title).init();
        if (text) {
            const textItem = new RcdTextElement(text).init();
            this.contentArea.addItem(textItem);
        }
        this.actions = new RcdDivElement().init().
            addClass('rcd-material-dialog-actions');
    }

    init() {
        return this.addClass('rcd-material-dialog').
            addChild(this.contentArea).
            addChild(this.actions);
    }

    addItem(item) {
        this.contentArea.addChild(item);
    }

    addAction(label, callback) {
        const action = new RcdMaterialButtonArea(label, callback, RcdMaterialButtonType.FLAT).init().
            addClass('rcd-material-dialog-action');
        this.actions.addChild(action);
        return this;
    }
}

class RcdMaterialModalDialog extends RcdDivElement {
    constructor(title, text, overlay) {
        super();
        this.overlay = overlay;
        this.dialog = new RcdMaterialDialog(title, text).init();
    }

    init() {
        if (this.overlay) {
            this.addClass('rcd-material-overlay');
        }
        return this.addClass('rcd-material-cache').
            addClass('rcd-body'). //Workaround for widget
            addChild(this.dialog);
    }

    addItem(item) {
        this.dialog.addItem(item);
        return this;
    }

    addAction(label, callback) {
        this.dialog.addAction(label, callback);
        return this;
    }

    open(parent) {
        return this.setParent(parent).
            focus();
    }

    close() {
        this.removeParent();
    }
}

class RcdMaterialInfoDialog extends RcdMaterialModalDialog {
    constructor(params) {
        super(params.title, params.text, false);
    }
}

class RcdMaterialDetailsDialog extends RcdMaterialModalDialog {
    constructor(params) {
        super(params.title, params.text, true);
        this.callback = params.callback;
    }

    init() {
        const closeCallback = () => {
            this.close();
            if (this.callback) {
                this.callback();
            }
        };
        super.init().
            addAction('CLOSE', closeCallback).
            addKeyUpListener('Enter', closeCallback).
            addKeyUpListener('Escape', closeCallback);
        return this;
    }
}

class RcdMaterialConfirmationDialog extends RcdMaterialModalDialog {
    constructor(params) {
        super(params.title, params.text, true);
        this.callback = params.callback;
        this.confirmationLabel = params.confirmationLabel || 'OK';
    }

    init() {
        const closeCallback = () => this.close();
        const confirmationCallback = (source, event) => {
            this.close();
            this.callback();
            event.stopPropagation();
        };
        return super.init().
            addAction('CANCEL', closeCallback).
            addAction(this.confirmationLabel, confirmationCallback).
            addKeyUpListener('Enter', confirmationCallback).
            addKeyUpListener('Escape', closeCallback);
    }
}

class RcdMaterialSelectionDialog extends RcdMaterialModalDialog {
    constructor(params) {
        super(params.title, params.text, true);
        this.callback = params.callback;
        this.dropdownField = new RcdMaterialDropdown(params.label, params.options).init();
        this.confirmationLabel = params.confirmationLabel || 'OK';
    }

    init() {
        const closeCallback = () => this.close();
        const confirmationCallback = (source, event) => {
            this.close();
            this.callback(this.dropdownField.getValue());
            event.stopPropagation();
        };
        return super.init().
            addAction('CANCEL', closeCallback).
            addAction(this.confirmationLabel, confirmationCallback).
            addKeyUpListener('Enter', confirmationCallback).
            addKeyUpListener('Escape', closeCallback).
            addItem(this.dropdownField);
    }

    open(parent) {
        super.open(parent);
        this.dropdownField.focus();
        return this;
    }
}

class RcdMaterialInputDialog extends RcdMaterialModalDialog {
    constructor(params) {
        super(params.title, params.text, true);
        this.callback = params.callback;
        this.inputField = new RcdMaterialTextField(params.label, params.placeholder).init().
            setValue(params.value || '');
        this.confirmationLabel = params.confirmationLabel || 'OK';
    }

    init() {
        const closeCallback = () => this.close();
        const confirmationCallback = (source, event) => {
            this.close();
            this.callback(this.inputField.getValue());
            event.stopPropagation();
        };
        return super.init().
            addAction('CANCEL', closeCallback).
            addAction(this.confirmationLabel, confirmationCallback).
            addKeyUpListener('Enter', confirmationCallback).
            addKeyUpListener('Escape', closeCallback).
            addItem(this.inputField);
    }

    open(parent) {
        super.open(parent);
        this.inputField.focus().select();
        return this;
    }
}<|endoftext|>


<commit_before>angular.module('onsTemplates')
    .controller('T5Ctrl', ['$scope', 'Downloader',
        function($scope, Downloader) {

            var t5 = this;
            $scope.header = "Time Series";
            $scope.sidebar = true;
            $scope.sidebarUrl = "/app/templates/t5/t5sidebar.html";

            function downloadXls() {
                download('xlsx');
            }

            function downloadCsv() {
                download('csv');
            }

            function download(type) {
                var downloadRequest = {
                    type: type
                };
                downloadRequest.uriList = [$scope.getPath()];
                var fileName = $scope.getPage() + '.' + downloadRequest.type;
                Downloader.downloadFile(downloadRequest, fileName);
            }

            angular.extend(t5, {
                downloadXls: downloadXls,
                downloadCsv: downloadCsv
            });

        }
    ])

.controller('chartController', ['$scope', '$location',
    function($scope, $location) {
        var data = $scope.taxonomy.data;
        var categoriesY = [];
        var categoriesYnum = [];
        var seriesDataY = [];
        var categoriesQ = [];
        var categoriesQnum = [];
        var seriesDataQ = [];
        var categoriesM = [];
        var categoriesMnum = [];
        var seriesDataM = [];
        var currentSorter;
        var currentCategories;
        var currentSeries;
        var reY = new RegExp('^[0-9]{4}$');
        var reQ = new RegExp('^[0-9]{4}.[Q1-4]{2}$');
        var reM = new RegExp('^[0-9]{4}.[A-Z]{3}$');

        $scope.chart = data;

        makeArray($scope.chart.data);
        // Year by default
        $scope.tableValue = makeTableObj(categoriesY, seriesDataY, categoriesYnum);

        currentCategories = categoriesY;
        currentSeries = seriesDataY;
        currentSorter = categoriesYnum;

        $scope.graphValue = makeGraphValue(categoriesY, seriesDataY, categoriesYnum);

        function makeGraphValue(x, y, sorter) {
            return [x, y, sorter];
        }

        //Takes data from json file and transforms it in an array to be read by Highcharts
        function makeArray(jsonData) {
            // Will make the buttons for y,q,m appear or not
            $scope.hasYData = false;
            $scope.hasQData = false;
            $scope.hasMData = false;
            for (var i = 0; i < jsonData.length; i++) {
                if (reY.test(jsonData[i].date)) {
                    categoriesY.push(jsonData[i].date);
                    categoriesYnum.push(Number(jsonData[i].date));
                    seriesDataY.push(Number(jsonData[i].value));
                    $scope.hasYData = true;
                }
                if (reQ.test(jsonData[i].date)) {
                    categoriesQ.push(jsonData[i].date);
                    categoriesQnum.push(QtoNum(jsonData[i].date));
                    seriesDataQ.push(Number(jsonData[i].value));
                    $scope.hasQData = true;
                }
                if (reM.test(jsonData[i].date)) {
                    categoriesM.push(jsonData[i].date);
                    categoriesMnum.push(MtoNum(jsonData[i].date));
                    seriesDataM.push(Number(jsonData[i].value));
                    $scope.hasMData = true;
                }
            }
        }

        /* ****************************************
        WARNING!!!!
        THIS WILL FAIL IF THE DATA FORMAT CHANGES
        ******************************************* */
        // helper to sort table by quarter
        function QtoNum(quarter) {
            return Number(quarter.replace(' Q', '.'));
        }

        /* ****************************************
        WARNING!!!!
        THIS WILL FAIL IF THE DATA FORMAT CHANGES
        ******************************************* */
        // helper to sort table by month
        function MtoNum(months) {
            var month = months.match(/ [A-Z]{3}/i);
            if (month[0].toUpperCase() === ' JAN') {
                return Number(months.replace(month[0], '.01'));
            }
            if (month[0].toUpperCase() === ' FEB') {
                return Number(months.replace(month[0], '.02'));
            }
            if (month[0].toUpperCase() === ' MAR') {
                return Number(months.replace(month[0], '.03'));
            }
            if (month[0].toUpperCase() === ' APR') {
                return Number(months.replace(month[0], '.04'));
            }
            if (month[0].toUpperCase() === ' MAY') {
                return Number(months.replace(month[0], '.05'));
            }
            if (month[0].toUpperCase() === ' JUN') {
                return Number(months.replace(month[0], '.06'));
            }
            if (month[0].toUpperCase() === ' JUL') {
                return Number(months.replace(month[0], '.07'));
            }
            if (month[0].toUpperCase() === ' AUG') {
                return Number(months.replace(month[0], '.08'));
            }
            if (month[0].toUpperCase() === ' SEP') {
                return Number(months.replace(month[0], '.09'));
            }
            if (month[0].toUpperCase() === ' OCT') {
                return Number(months.replace(month[0], '.10'));
            }
            if (month[0].toUpperCase() === ' NOV') {
                return Number(months.replace(month[0], '.11'));
            }
            if (month[0].toUpperCase() === ' DEC') {
                return Number(months.replace(month[0], '.12'));
            }
        }

        // Creates an object for angular table control
        function makeTableObj(key, values, number) {
            var obj = [];
            var x = [];
            for (var i = 0; i < key.length; i++) {
                obj[0] = key[i];
                obj[1] = values[i];
                obj[2] = number[i];
                x.push({
                    "date": obj[0],
                    "values": obj[1],
                    "number": obj[2]
                });
            }
            return x;
        }

        $scope.changeChartRange = function changeChartRange() {
            var from = $scope.chartDataFrom;
            var to = $scope.chartDataTo;
            var w;
            var x;
            var y;
            var categoriesRange = [];
            var seriesRange = [];
            var sorterRange = [];
            for (var i = 0; i < currentCategories.length; i++) {
                w = currentSorter[i];
                x = currentCategories[i];
                y = currentSeries[i];
                if (from && to) {
                    if (w >= from && w <= to) {
                        categoriesRange.push(x);
                        seriesRange.push(y);
                        sorterRange.push(w);
                    }
                } else if (from) {
                    if (w >= from) {
                        categoriesRange.push(x);
                        seriesRange.push(y);
                        sorterRange.push(w);
                    }
                } else if (to) {
                    if (w <= to) {
                        categoriesRange.push(x);
                        seriesRange.push(y);
                        sorterRange.push(w);
                    }
                } else {
                    categoriesRange.push(x);
                    seriesRange.push(y);
                    sorterRange.push(w);
                }
            }
            $scope.graphValue = makeGraphValue(categoriesRange, seriesRange, sorterRange);
            $scope.chartData.options.xAxis.categories = $scope.graphValue[0];
            $scope.chartData.options.xAxis.tickInterval = tickInterval(categoriesY.length);
            $scope.chartData.series[0].data = $scope.graphValue[1];
        };

        $scope.chartData = getData();
        // year by default
        $scope.chartData.options.xAxis.tickInterval = tickInterval(categoriesY.length);

        //If true shows graph, else table.
        $scope.chartTable = true;

        $scope.changeChartType = function(type) {
            if (type === "line") {
                $scope.chartTable = true;
            }
            if (type === "table") {
                $scope.chartTable = false;
            }
        };

        //year (0, by Default), quarter (1) or month (2)
        $scope.yqm = 0;
        $scope.changeTime = function(time) {
            if (time === 'year') {
                $scope.tableValue = makeTableObj(categoriesY, seriesDataY, categoriesYnum);
                $scope.graphValue = makeGraphValue(categoriesY, seriesDataY, categoriesYnum);
                $scope.yqm = 0;
                $scope.chartData.options.xAxis.categories = $scope.graphValue[0];
                $scope.chartData.options.xAxis.tickInterval = tickInterval(categoriesY.length);
                $scope.chartData.series[0].data = $scope.graphValue[1];
                currentCategories=categoriesY;
                currentSeries=seriesDataY;
                currentSorter = categoriesYnum;
            }
            if (time === 'quarter') {
                $scope.tableValue = makeTableObj(categoriesQ, seriesDataQ, categoriesQnum);
                $scope.graphValue = makeGraphValue(categoriesQ, seriesDataQ, categoriesQnum);
                $scope.yqm = 1;
                $scope.chartData.options.xAxis.categories = $scope.graphValue[0];
                $scope.chartData.options.xAxis.tickInterval = tickInterval(categoriesQ.length);
                $scope.chartData.series[0].data = $scope.graphValue[1];
                currentCategories=categoriesQ;
                currentSeries=seriesDataQ;
                currentSorter = categoriesQnum;
            }
            if (time === 'month') {
                $scope.tableValue = makeTableObj(categoriesM, seriesDataM, categoriesMnum);
                $scope.graphValue = makeGraphValue(categoriesM, seriesDataM, categoriesMnum);
                $scope.yqm = 2;
                $scope.chartData.options.xAxis.categories = $scope.graphValue[0];
                $scope.chartData.options.xAxis.tickInterval = tickInterval(categoriesM.length);
                $scope.chartData.series[0].data = $scope.graphValue[1];
                currentCategories=categoriesM;
                currentSeries=seriesDataM;
                currentSorter = categoriesMnum;
            }
        };

        //Defines the intervals in xAxis according to data
        function tickInterval(categories) {
            var tick;
            if (categories <= 20) {
                tick = 1;
            }
            if (categories > 20 && categories <= 80) {
                tick = 4;
            }
            if (categories > 80) {
                tick = 12;
            }
            if (categories > 240) {
                tick = 48;
            }
            if (categories > 480) {
                tick = 96;
            }
            if (categories > 960) {
                tick = 192;
            }
            return tick;
        }

        function getData() {
            var data = {
                options: {
                    chart: {
                        type: 'line',
                    },
                    colors: ['#007dc3', '#409ed2', '#7fbee1', '#007dc3', '#409ed2', '#7fbee1'],

                    title: {
                        text: ''
                    },
                    subtitle: {
                        text: ''
                    },
                    navigation: {
                        buttonOptions: {
                            enabled: false
                        //     verticalAlign: 'bottom',
                        //     y: 0,
                        //     text: 'Image',
                        //     theme: {
                        //         fill: '#0054aa',
                        //         r: 0,
                        //         states: {
                        //             hover: {
                        //                 fill: '#004790'
                        //             },
                        //             select: {
                        //                 fill: '#004790'
                        //             }
                                // }
                             // }
                        }
                    },
                    xAxis: {
                        categories: $scope.graphValue[0],
                        // tickInterval: 1,
                        labels: {
                            formatter: function() {
                                var w = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
                                var response = "";
                                if (w < 768) {
                                    if (this.isFirst) {
                                        count = 0;
                                    }
                                    if (count % 3 === 0) {
                                        response = this.value;
                                    }
                                    count++;
                                } else {
                                    response = this.value;
                                }
                                return response;
                            },
                        },
                        tickmarkPlacement: 'on'
                    },
                    yAxis: {
                        title: {
                            text: $scope.chart.units
                        }
                    },

                    credits: {
                        enabled: false
                    },

                    plotOptions: {
                        series: {
                            shadow: false,
                            states: {
                                hover: {
                                    enabled: true,
                                    shadow: false,
                                    lineWidth: 3,
                                    lineWidthPlus: 0,
                                    marker: {
                                        height: 0,
                                        width: 0,
                                        halo: false,
                                        enabled: true,
                                        fillColor: null,
                                        radiusPlus: null,
                                        lineWidth: 3,
                                        lineWidthPlus: 0
                                    }
                                }
                            }
                        }
                    },
                    tooltip: {
                        shared: true,
                        width: '150px',
                        crosshairs: {
                            width: 2,
                            color: '#f37121'
                        },
                        positioner: function(labelWidth, labelHeight, point) {
                            var w = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
                            var points = {
                                x: 30,
                                y: 42
                            };
                            var tooltipX, tooltipY;
                            var chart = Highcharts.charts[Highcharts.charts.length - 1];
                            if (w > 768) {

                                if (point.plotX + labelWidth > chart.plotWidth) {
                                    tooltipX = point.plotX + chart.plotLeft - labelWidth - 20;
                                    $("#custom-tooltip").removeClass('tooltip-left');
                                } else {
                                    tooltipX = point.plotX + chart.plotLeft + 20;
                                    $("#custom-tooltip").removeClass('tooltip-right');
                                }

                                tooltipY = 50;
                                points = {
                                    x: tooltipX,
                                    y: tooltipY
                                };
                            } else {
                                $("#custom-tooltip").removeClass('tooltip-left');
                                $("#custom-tooltip").removeClass('tooltip-right');
                            }

                            return points;
                        },

                        formatter: function() {
                            var id = '
';
                            var block = id + "
";
                            var title = '' + this.x + ':
';
                            var symbol = ['
●
', '
■
', '
♦
', '
▲
', '
▼
'];

                            var content = block + "

";

                            // symbols
                            $.each(this.points, function(i, val) {
                                content += symbol[i];
                            });

                            content += "
";
                            content += "
";
                            content += title;

                            // series names and values
                            $.each(this.points, function(i, val) {
                                content += '
' + val.point.series.chart.series[i].name + "
Value: " + Highcharts.numberFormat(val.y, 2) + '
';
                            });
                            content += "
";
                            return content;
                        },

                        backgroundColor: 'rgba(255, 255, 255, 0)',
                        borderWidth: 0,
                        borderColor: 'rgba(255, 255, 255, 0)',
                        shadow: false,
                        useHTML: true

                    }
                },

                series: [{
                    name: $scope.chart.name,
                    data: $scope.graphValue[1],
                    marker: {
                        symbol: "circle",
                        states: {
                            hover: {
                                fillColor: '#007dc3',
                                radiusPlus: 0,
                                lineWidthPlus: 0
                            }
                        }
                    },
                    dashStyle: 'Solid',
                }]
            };
            return data;
        }
            // the button handler
            $('#imgExp').click(function() {
                var chartExp = $('#chart_prices').highcharts();
                chartExp.exportChart();
            });
    }
]);
<commit_msg>T5 graph range controller<commit_after>angular.module('onsTemplates')
    .controller('T5Ctrl', ['$scope', 'Downloader',
        function($scope, Downloader) {

            var t5 = this;
            $scope.header = "Time Series";
            $scope.sidebar = true;
            $scope.sidebarUrl = "/app/templates/t5/t5sidebar.html";

            function downloadXls() {
                download('xlsx');
            }

            function downloadCsv() {
                download('csv');
            }

            function download(type) {
                var downloadRequest = {
                    type: type
                };
                downloadRequest.uriList = [$scope.getPath()];
                var fileName = $scope.getPage() + '.' + downloadRequest.type;
                Downloader.downloadFile(downloadRequest, fileName);
            }

            angular.extend(t5, {
                downloadXls: downloadXls,
                downloadCsv: downloadCsv
            });

        }
    ])

.controller('chartController', ['$scope', '$location',
    function($scope, $location) {
        var data = $scope.taxonomy.data;
        var categoriesY = [];
        var categoriesYnum = [];
        var seriesDataY = [];
        var categoriesQ = [];
        var categoriesQnum = [];
        var seriesDataQ = [];
        var categoriesM = [];
        var categoriesMnum = [];
        var seriesDataM = [];
        var currentSorter;
        var currentCategories;
        var currentSeries;
        var reY = new RegExp('^[0-9]{4}$');
        var reQ = new RegExp('^[0-9]{4}.[Q1-4]{2}$');
        var reM = new RegExp('^[0-9]{4}.[A-Z]{3}$');

        $scope.chart = data;

        makeArray($scope.chart.data);
        // Year by default
        $scope.tableValue = makeTableObj(categoriesY, seriesDataY, categoriesYnum);

        currentCategories = categoriesY;
        currentSeries = seriesDataY;
        currentSorter = categoriesYnum;

        $scope.graphValue = makeGraphValue(categoriesY, seriesDataY, categoriesYnum);

        function makeGraphValue(x, y, sorter) {
            return [x, y, sorter];
        }

        //Takes data from json file and transforms it in an array to be read by Highcharts
        function makeArray(jsonData) {
            // Will make the buttons for y,q,m appear or not
            $scope.hasYData = false;
            $scope.hasQData = false;
            $scope.hasMData = false;
            for (var i = 0; i < jsonData.length; i++) {
                if (reY.test(jsonData[i].date)) {
                    categoriesY.push(jsonData[i].date);
                    categoriesYnum.push(Number(jsonData[i].date));
                    seriesDataY.push(Number(jsonData[i].value));
                    $scope.hasYData = true;
                }
                if (reQ.test(jsonData[i].date)) {
                    categoriesQ.push(jsonData[i].date);
                    categoriesQnum.push(QtoNum(jsonData[i].date));
                    seriesDataQ.push(Number(jsonData[i].value));
                    $scope.hasQData = true;
                }
                if (reM.test(jsonData[i].date)) {
                    categoriesM.push(jsonData[i].date);
                    categoriesMnum.push(MtoNum(jsonData[i].date));
                    seriesDataM.push(Number(jsonData[i].value));
                    $scope.hasMData = true;
                }
            }
        }

        /* ****************************************
        WARNING!!!!
        THIS WILL FAIL IF THE DATA FORMAT CHANGES
        ******************************************* */
        // helper to sort table by quarter
        function QtoNum(quarter) {
            return Number(quarter.replace(' Q', '.'));
        }

        /* ****************************************
        WARNING!!!!
        THIS WILL FAIL IF THE DATA FORMAT CHANGES
        ******************************************* */
        // helper to sort table by month
        function MtoNum(months) {
            var month = months.match(/ [A-Z]{3}/i);
            if (month[0].toUpperCase() === ' JAN') {
                return Number(months.replace(month[0], '.01'));
            }
            if (month[0].toUpperCase() === ' FEB') {
                return Number(months.replace(month[0], '.02'));
            }
            if (month[0].toUpperCase() === ' MAR') {
                return Number(months.replace(month[0], '.03'));
            }
            if (month[0].toUpperCase() === ' APR') {
                return Number(months.replace(month[0], '.04'));
            }
            if (month[0].toUpperCase() === ' MAY') {
                return Number(months.replace(month[0], '.05'));
            }
            if (month[0].toUpperCase() === ' JUN') {
                return Number(months.replace(month[0], '.06'));
            }
            if (month[0].toUpperCase() === ' JUL') {
                return Number(months.replace(month[0], '.07'));
            }
            if (month[0].toUpperCase() === ' AUG') {
                return Number(months.replace(month[0], '.08'));
            }
            if (month[0].toUpperCase() === ' SEP') {
                return Number(months.replace(month[0], '.09'));
            }
            if (month[0].toUpperCase() === ' OCT') {
                return Number(months.replace(month[0], '.10'));
            }
            if (month[0].toUpperCase() === ' NOV') {
                return Number(months.replace(month[0], '.11'));
            }
            if (month[0].toUpperCase() === ' DEC') {
                return Number(months.replace(month[0], '.12'));
            }
        }

        // Creates an object for angular table control
        function makeTableObj(key, values, number) {
            var obj = [];
            var x = [];
            for (var i = 0; i < key.length; i++) {
                obj[0] = key[i];
                obj[1] = values[i];
                obj[2] = number[i];
                x.push({
                    "date": obj[0],
                    "values": obj[1],
                    "number": obj[2]
                });
            }
            return x;
        }

        $scope.changeChartRange = function changeChartRange() {
            var from = $scope.chartDataFrom;
            var to = $scope.chartDataTo;
            var w;
            var x;
            var y;
            var categoriesRange = [];
            var seriesRange = [];
            var sorterRange = [];
            for (var i = 0; i < currentCategories.length; i++) {
                w = currentSorter[i];
                x = currentCategories[i];
                y = currentSeries[i];
                if (from && to) {
                    if (w >= from && w <= to) {
                        categoriesRange.push(x);
                        seriesRange.push(y);
                        sorterRange.push(w);
                    }
                } else if (from) {
                    if (w >= from) {
                        categoriesRange.push(x);
                        seriesRange.push(y);
                        sorterRange.push(w);
                    }
                } else if (to) {
                    if (w <= to) {
                        categoriesRange.push(x);
                        seriesRange.push(y);
                        sorterRange.push(w);
                    }
                } else {
                    categoriesRange.push(x);
                    seriesRange.push(y);
                    sorterRange.push(w);
                }
            }
            $scope.graphValue = makeGraphValue(categoriesRange, seriesRange, sorterRange);
            $scope.chartData.options.xAxis.categories = $scope.graphValue[0];
            $scope.chartData.options.xAxis.tickInterval = tickInterval(categoriesRange.length);
            $scope.chartData.series[0].data = $scope.graphValue[1];
        };

        $scope.chartData = getData();
        // year by default
        $scope.chartData.options.xAxis.tickInterval = tickInterval(categoriesY.length);

        //If true shows graph, else table.
        $scope.chartTable = true;

        $scope.changeChartType = function(type) {
            if (type === "line") {
                $scope.chartTable = true;
            }
            if (type === "table") {
                $scope.chartTable = false;
            }
        };

        //year (0, by Default), quarter (1) or month (2)
        $scope.yqm = 0;
        $scope.changeTime = function(time) {
            if (time === 'year') {
                $scope.tableValue = makeTableObj(categoriesY, seriesDataY, categoriesYnum);
                $scope.graphValue = makeGraphValue(categoriesY, seriesDataY, categoriesYnum);
                $scope.yqm = 0;
                $scope.chartData.options.xAxis.categories = $scope.graphValue[0];
                $scope.chartData.options.xAxis.tickInterval = tickInterval(categoriesY.length);
                $scope.chartData.series[0].data = $scope.graphValue[1];
                currentCategories=categoriesY;
                currentSeries=seriesDataY;
                currentSorter = categoriesYnum;
            }
            if (time === 'quarter') {
                $scope.tableValue = makeTableObj(categoriesQ, seriesDataQ, categoriesQnum);
                $scope.graphValue = makeGraphValue(categoriesQ, seriesDataQ, categoriesQnum);
                $scope.yqm = 1;
                $scope.chartData.options.xAxis.categories = $scope.graphValue[0];
                $scope.chartData.options.xAxis.tickInterval = tickInterval(categoriesQ.length);
                $scope.chartData.series[0].data = $scope.graphValue[1];
                currentCategories=categoriesQ;
                currentSeries=seriesDataQ;
                currentSorter = categoriesQnum;
            }
            if (time === 'month') {
                $scope.tableValue = makeTableObj(categoriesM, seriesDataM, categoriesMnum);
                $scope.graphValue = makeGraphValue(categoriesM, seriesDataM, categoriesMnum);
                $scope.yqm = 2;
                $scope.chartData.options.xAxis.categories = $scope.graphValue[0];
                $scope.chartData.options.xAxis.tickInterval = tickInterval(categoriesM.length);
                $scope.chartData.series[0].data = $scope.graphValue[1];
                currentCategories=categoriesM;
                currentSeries=seriesDataM;
                currentSorter = categoriesMnum;
            }
        };

        //Defines the intervals in xAxis according to data
        function tickInterval(categories) {
            var tick;
            if (categories <= 20) {
                tick = 1;
            }
            if (categories > 20 && categories <= 80) {
                tick = 4;
            }
            if (categories > 80) {
                tick = 12;
            }
            if (categories > 240) {
                tick = 48;
            }
            if (categories > 480) {
                tick = 96;
            }
            if (categories > 960) {
                tick = 192;
            }
            return tick;
        }

        function getData() {
            var data = {
                options: {
                    chart: {
                        type: 'line',
                    },
                    colors: ['#007dc3', '#409ed2', '#7fbee1', '#007dc3', '#409ed2', '#7fbee1'],

                    title: {
                        text: ''
                    },
                    subtitle: {
                        text: ''
                    },
                    navigation: {
                        buttonOptions: {
                            enabled: false
                        //     verticalAlign: 'bottom',
                        //     y: 0,
                        //     text: 'Image',
                        //     theme: {
                        //         fill: '#0054aa',
                        //         r: 0,
                        //         states: {
                        //             hover: {
                        //                 fill: '#004790'
                        //             },
                        //             select: {
                        //                 fill: '#004790'
                        //             }
                                // }
                             // }
                        }
                    },
                    xAxis: {
                        categories: $scope.graphValue[0],
                        // tickInterval: 1,
                        labels: {
                            formatter: function() {
                                var w = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
                                var response = "";
                                if (w < 768) {
                                    if (this.isFirst) {
                                        count = 0;
                                    }
                                    if (count % 3 === 0) {
                                        response = this.value;
                                    }
                                    count++;
                                } else {
                                    response = this.value;
                                }
                                return response;
                            },
                        },
                        tickmarkPlacement: 'on'
                    },
                    yAxis: {
                        title: {
                            text: $scope.chart.units
                        }
                    },

                    credits: {
                        enabled: false
                    },

                    plotOptions: {
                        series: {
                            shadow: false,
                            states: {
                                hover: {
                                    enabled: true,
                                    shadow: false,
                                    lineWidth: 3,
                                    lineWidthPlus: 0,
                                    marker: {
                                        height: 0,
                                        width: 0,
                                        halo: false,
                                        enabled: true,
                                        fillColor: null,
                                        radiusPlus: null,
                                        lineWidth: 3,
                                        lineWidthPlus: 0
                                    }
                                }
                            }
                        }
                    },
                    tooltip: {
                        shared: true,
                        width: '150px',
                        crosshairs: {
                            width: 2,
                            color: '#f37121'
                        },
                        positioner: function(labelWidth, labelHeight, point) {
                            var w = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
                            var points = {
                                x: 30,
                                y: 42
                            };
                            var tooltipX, tooltipY;
                            var chart = Highcharts.charts[Highcharts.charts.length - 1];
                            if (w > 768) {

                                if (point.plotX + labelWidth > chart.plotWidth) {
                                    tooltipX = point.plotX + chart.plotLeft - labelWidth - 20;
                                    $("#custom-tooltip").removeClass('tooltip-left');
                                } else {
                                    tooltipX = point.plotX + chart.plotLeft + 20;
                                    $("#custom-tooltip").removeClass('tooltip-right');
                                }

                                tooltipY = 50;
                                points = {
                                    x: tooltipX,
                                    y: tooltipY
                                };
                            } else {
                                $("#custom-tooltip").removeClass('tooltip-left');
                                $("#custom-tooltip").removeClass('tooltip-right');
                            }

                            return points;
                        },

                        formatter: function() {
                            var id = '
';
                            var block = id + "
";
                            var title = '' + this.x + ':
';
                            var symbol = ['
●
', '
■
', '
♦
', '
▲
', '
▼
'];

                            var content = block + "

";

                            // symbols
                            $.each(this.points, function(i, val) {
                                content += symbol[i];
                            });

                            content += "
";
                            content += "
";
                            content += title;

                            // series names and values
                            $.each(this.points, function(i, val) {
                                content += '
' + val.point.series.chart.series[i].name + "
Value: " + Highcharts.numberFormat(val.y, 2) + '
';
                            });
                            content += "
";
                            return content;
                        },

                        backgroundColor: 'rgba(255, 255, 255, 0)',
                        borderWidth: 0,
                        borderColor: 'rgba(255, 255, 255, 0)',
                        shadow: false,
                        useHTML: true

                    }
                },

                series: [{
                    name: $scope.chart.name,
                    data: $scope.graphValue[1],
                    marker: {
                        symbol: "circle",
                        states: {
                            hover: {
                                fillColor: '#007dc3',
                                radiusPlus: 0,
                                lineWidthPlus: 0
                            }
                        }
                    },
                    dashStyle: 'Solid',
                }]
            };
            return data;
        }
            // the button handler
            $('#imgExp').click(function() {
                var chartExp = $('#chart_prices').highcharts();
                chartExp.exportChart();
            });
    }
]);
<|endoftext|>


<commit_before>function autocompleteCallback() {
    var name = this.attr('name');
    var select = this.parent().parent().find('select[name ^= field]');
    if (select) {
        return select.val();
    } else
        return 'noparam';
}

function repeatCallback() {
    var input = $('input[name ^= input]', this);
    input.autocomplete("autocomplete.xql", {
        extraParams: { field: function () { return autocompleteCallback.call(input);} },
        width: 300,
        multiple: false,
        matchContains: false
    });
}

function resultsLoaded(options) {
    if (options.itemsPerPage > 1)
        $('tbody > tr:even > td', this).addClass('even');
    $('#filters').css('display', 'block');
    $('#filters .include-target').empty();
    $('#filters .expand').removeClass('expanded');
    $('.actions .save', this).click(function (ev) {
        var img = $('img', this);
        var pos = this.hash.substring(1);
        if (img.hasClass('stored')) {
            var id = this.id;
            img.removeClass('stored');
            img.attr('src', 'disk.gif');
            $.get('user.xql', { list: 'remove', id: id });
        } else {
            img.attr('src', 'disk_gew.gif');
            img.addClass('stored');
            $.get('user.xql', { list: 'add', pos: pos });
        }
        $('#personal-list-size').load('user.xql', { action: 'count' });
    });
}

function searchTabSelected(ev, ui) {
    if (ui.index == 3) {
        $('#personal-list-size').load('user.xql', { action: 'count' });
    }
}<commit_msg>[ignore] new biblio demo: boolean operator was invisible<commit_after>function autocompleteCallback() {
    var name = this.attr('name');
    var select = this.parent().parent().find('select[name ^= field]');
    if (select) {
        return select.val();
    } else
        return 'noparam';
}

function repeatCallback() {
    var input = $('input[name ^= input]', this);
    input.autocomplete("autocomplete.xql", {
        extraParams: { field: function () { return autocompleteCallback.call(input);} },
        width: 300,
        multiple: false,
        matchContains: false
    });
    $('select[name ^= operator]', this).each(function () {
        $(this).css('display', '');
    });
}

function resultsLoaded(options) {
    if (options.itemsPerPage > 1)
        $('tbody > tr:even > td', this).addClass('even');
    $('#filters').css('display', 'block');
    $('#filters .include-target').empty();
    $('#filters .expand').removeClass('expanded');
    $('.actions .save', this).click(function (ev) {
        var img = $('img', this);
        var pos = this.hash.substring(1);
        if (img.hasClass('stored')) {
            var id = this.id;
            img.removeClass('stored');
            img.attr('src', 'disk.gif');
            $.get('user.xql', { list: 'remove', id: id });
        } else {
            img.attr('src', 'disk_gew.gif');
            img.addClass('stored');
            $.get('user.xql', { list: 'add', pos: pos });
        }
        $('#personal-list-size').load('user.xql', { action: 'count' });
    });
}

function searchTabSelected(ev, ui) {
    if (ui.index == 3) {
        $('#personal-list-size').load('user.xql', { action: 'count' });
    }
}<|endoftext|>


<commit_before>/**
 * Editor screen for uploading visualisations
 * @param collectionId
 * @param data
 */

function visualisationEditor(collectionId, data, collectionData) {
    var path = data.uri,
        $indexSelect = $('#filenames'),
        setActiveTab, getActiveTab;

    // Active tab
    $(".edit-accordion").on('accordionactivate', function () {
        setActiveTab = $(".edit-accordion").accordion("option", "active");
        if (setActiveTab !== false) {
            Florence.globalVars.activeTab = setActiveTab;
        }
    });
    getActiveTab = Florence.globalVars.activeTab;
    accordion(getActiveTab);
    getLastPosition();

    // Refresh preview with new URL if index page previously selected (can't use refreshPreview function because it removes "/" from end or path by default)
    function refreshVisPreview(url) {
        var newUrl;
        if (url) {
            newUrl = Florence.babbageBaseUrl + path  + "/" + url;
            // Florence.globalVars.pagePath = path;
        } else {
            newUrl = Florence.babbageBaseUrl + path + "/";
        }
        document.getElementById('iframe').contentWindow.location.href = newUrl;
        $('.browser-location').val(newUrl);
    }

    // Submit new ZIP file
    bindZipSubmit();

    // Edit existing ZIP file
    $('#edit-vis').on('submit', function (e) {
        e.preventDefault();
        e.stopImmediatePropagation();

        // Refresh visualisations tab but show 'submit ZIP' option
        var tempData = data;
        tempData.zipTitle = "";
        var html = templates.workEditVisualisation(tempData);
        $('.workspace-menu').html(html);
        bindZipSubmit();

        // Set visualisation tab to active
        accordion(1);
    });

    // Listen to change of index page input and refresh preview to show new index page
    $indexSelect.change(function () {
        refreshVisPreview($indexSelect.val());
    });

    // Bind save buttons
    var editNav = $('.edit-nav');
    editNav.off(); // remove any existing event handlers.

    editNav.on('click', '.btn-edit-save', function () {
        var indexPage = $('#filenames').val();
        data['indexPage'] = indexPage;

        save();
    });

    editNav.on('click', '.btn-edit-save-and-submit-for-review', function () {
        saveAndCompleteContent(collectionId, data.uri, JSON.stringify(data), true);
    });

    editNav.on('click', '.btn-edit-save-and-submit-for-approval', function () {
        saveAndReviewContent(collectionId, data.uri, JSON.stringify(data), true);
    });

    /* FUNCTIONS */
    function bindZipSubmit() {
        // Upload ZIP file
        $('#upload-vis').on('submit', function (e) {
            e.preventDefault();
            e.stopImmediatePropagation();

            var formdata = new FormData($(this)[0]),
                file = this[0].files[0];

            if (!$('#input-vis')) {
                sweetAlert("Please choose a file before submitting");
                return false;
            }

            if (!file.name.match(/\.zip$/)) {
                sweetAlert("Incorrect file format", "You are only allowed to upload ZIP files", "warning")
            } else {
                var fileNameNoSpace = file.name.replace(/[^a-zA-Z0-9\.]/g, "").toLowerCase();
                var uniqueIdNoSpace = data.uid.replace(/[^a-zA-Z0-9\.]/g, "").toLowerCase();
                var contentUri = "/visualisations/" + uniqueIdNoSpace + "/content";
                var uriUpload = contentUri + "/" + fileNameNoSpace;
                var safeUriUpload = checkPathSlashes(uriUpload);

                path = "/visualisations/" + uniqueIdNoSpace + "/";

                deleteAndUploadFile(
                    safeUriUpload, contentUri, formdata,
                    success = function () {
                        unpackZip(safeUriUpload,
                            success = function () {

                                // On unpack of Zip refresh the reload editor and preview
                                loadPageDataIntoEditor(path, collectionId);
                            }
                        );
                    }
                )
            }

        });
    }

    function deleteAndUploadFile(path, contentUri, formData, success) {
        $.ajax({
            url: "/zebedee/DataVisualisationZip/" + Florence.collection.id + "?zipPath=" + contentUri,
            type: 'DELETE',
            async: false,
            cache: false,
            contentType: false,
            processData: false,
            success: function (response) {
                uploadFile(path, formData, success);
            },
            error: function (response) {
                handleApiError(response);
            }
        });
    }

    function uploadFile(path, formData, success) {
        // Send zip file to zebedee
        $.ajax({
            url: "/zebedee/content/" + Florence.collection.id + "?uri=" + path,
            type: 'POST',
            data: formData,
            async: false,
            cache: false,
            contentType: false,
            processData: false,
            success: function (response) {
                success(response);
            },
            error: function (response) {
                handleApiError(response);
            }
        });
    }

    function unpackZip(zipPath, success, error) {
        // Unpack contents of ZIP
        console.log("Unpack: " + zipPath);
        var url = "/zebedee/DataVisualisationZip/" + Florence.collection.id + "?zipPath=" + zipPath;

        $.ajax({
            url: url,
            contentType: 'application/json',
            type: 'POST',
            success: function (response) {
                success(response);
            },
            error: function (response) {
                if (error) {
                    error(response);
                } else {
                    handleApiError(response);
                }
            }
        });
    }

    function save() {
        putContent(collectionId, data.uri, JSON.stringify(data),
            success = function () {
                Florence.Editor.isDirty = false;
                refreshVisPreview();
                loadPageDataIntoEditor(data.uri, collectionId);
            },
            error = function (response) {
                if (response.status === 409) {
                    sweetAlert("Cannot edit this page", "It is already part of another collection.");
                } else {
                    handleApiError(response);
                }
            },
            true
        );
    }
}
<commit_msg>Use path without trailing slash when reloading after index page change<commit_after>/**
 * Editor screen for uploading visualisations
 * @param collectionId
 * @param data
 */

function visualisationEditor(collectionId, data) {
    var path = data.uri,
        $indexSelect = $('#filenames'),
        setActiveTab, getActiveTab;

    // Active tab
    $(".edit-accordion").on('accordionactivate', function () {
        setActiveTab = $(".edit-accordion").accordion("option", "active");
        if (setActiveTab !== false) {
            Florence.globalVars.activeTab = setActiveTab;
        }
    });
    getActiveTab = Florence.globalVars.activeTab;
    accordion(getActiveTab);
    getLastPosition();

    // Refresh preview with new URL if index page previously selected (can't use refreshPreview function because it removes "/" from end or path by default)
    function refreshVisPreview(url) {
        var newUrl;
        if (url) {
            newUrl = Florence.babbageBaseUrl + path  + "/" + url;
            // Florence.globalVars.pagePath = path;
        } else {
            newUrl = Florence.babbageBaseUrl + path + "/";
        }
        document.getElementById('iframe').contentWindow.location.href = newUrl;
        $('.browser-location').val(newUrl);
    }

    // Submit new ZIP file
    bindZipSubmit();

    // Edit existing ZIP file
    $('#edit-vis').on('submit', function (e) {
        e.preventDefault();
        e.stopImmediatePropagation();

        // Refresh visualisations tab but show 'submit ZIP' option
        var tempData = data;
        tempData.zipTitle = "";
        var html = templates.workEditVisualisation(tempData);
        $('.workspace-menu').html(html);
        bindZipSubmit();

        // Set visualisation tab to active
        accordion(1);
    });

    // Listen to change of index page input and refresh preview to show new index page
    $indexSelect.change(function () {
        refreshVisPreview($indexSelect.val());
    });

    // Bind save buttons
    var editNav = $('.edit-nav');
    editNav.off(); // remove any existing event handlers.

    editNav.on('click', '.btn-edit-save', function () {
        var indexPage = $('#filenames').val();
        data['indexPage'] = indexPage;

        save();
    });

    editNav.on('click', '.btn-edit-save-and-submit-for-review', function () {
        saveAndCompleteContent(collectionId, data.uri, JSON.stringify(data), true);
    });

    editNav.on('click', '.btn-edit-save-and-submit-for-approval', function () {
        saveAndReviewContent(collectionId, data.uri, JSON.stringify(data), true);
    });

    /* FUNCTIONS */
    function bindZipSubmit() {
        // Upload ZIP file
        $('#upload-vis').on('submit', function (e) {
            e.preventDefault();
            e.stopImmediatePropagation();

            var formdata = new FormData($(this)[0]),
                file = this[0].files[0];

            if (!$('#input-vis')) {
                sweetAlert("Please choose a file before submitting");
                return false;
            }

            if (!file.name.match(/\.zip$/)) {
                sweetAlert("Incorrect file format", "You are only allowed to upload ZIP files", "warning")
            } else {
                var fileNameNoSpace = file.name.replace(/[^a-zA-Z0-9\.]/g, "").toLowerCase();
                var uniqueIdNoSpace = data.uid.replace(/[^a-zA-Z0-9\.]/g, "").toLowerCase();
                var contentUri = "/visualisations/" + uniqueIdNoSpace + "/content";
                var uriUpload = contentUri + "/" + fileNameNoSpace;
                var safeUriUpload = checkPathSlashes(uriUpload);

                path = "/visualisations/" + uniqueIdNoSpace;

                deleteAndUploadFile(
                    safeUriUpload, contentUri, formdata,
                    success = function () {
                        unpackZip(safeUriUpload,
                            success = function () {

                                // On unpack of Zip refresh the reload editor and preview
                                loadPageDataIntoEditor(path, collectionId);
                            }
                        );
                    }
                )
            }

        });
    }

    function deleteAndUploadFile(path, contentUri, formData, success) {
        $.ajax({
            url: "/zebedee/DataVisualisationZip/" + Florence.collection.id + "?zipPath=" + contentUri,
            type: 'DELETE',
            async: false,
            cache: false,
            contentType: false,
            processData: false,
            success: function (response) {
                uploadFile(path, formData, success);
            },
            error: function (response) {
                handleApiError(response);
            }
        });
    }

    function uploadFile(path, formData, success) {
        // Send zip file to zebedee
        $.ajax({
            url: "/zebedee/content/" + Florence.collection.id + "?uri=" + path,
            type: 'POST',
            data: formData,
            async: false,
            cache: false,
            contentType: false,
            processData: false,
            success: function (response) {
                success(response);
            },
            error: function (response) {
                handleApiError(response);
            }
        });
    }

    function unpackZip(zipPath, success, error) {
        // Unpack contents of ZIP
        console.log("Unpack: " + zipPath);
        var url = "/zebedee/DataVisualisationZip/" + Florence.collection.id + "?zipPath=" + zipPath;

        $.ajax({
            url: url,
            contentType: 'application/json',
            type: 'POST',
            success: function (response) {
                success(response);
            },
            error: function (response) {
                if (error) {
                    error(response);
                } else {
                    handleApiError(response);
                }
            }
        });
    }

    function save() {
        putContent(collectionId, data.uri, JSON.stringify(data),
            success = function () {
                Florence.Editor.isDirty = false;
                refreshVisPreview();
                loadPageDataIntoEditor(data.uri, collectionId);
            },
            error = function (response) {
                if (response.status === 409) {
                    sweetAlert("Cannot edit this page", "It is already part of another collection.");
                } else {
                    handleApiError(response);
                }
            },
            true
        );
    }
}
<|endoftext|>


<commit_before>import axios from "axios";
import { setBaseUrl } from "../../utilities/url-utilities";

const BASE_URL = setBaseUrl(`ajax/remote_api`);

/**
 * Check the status of a specific Remote API.
 * @param {number} id - identifier for the API.
 * @returns {Promise<boolean>}
 */
export function checkConnectionStatus({ id }) {
  return axios
    .get(`${BASE_URL}/status/${id}`)
    .then(({ data }) => data)
    .catch(() => false);
}

/**
 * Get the specific details about a remote api connection
 * @param id - identifier for a remote api
 * @returns {Promise<*>}
 */
export function getConnectionDetails({ id }) {
  return axios.get(`${BASE_URL}/${id}`).then(({ data }) => data);
}

/**
 * Delete a specific remote api
 * @param id - identifier for a remote api
 * @returns {Promise<AxiosResponse<any>>}
 */
export function deleteRemoteApi({ id }) {
  return axios.delete(`${BASE_URL}/${id}/delete`);
}

export function getListOfRemoteApis() {
  return axios.get(`${BASE_URL}/apis`).then(({ data }) => data);
}

export function getProjectsForAPI({ id }) {
  return axios.get(`${BASE_URL}/${id}/projects`).then(({ data }) => data);
}

export function createSynchronizedProject({ url, frequency }) {
  return axios
    .post(`${BASE_URL}/project`, { url, frequency })
    .then(({ data }) => data);
}
<commit_msg>:bulb: Added JSDoc<commit_after>import axios from "axios";
import { setBaseUrl } from "../../utilities/url-utilities";

const BASE_URL = setBaseUrl(`ajax/remote_api`);

/**
 * Check the status of a specific Remote API.
 * @param {number} id - identifier for the API.
 * @returns {Promise<boolean>}
 */
export function checkConnectionStatus({ id }) {
  return axios
    .get(`${BASE_URL}/status/${id}`)
    .then(({ data }) => data)
    .catch(() => false);
}

/**
 * Get the specific details about a remote api connection
 * @param id - identifier for a remote api
 * @returns {Promise<*>}
 */
export function getConnectionDetails({ id }) {
  return axios.get(`${BASE_URL}/${id}`).then(({ data }) => data);
}

/**
 * Delete a specific remote api
 * @param id - identifier for a remote api
 * @returns {Promise<AxiosResponse<any>>}
 */
export function deleteRemoteApi({ id }) {
  return axios.delete(`${BASE_URL}/${id}/delete`);
}

/**
 * Get a list of all remote APIs
 * @returns {Promise<*>}
 */
export function getListOfRemoteApis() {
  return axios.get(`${BASE_URL}/apis`).then(({ data }) => data);
}

/**
 * Get a list of projects for a Remote API
 * @param id - Remote API identifier
 * @returns {Promise<*>}
 */
export function getProjectsForAPI({ id }) {
  return axios.get(`${BASE_URL}/${id}/projects`).then(({ data }) => data);
}

/**
 * Create a new Synchronized Project
 * @param url
 * @param frequency
 * @returns {Promise<*>}
 */
export function createSynchronizedProject({ url, frequency }) {
  return axios
    .post(`${BASE_URL}/project`, { url, frequency })
    .then(({ data }) => data);
}
<|endoftext|>


<commit_before>/* Copyright 2017 Streampunk Media Ltd.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
*/

var dgram = require('dgram');
var argv = require('yargs')
  .default('p', 6789)
  .default('a', '234.5.6.7')
  .number('p')
  .usage('Join a multicast group. Useful for wireshark testing.\n' +
    'Usage: $0 ')
  .help()
  .describe('a', 'Address of multicast group to join.')
  .describe('p', 'Port of multicast group to join.')
  .describe('i', 'Multicast interface.')
  .argv;

var socket = dgram.createSocket('udp4');

socket.addMembership(argv.a, argv.i);

socket.on('listening', () => {
  console.log('Multicast group subscribed and listening.');
});

socket.on('error', console.error);

socket.bind(argv.p);
<commit_msg>Comments to suggest how to see Node.JS causing UDP packets drops.<commit_after>/* Copyright 2017 Streampunk Media Ltd.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
*/

var dgram = require('dgram');
var argv = require('yargs')
  .default('p', 6789)
  .default('a', '234.5.6.7')
  .number('p')
  .usage('Join a multicast group. Useful for wireshark testing.\n' +
    'Usage: $0 ')
  .help()
  .describe('a', 'Address of multicast group to join.')
  .describe('p', 'Port of multicast group to join.')
  .describe('i', 'Multicast interface.')
  .argv;

var socket = dgram.createSocket('udp4');

// Uncomment this line to see the effect of joining the group prior to the bind
// socket.addMembership(argv.a, argv.i);

socket.on('listening', () => {
  // Comment this line to see the effect of joining the group prior to the bind
  socket.addMembership(argv.a, argv.i);
  console.log('Multicast group subscribed and listening.');
});

socket.on('error', console.error);

socket.bind(argv.p);
<|endoftext|>