]> source.dussan.org Git - sonarqube.git/commitdiff
SONARCLOUD-63 Update help dropdown with product news
authorGrégoire Aubert <gregoire.aubert@sonarsource.com>
Tue, 12 Jun 2018 12:58:03 +0000 (14:58 +0200)
committerSonarTech <sonartech@sonarsource.com>
Thu, 21 Jun 2018 18:21:28 +0000 (20:21 +0200)
14 files changed:
server/sonar-web/src/main/js/api/news.ts [new file with mode: 0644]
server/sonar-web/src/main/js/app/components/embed-docs-modal/EmbedDocsPopup.tsx
server/sonar-web/src/main/js/app/components/embed-docs-modal/EmbedDocsPopupHelper.tsx
server/sonar-web/src/main/js/app/components/embed-docs-modal/ProductNewsMenuItem.tsx [new file with mode: 0644]
server/sonar-web/src/main/js/app/components/embed-docs-modal/__tests__/EmbedDocsPopup-test.tsx
server/sonar-web/src/main/js/app/components/embed-docs-modal/__tests__/ProductNewsMenuItem-test.tsx [new file with mode: 0644]
server/sonar-web/src/main/js/app/components/embed-docs-modal/__tests__/__snapshots__/EmbedDocsPopup-test.tsx.snap
server/sonar-web/src/main/js/app/components/embed-docs-modal/__tests__/__snapshots__/ProductNewsMenuItem-test.tsx.snap [new file with mode: 0644]
server/sonar-web/src/main/js/app/styles/components/menu.css
server/sonar-web/src/main/js/app/styles/init/misc.css
server/sonar-web/src/main/js/components/ui/PlaceholderBar.css [new file with mode: 0644]
server/sonar-web/src/main/js/components/ui/PlaceholderBar.tsx [new file with mode: 0644]
server/sonar-web/src/main/js/helpers/request.ts
sonar-core/src/main/resources/org/sonar/l10n/core.properties

diff --git a/server/sonar-web/src/main/js/api/news.ts b/server/sonar-web/src/main/js/api/news.ts
new file mode 100644 (file)
index 0000000..a262a9e
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+/* eslint-disable camelcase */
+import { getCorsJSON } from '../helpers/request';
+
+interface PrismicRef {
+  id: string;
+  ref: string;
+}
+
+export interface PrismicNews {
+  data: { title: string };
+  last_publication_date: string;
+  uid: string;
+}
+
+const PRISMIC_API_URL = 'https://sonarsource.cdn.prismic.io/api/v2';
+
+export function fetchPrismicRefs() {
+  return getCorsJSON(PRISMIC_API_URL).then((response: { refs: Array<PrismicRef> }) => {
+    const master = response && response.refs.find(ref => ref.id === 'master');
+    if (!master) {
+      return Promise.reject('No master ref found');
+    }
+    return Promise.resolve(master);
+  });
+}
+
+export function fetchPrismicNews(data: {
+  accessToken: string;
+  ps?: number;
+  ref: string;
+  tag?: string;
+}) {
+  const q = ['[[at(document.type, "blog_sonarsource_post")]]'];
+  if (data.tag) {
+    q.push(`[[at(document.tags,["${data.tag}"])]]`);
+  }
+  return getCorsJSON(PRISMIC_API_URL + '/documents/search', {
+    access_token: data.accessToken,
+    orderings: '[document.first_publication_date desc]',
+    pageSize: data.ps || 1,
+    q,
+    ref: data.ref
+  }).then(({ results }: { results: Array<PrismicNews> }) => results);
+}
index da65d03892efd208ad563025d69f18c1a73f9bf1..cbaea65d18cefa2bc08aea060d8ebcedb56e0721 100644 (file)
 import * as React from 'react';
 import * as PropTypes from 'prop-types';
 import { Link } from 'react-router';
+import ProductNewsMenuItem from './ProductNewsMenuItem';
 import { SuggestionLink } from './SuggestionsProvider';
 import { CurrentUser, isLoggedIn } from '../../types';
 import { translate } from '../../../helpers/l10n';
 import { getBaseUrl } from '../../../helpers/urls';
-import { DropdownOverlay } from '../../../components/controls/Dropdown';
 import { isSonarCloud } from '../../../helpers/system';
