Browse Source

feat(ui): new platformicons on dashboard (#8327)

* feat(ui): introduce new platformicons and platformicon component

* add platformicon story

* add perl icon

* Shorter install an sdk button

* remove unecessary package

* Add cordova, electron, rust, and vue icons

* Rename context/ios.svg to avoid naming conflict

* Remove unecessary className. Update test.

* Platformicon is one word
Chris Jennings 6 years ago
parent
commit
ff19a3d984

+ 42 - 0
docs-ui/components/platformicon.stories.js

@@ -0,0 +1,42 @@
+import React from 'react';
+import styled from 'react-emotion';
+import {storiesOf} from '@storybook/react';
+import {withInfo} from '@storybook/addon-info';
+
+import Platformicon from 'app/components/platformicon';
+
+const StyledPlatformicon = styled(Platformicon)`
+  margin: 0 15px 15px 0;
+`;
+
+storiesOf('Platformicon', module).add(
+  'default',
+  withInfo('Scalable platform and framework icons')(() => (
+    <div>
+      <StyledPlatformicon platform="generic" size="24" />
+      <StyledPlatformicon platform="javascript-angular" size="24" />
+      <StyledPlatformicon platform="java-appengine" size="24" />
+      <StyledPlatformicon platform="apple" size="24" />
+      <StyledPlatformicon platform="python-bottle" size="24" />
+      <StyledPlatformicon platform="cordova" size="24" />
+      <StyledPlatformicon platform="csharp" size="24" />
+      <StyledPlatformicon platform="python-django" size="24" />
+      <StyledPlatformicon platform="electron" size="24" />
+      <StyledPlatformicon platform="elixir" size="24" />
+      <StyledPlatformicon platform="javascript-ember" size="24" />
+      <StyledPlatformicon platform="python-flask" size="24" />
+      <StyledPlatformicon platform="go" size="24" />
+      <StyledPlatformicon platform="java" size="24" />
+      <StyledPlatformicon platform="node" size="24" />
+      <StyledPlatformicon platform="php" size="24" />
+      <StyledPlatformicon platform="perl" size="24" />
+      <StyledPlatformicon platform="python" size="24" />
+      <StyledPlatformicon platform="ruby-rails" size="24" />
+      <StyledPlatformicon platform="javascript-react" size="24" />
+      <StyledPlatformicon platform="ruby" size="24" />
+      <StyledPlatformicon platform="rust" size="24" />
+      <StyledPlatformicon platform="swift" size="24" />
+      <StyledPlatformicon platform="javascript-vue" size="24" />
+    </div>
+  ))
+);

+ 24 - 13
package.json

@@ -55,7 +55,7 @@
     "moment": "2.22.0",
     "moment-timezone": "0.5.4",
     "node-libs-browser": "0.5.3",
-    "platformicons": "2.0.1",
+    "platformicons": "2.0.3",
     "po-catalog-loader": "^1.2.0",
     "prop-types": "^15.6.0",
     "query-string": "2.4.2",
@@ -96,14 +96,12 @@
     "test-ci": "yarn test --runInBand --ci --coverage --testResultsProcessor=jest-junit",
     "test-debug": "node --inspect-brk scripts/test.js --runInBand",
     "test-staged": "yarn test --findRelatedTests $(git diff --name-only --cached)",
-    "lint":
-      "node_modules/.bin/eslint tests/js src/sentry/static/sentry/app --ext .js,.jsx",
+    "lint": "node_modules/.bin/eslint tests/js src/sentry/static/sentry/app --ext .js,.jsx",
     "lint:css": "stylelint 'src/sentry/static/sentry/app/**/*.jsx'",
     "dev-proxy": "node scripts/devproxy.js",
     "dev-server": "webpack-dev-server",
     "storybook": "start-storybook -p 9001 -c .storybook",
-    "snapshot":
-      "build-storybook && PERCY_TOKEN=$STORYBOOK_PERCY_TOKEN PERCY_PROJECT=$STORYBOOK_PERCY_PROJECT percy-storybook --widths=1280",
+    "snapshot": "build-storybook && PERCY_TOKEN=$STORYBOOK_PERCY_TOKEN PERCY_PROJECT=$STORYBOOK_PERCY_PROJECT percy-storybook --widths=1280",
     "webpack-profile": "yarn -s webpack --profile --json > stats.json"
   },
   "jest": {
@@ -111,20 +109,33 @@
       "tests/js/spec/**/*.{js,jsx}",
       "src/sentry/static/sentry/app/**/*.{js,jsx}"
     ],
-    "coverageReporters": ["html", "lcov", "cobertura"],
-    "snapshotSerializers": ["enzyme-to-json/serializer"],
+    "coverageReporters": [
+      "html",
+      "lcov",
+      "cobertura"
+    ],
+    "snapshotSerializers": [
+      "enzyme-to-json/serializer"
+    ],
     "moduleNameMapper": {
       "\\.(css|less|png)$": "<rootDir>/tests/js/helpers/importStyleMock.js",
       "\\.(svg)$": "<rootDir>/tests/js/helpers/svgMock.js",
       "jquery": "<rootDir>/src/sentry/static/sentry/__mocks__/jquery.jsx",
-      "integration-docs-platforms":
-        "<rootDir>/tests/fixtures/integration-docs/_platforms.json"
+      "integration-docs-platforms": "<rootDir>/tests/fixtures/integration-docs/_platforms.json"
     },
-    "modulePaths": ["<rootDir>/src/sentry/static/sentry"],
-    "setupFiles": ["<rootDir>/tests/js/setup.js"],
+    "modulePaths": [
+      "<rootDir>/src/sentry/static/sentry"
+    ],
+    "setupFiles": [
+      "<rootDir>/tests/js/setup.js"
+    ],
     "setupTestFrameworkScriptFile": "<rootDir>/tests/js/setupFramework.js",