+import { DropdownOverlay } from '../../../components/controls/Dropdown';
 
 interface Props {
   currentUser: CurrentUser;
@@ -87,17 +88,27 @@ export default class EmbedDocsPopup extends React.PureComponent<Props> {
       <React.Fragment>
         <li className="divider" />
         <li>
-          <a href="https://community.sonarsource.com/" rel="noopener noreferrer" target="_blank">
+          <a
+            href="https://community.sonarsource.com/c/help/sc"
+            rel="noopener noreferrer"
+            target="_blank">
             {translate('embed_docs.get_help')}
           </a>
         </li>
         <li className="divider" />
         {this.renderTitle(translate('embed_docs.stay_connected'))}
         <li>
-          {this.renderIconLink('https://about.sonarcloud.io/news/', 'sc-icon.svg', 'Product News')}
+          {this.renderIconLink('https://twitter.com/sonarcloud', 'twitter-icon.svg', 'Twitter')}
         </li>
         <li>
-          {this.renderIconLink('https://twitter.com/sonarcloud', 'twitter-icon.svg', 'Twitter')}
+          {this.renderIconLink(
+            'https://blog.sonarsource.com/product/SonarCloud',
+            'sc-icon.svg',
+            translate('embed_docs.news')
+          )}
+        </li>
+        <li>
+          <ProductNewsMenuItem tag="SonarCloud" />
         </li>
       </React.Fragment>
     );
@@ -125,7 +136,7 @@ export default class EmbedDocsPopup extends React.PureComponent<Props> {
           {this.renderIconLink(
             'https://www.sonarsource.com/resources/product-news/',
             'sq-icon.svg',
-            'Product News'
+            translate('embed_docs.news')
           )}
         </li>
         <li>
index c2ad6cf19c5b6d60dc4be9e530ee41776bfeecdc..06b7bc02b0217eaee6815b75f8364b787b0d3b66 100644 (file)
@@ -34,6 +34,7 @@ interface State {
 }
 
 export default class EmbedDocsPopupHelper extends React.PureComponent<Props, State> {
+  mounted = false;
   state: State = { helpOpen: false };
 
   componentDidMount() {
diff --git a/server/sonar-web/src/main/js/app/components/embed-docs-modal/ProductNewsMenuItem.tsx b/server/sonar-web/src/main/js/app/components/embed-docs-modal/ProductNewsMenuItem.tsx
new file mode 100644 (file)
index 0000000..e87e82b
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+import * as React from 'react';
+import { connect } from 'react-redux';
+import { fetchPrismicRefs, fetchPrismicNews, PrismicNews } from '../../../api/news';
+import { getGlobalSettingValue } from '../../../store/rootReducer';
+import DateFormatter from '../../../components/intl/DateFormatter';
+import ChevronRightIcon from '../../../components/icons-components/ChevronRightcon';
+import PlaceholderBar from '../../../components/ui/PlaceholderBar';
+
+interface OwnProps {
+  tag?: string;
+}
+
+interface StateProps {
+  accessToken?: string;
+}
+
+type Props = OwnProps & StateProps;
+
+interface State {
+  loading: boolean;
+  news?: PrismicNews;
+}
+
+export class ProductNewsMenuItem extends React.PureComponent<Props, State> {
+  mounted = false;
+  state: State = { loading: false };
+
+  componentDidMount() {
+    this.mounted = true;
+    this.fetchProductNews();
+  }
+
+  componentWillUnmount() {
+    this.mounted = false;
+  }
+
+  fetchProductNews = () => {
+    const { accessToken, tag } = this.props;
+    if (accessToken) {
+      this.setState({ loading: true });
+      fetchPrismicRefs()
+        .then(({ ref }) => fetchPrismicNews({ accessToken, ref, tag }))
+        .then(
+          news => {
+            if (this.mounted) {
+              this.setState({ news: news[0], loading: false });
+            }
+          },
+          () => {
+            if (this.mounted) {
+              this.setState({ loading: false });
+            }
+          }
+        );
+    }
+  };
+
+  renderPlaceholder() {
+    return (
+      <a className="rich-item new-loading">
+        <div className="flex-1">
+          <div className="display-inline-flex-center">
+            <h4>Latest news</h4>
+            <span className="note spacer-left">
+              <PlaceholderBar color="#aaa" width={60} />
+            </span>
+          </div>
+          <p className="little-spacer-bottom">
+            <PlaceholderBar color="#aaa" width={84} /> <PlaceholderBar color="#aaa" width={48} />{' '}
+            <PlaceholderBar color="#aaa" width={24} /> <PlaceholderBar color="#aaa" width={72} />{' '}
+            <PlaceholderBar color="#aaa" width={24} /> <PlaceholderBar color="#aaa" width={48} />
+          </p>
+        </div>
+        <ChevronRightIcon className="flex-0" />
+      </a>
+    );
+  }
+
+  render() {
+    const link = 'https://blog.sonarsource.com/';
+    const { loading, news } = this.state;
+
+    if (loading) {
+      return this.renderPlaceholder();
+    }
+
+    if (!news) {
+      return null;
+    }
+
+    return (
+      <a className="rich-item" href={link + news.uid} rel="noopener noreferrer" target="_blank">
+        <div className="flex-1">
+          <div className="display-inline-flex-center">
+            <h4>Latest news</h4>
+            <DateFormatter date={news.last_publication_date}>
+              {formattedDate => <span className="note spacer-left">{formattedDate}</span>}
+            </DateFormatter>
+          </div>
+          <p className="little-spacer-bottom">{news.data.title}</p>
+        </div>
+        <ChevronRightIcon className="flex-0" />
+      </a>
+    );
+  }
+}
+
+const mapStateToProps = (state: any): StateProps => ({
+  accessToken: (getGlobalSettingValue(state, 'sonar.prismic.accessToken') || {}).value
+});
+
+export default connect<StateProps, {}, OwnProps>(mapStateToProps)(ProductNewsMenuItem);
index 48bb8a0799a7f7a94063ab88ab7d97b792cc028b..9423f9979fa9b2dd8319fa84d2834268a6784bc5 100644 (file)
  */
 import * as React from 'react';
 import { shallow } from 'enzyme';
-import EmbedDocsPopups from '../EmbedDocsPopup';
+import EmbedDocsPopup from '../EmbedDocsPopup';
+import { isSonarCloud } from '../../../../helpers/system';
+
+jest.mock('../../../../helpers/system', () => ({ isSonarCloud: jest.fn().mockReturnValue(false) }));
 
 const suggestions = [{ link: '#', text: 'foo' }, { link: '#', text: 'bar' }];
 
 it('should display suggestion links', () => {
   const context = {};
   const wrapper = shallow(
-    <EmbedDocsPopups
+    <EmbedDocsPopup
+      currentUser={{ isLoggedIn: true }}
+      onClose={jest.fn()}
+      suggestions={suggestions}
+    />,
+    {
+      context
+    }
+  );
+  wrapper.update();
+  expect(wrapper).toMatchSnapshot();
+});
+
+it('should display correct links for SonarCloud', () => {
+  (isSonarCloud as jest.Mock<any>).mockReturnValueOnce(true);
+  const context = {};
+  const wrapper = shallow(
+    <EmbedDocsPopup
       currentUser={{ isLoggedIn: true }}
       onClose={jest.fn()}
       suggestions={suggestions}
diff --git a/server/sonar-web/src/main/js/app/components/embed-docs-modal/__tests__/ProductNewsMenuItem-test.tsx b/server/sonar-web/src/main/js/app/components/embed-docs-modal/__tests__/ProductNewsMenuItem-test.tsx
new file mode 100644 (file)
index 0000000..ba0ca53
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+import * as React from 'react';
+import { shallow } from 'enzyme';
+import { ProductNewsMenuItem } from '../ProductNewsMenuItem';
+import { fetchPrismicRefs, fetchPrismicNews } from '../../../../api/news';
+import { waitAndUpdate } from '../../../../helpers/testUtils';
+
+jest.mock('../../../../api/news', () => ({
+  fetchPrismicRefs: jest.fn().mockResolvedValue({ id: 'master', ref: 'master-ref' }),
+  fetchPrismicNews: jest.fn().mockResolvedValue([
+    {
+      data: { title: 'My Product News' },
+      last_publication_date: '2018-04-06T12:07:19+0000',
+      uid: 'my-product-news'
+    }
+  ])
+}));
+
+it('should load the product news', async () => {
+  const wrapper = shallow(<ProductNewsMenuItem accessToken="token" tag="SonarCloud" />);
+  expect(wrapper).toMatchSnapshot();
+  await waitAndUpdate(wrapper);
+  expect(fetchPrismicRefs).toHaveBeenCalled();
+  expect(fetchPrismicNews).toHaveBeenCalledWith({
+    accessToken: 'token',
+    ref: 'master-ref',
+    tag: 'SonarCloud'
+  });
+  expect(wrapper).toMatchSnapshot();
+});
index 05de0c054600bfbece5c1d3d2b3ef63748c0a1c5..3fc1cca678d4e597ddbef9e2fe8d84a400e6860b 100644 (file)
@@ -1,5 +1,127 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
+exports[`should display correct links for SonarCloud 1`] = `
+<DropdownOverlay>
+  <ul
+    className="menu abs-width-240"
+  >
+    <React.Fragment>
+      <li
+        className="menu-header"
+      >
+        embed_docs.suggestion
+      </li>
+      <li
+        key="0"
+      >
+        <Link
+          onClick={[MockFunction]}
+          onlyActiveOnIndex={false}
+          style={Object {}}
+          to="#"
+        >
+          foo
+        </Link>
+      </li>
+      <li
+        key="1"
+      >
+        <Link
+          onClick={[MockFunction]}
+          onlyActiveOnIndex={false}
+          style={Object {}}
+          to="#"
+        >
+          bar
+        </Link>
+      </li>
+      <li
+        className="divider"
+      />
+    </React.Fragment>
+    <li>
+      <Link
+        onClick={[MockFunction]}
+        onlyActiveOnIndex={false}
+        style={Object {}}
+        to="/documentation"
+      >
+        embed_docs.documentation
+      </Link>
+    </li>
+    <li>
+      <Link
+        onClick={[MockFunction]}
+        onlyActiveOnIndex={false}
+        style={Object {}}
+        to="/web_api"
+      >
+        api_documentation.page
+      </Link>
+    </li>
+    <React.Fragment>
+      <li
+        className="divider"
+      />
+      <li>
+        <a
+          href="https://community.sonarsource.com/c/help/sc"
+          rel="noopener noreferrer"
+          target="_blank"
+        >
+          embed_docs.get_help
+        </a>
+      </li>
+      <li
+        className="divider"
+      />
+      <li
+        className="menu-header"
+      >
+        embed_docs.stay_connected
+      </li>
+      <li>
+        <a
+          href="https://twitter.com/sonarcloud"
+          rel="noopener noreferrer"
+          target="_blank"
+        >
+          <img
+            alt="Twitter"
+            className="spacer-right"
+            height="18"
+            src="/images/embed-doc/twitter-icon.svg"
+            width="18"
+          />
+          Twitter
+        </a>
+      </li>
+      <li>
+        <a
+          href="https://blog.sonarsource.com/product/SonarCloud"
+          rel="noopener noreferrer"
+          target="_blank"
+        >
+          <img
+            alt="embed_docs.news"
+            className="spacer-right"
+            height="18"
+            src="/images/embed-doc/sc-icon.svg"
+            width="18"
+          />
+          embed_docs.news
+        </a>
+      </li>
+      <li>
+        <Connect(ProductNewsMenuItem)
+          tag="SonarCloud"
+        />
+      </li>
+    </React.Fragment>
+  </ul>
+</DropdownOverlay>
+`;
+
 exports[`should display suggestion links 1`] = `
 <DropdownOverlay>
   <ul
@@ -95,13 +217,13 @@ exports[`should display suggestion links 1`] = `
           target="_blank"
         >
           <img
-            alt="Product News"
+            alt="embed_docs.news"
             className="spacer-right"
             height="18"
             src="/images/embed-doc/sq-icon.svg"
             width="18"
           />
-          Product News
+          embed_docs.news
         </a>
       </li>
       <li>
diff --git a/server/sonar-web/src/main/js/app/components/embed-docs-modal/__tests__/__snapshots__/ProductNewsMenuItem-test.tsx.snap b/server/sonar-web/src/main/js/app/components/embed-docs-modal/__tests__/__snapshots__/ProductNewsMenuItem-test.tsx.snap
new file mode 100644 (file)
index 0000000..365de2d
--- /dev/null
@@ -0,0 +1,95 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should load the product news 1`] = `
+<a
+  className="rich-item new-loading"
+>
+  <div
+    className="flex-1"
+  >
+    <div
+      className="display-inline-flex-center"
+    >
+      <h4>
+        Latest news
+      </h4>
+      <span
+        className="note spacer-left"
+      >
+        <PlaceholderBar
+          color="#aaa"
+          width={60}
+        />
+      </span>
+    </div>
+    <p
+      className="little-spacer-bottom"
+    >
+      <PlaceholderBar
+        color="#aaa"
+        width={84}
+      />
+       
+      <PlaceholderBar
+        color="#aaa"
+        width={48}
+      />
+       
+      <PlaceholderBar
+        color="#aaa"
+        width={24}
+      />
+       
+      <PlaceholderBar
+        color="#aaa"
+        width={72}
+      />
+       
+      <PlaceholderBar
+        color="#aaa"
+        width={24}
+      />
+       
+      <PlaceholderBar
+        color="#aaa"
+        width={48}
+      />
+    </p>
+  </div>
+  <ChevronRightIcon
+    className="flex-0"
+  />
+</a>
+`;
+
+exports[`should load the product news 2`] = `
+<a
+  className="rich-item"
+  href="https://blog.sonarsource.com/my-product-news"
+  rel="noopener noreferrer"
+  target="_blank"
+>
+  <div
+    className="flex-1"
+  >
+    <div
+      className="display-inline-flex-center"
+    >
+      <h4>
+        Latest news
+      </h4>
+      <DateFormatter
+        date="2018-04-06T12:07:19+0000"
+      />
+    </div>
+    <p
+      className="little-spacer-bottom"
+    >
+      My Product News
+    </p>
+  </div>
+  <ChevronRightIcon
+    className="flex-0"
+  />
+</a>
+`;
index e5bf1c05edab4678c0afa2282e46fa3400a485a8..9bead9c66d3d78e0c53118e16ec6e4b61a6d1921 100644 (file)
   transition: none;
 }
 
+.menu > li > a.rich-item {
+  display: flex;
+  align-items: center;
+  border: 1px solid var(--gray80);
+  border-radius: 4px;
+  margin: 4px 10px;
+  padding: 2px 8px;
+  white-space: normal;
+}
+
 .menu .divider {
   height: 1px;
   margin: 6px 0;
index 16e78425e0a6f68bbf9bb039ee4d5390278a4f78..0e70c8dba9905e8689c047313c9659114065ec3c 100644 (file)
@@ -310,6 +310,10 @@ td.big-spacer-top {
   flex: 1;
 }
 
+.flex-0 {
+  flex: 0 0 auto;
+}
+
 .flex-shrink {
   flex-shrink: 1;
   min-width: 0;
diff --git a/server/sonar-web/src/main/js/components/ui/PlaceholderBar.css b/server/sonar-web/src/main/js/components/ui/PlaceholderBar.css
new file mode 100644 (file)
index 0000000..a204a34
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+.placeholder-bar {
+  display: inline-block;
+  vertical-align: middle;
+  height: 8px;
+  background-color: currentColor;
+}
diff --git a/server/sonar-web/src/main/js/components/ui/PlaceholderBar.tsx b/server/sonar-web/src/main/js/components/ui/PlaceholderBar.tsx
new file mode 100644 (file)
index 0000000..c33d3b7
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+import * as React from 'react';
+import './PlaceholderBar.css';
+
+interface Props {
+  color?: string;
+  width: number;
+  height?: number;
+}
+
+export default function PlaceholderBar({ color, width, height }: Props) {
+  return <span className="placeholder-bar" style={{ color, width, height }} />;
+}
index 1b0e075b21e9212a5624029dfc9196bb56348fd8..682b86d22fe5b3601c5eb059f3078091e4272583 100644 (file)
@@ -212,6 +212,23 @@ export function getJSON(url: string, data?: RequestData): Promise<any> {
     .then(parseJSON);
 }
 
+/**
+ * Shortcut to do a CORS GET request and return responsejson
+ */
+export function getCorsJSON(url: string, data?: RequestData): Promise<any> {
+  return corsRequest(url)
+    .setData(data)
+    .submit()
+    .then(response => {
+      if (response.status >= 200 && response.status < 300) {
+        return Promise.resolve(response);
+      } else {
+        return Promise.reject({ response });
+      }
+    })
+    .then(parseJSON);
+}
+
 /**
  * Shortcut to do a POST request and return response json
  */
index 7913933313a3cc389e5e0cc6fcbdfd45ad43cc40..9e09559006dfdcc2cf2c4f4b2743f35021542419 100644 (file)
@@ -2553,11 +2553,12 @@ organization.change_visibility_form.submit=Change Default Visibility
 # EMBEDED DOCS
 #
 #------------------------------------------------------------------------------
-embed_docs.suggestion=Suggestions For This Page
+embed_docs.analyze_new_project=Analyze New Project
 embed_docs.documentation=Documentation
 embed_docs.get_help=Get Help
+embed_docs.news=Product News
 embed_docs.stay_connected=Stay Connected
-embed_docs.analyze_new_project=Analyze New Project
+embed_docs.suggestion=Suggestions For This Page
 
 #------------------------------------------------------------------------------
 #