-    "testMatch": ["<rootDir>/tests/js/**/?(*.)(spec|test).js?(x)"],
-    "testPathIgnorePatterns": ["<rootDir>/tests/sentry/lang/javascript/"],
+    "testMatch": [
+      "<rootDir>/tests/js/**/?(*.)(spec|test).js?(x)"
+    ],
+    "testPathIgnorePatterns": [
+      "<rootDir>/tests/sentry/lang/javascript/"
+    ],
     "unmockedModulePathPatterns": [
       "<rootDir>/node_modules/react",
       "<rootDir>/node_modules/reflux"

+ 82 - 0
src/sentry/static/sentry/app/components/platformicon.jsx

@@ -0,0 +1,82 @@
+import PropTypes from 'prop-types';
+import React from 'react';
+
+const PLATFORM_TO_ICON = {
+  apple: 'apple',
+  cocoa: 'apple',
+  cordova: 'cordova',
+  csharp: 'csharp',
+  elixir: 'elixir',
+  electron: 'electron',
+  go: 'go',
+  java: 'java',
+  'java-android': 'java',
+  'java-appengine': 'app-engine',
+  'java-log4j': 'java',
+  'java-log4j2': 'java',
+  'java-logback': 'java',
+  'java-logging': 'java',
+  javascript: 'javascript',
+  'javascript-angular': 'angularjs',
+  'javascript-backbone': 'javascript',
+  'javascript-ember': 'ember',
+  'javascript-react': 'react',
+  'javascript-vue': 'vue',
+  node: 'nodejs',
+  'node-connect': 'nodejs',
+  'node-express': 'nodejs',
+  'node-koa': 'nodejs',
+  'objective-c': 'apple',
+  perl: 'perl',
+  php: 'php',
+  'php-laravel': 'laravel',
+  'php-monolog': 'php',
+  'php-symfony2': 'php',
+  python: 'python',
+  'python-flask': 'flask',
+  'python-bottle': 'bottle',
+  'python-celery': 'python',
+  'python-django': 'django',
+  'python-pylons': 'python',
+  'python-pyramid': 'python',
+  'python-rq': 'python',
+  'python-tornado': 'python',
+  'react-native': 'apple',
+  ruby: 'ruby',
+  'ruby-rack': 'ruby',
+  'ruby-rails': 'rails',
+  rust: 'rust',
+  swift: 'swift',
+};
+
+export function getIcon(platform) {
+  let icon = PLATFORM_TO_ICON[platform];
+
+  if (!icon) {
+    return 'generic';
+  } else {
+    return icon;
+  }
+}
+
+const Platformicon = ({platform, size, width, height, ...props}) => {
+  let icon = getIcon(platform);
+
+  return (
+    <img
+      src={require(`platformicons/svg/${icon}.svg`)}
+      width={width || size || '1em'}
+      height={height || size || '1em'}
+      {...props}
+    />
+  );
+};
+
+Platformicon.propTypes = {
+  platform: PropTypes.string.isRequired,
+  size: PropTypes.string,
+  width: PropTypes.string,
+  height: PropTypes.string,
+};
+
+export default Platformicon;

+ 10 - 12
src/sentry/static/sentry/app/views/organizationDashboard/platformList.jsx

@@ -7,6 +7,7 @@ import {Flex} from 'grid-emotion';
 import SentryTypes from 'app/proptypes';
 import {t} from 'app/locale';
 import Button from 'app/components/buttons/button';
+import Platformicon from 'app/components/platformicon';
 
 const MAX_PLATFORMS = 5;
 
@@ -18,9 +19,9 @@ class PlatformList extends React.Component {
 
   getIcon(platform) {
     return (
-      <StyledPlatformIconWrapper key={platform} className={platform}>
-        <StyledPlatformIcon className={`platformicon platformicon-${platform}`} />
-      </StyledPlatformIconWrapper>
+      <StyledPlatformiconWrapper key={platform}>
+        <StyledPlatformicon platform={platform} size="24" />
+      </StyledPlatformiconWrapper>
     );
   }
 
@@ -65,21 +66,18 @@ class PlatformList extends React.Component {
   }
 }
 
-const StyledPlatformIconWrapper = styled.span`
+const StyledPlatformiconWrapper = styled.span`
   display: block;
-  margin-right: -14px;
-  margin-left: -2px;
+  margin-right: -8px;
 `;
 
-const StyledPlatformIcon = styled.span`
+const StyledPlatformicon = styled(Platformicon)`
   display: block;
   color: white;
-  height: 34px;
-  width: 34px;
   font-size: 22px;
   border-radius: 4px;
-  border: 2px solid white;
-  padding: 4px;
+  box-shadow: 0 0 0 2px #fff;
+  max-width: 24px;
 `;
 
 const PlatformText = styled.div`
@@ -90,7 +88,7 @@ const PlatformText = styled.div`
 
 const NoPlatforms = styled(Flex)`
   color: ${p => p.theme.gray2};
-  height: 66px;
+  height: 56px;
 `;
 
 export default withRouter(PlatformList);

+ 0 - 0
src/sentry/static/sentry/images/icons/context/ios.svg → src/sentry/static/sentry/images/icons/context/apple-ios.svg


+ 1 - 1
src/sentry/static/sentry/less/group-detail.less

@@ -1009,7 +1009,7 @@
     &.mac,
     &.watchos {
       .context-item-icon {
-        background-image: url(../images/icons/context/ios.svg);
+        background-image: url(../images/icons/context/apple-ios.svg);
         top: -2px;
       }
     }

+ 26 - 10
tests/js/spec/views/organizationDashboard/__snapshots__/projectCard.spec.jsx.snap

@@ -397,22 +397,38 @@ exports[`ProjectCard renders 1`] = `
                         className="css-1tznizk"
                         is={null}
                       >
-                        <StyledPlatformIconWrapper
-                          className="javascript"
+                        <StyledPlatformiconWrapper
                           key="javascript"
                         >
                           <span
-                            className="javascript css-128o7xp-StyledPlatformIconWrapper e1mca4c60"
+                            className="css-sxusd0-StyledPlatformiconWrapper e1mca4c60"
                           >
-                            <StyledPlatformIcon
-                              className="platformicon platformicon-javascript"
+                            <StyledPlatformicon
+                              platform="javascript"
+                              size="24"
                             >
-                              <span
-                                className="platformicon platformicon-javascript css-hf0kxf-StyledPlatformIcon e1mca4c61"
-                              />
-                            </StyledPlatformIcon>
+                              <Platformicon
+                                className="css-950w8s-StyledPlatformicon e1mca4c61"
+                                platform="javascript"
+                                size="24"
+                              >
+                                <img
+                                  className="css-950w8s-StyledPlatformicon e1mca4c61"
+                                  height="24"
+                                  src={
+                                    Object {
+                                      "default": Object {
+                                        "id": "test",
+                                        "viewBox": Object {},
+                                      },
+                                    }
+                                  }
+                                  width="24"
+                                />
+                              </Platformicon>
+                            </StyledPlatformicon>
                           </span>
-                        </StyledPlatformIconWrapper>
+                        </StyledPlatformiconWrapper>
                       </div>
                     </Base>
                   </Flex>

+ 3 - 3
tests/js/spec/views/organizationDashboard/projectCard.spec.jsx

@@ -48,9 +48,9 @@ describe('ProjectCard', function() {
 
   it('renders with one platform', function() {
     const platformList = wrapper.find('PlatformList');
-    expect(
-      platformList.find('StyledPlatformIcon.platformicon.platformicon-javascript')
-    ).toHaveLength(1);
+    expect(platformList.find('StyledPlatformicon[platform="javascript"]')).toHaveLength(
+      1
+    );
   });
 
   it('renders empty state if no event has ever been sent', function() {

+ 3 - 3
yarn.lock

@@ -7122,9 +7122,9 @@ pkg-dir@^2.0.0:
   dependencies:
     find-up "^2.1.0"
 
-platformicons@2.0.1:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/platformicons/-/platformicons-2.0.1.tgz#6d29a3ca9b7d0634850accb924ae5b12a221990f"
+platformicons@2.0.3:
+  version "2.0.3"
+  resolved "https://registry.yarnpkg.com/platformicons/-/platformicons-2.0.3.tgz#a7cf8074059639373061a4c00cf69d49800e7d01"
 
 pluralize@^4.0.0:
   version "4.0.0"