]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-13765 Fix permissions page minimum width
authorWouter Admiraal <wouter.admiraal@sonarsource.com>
Tue, 27 Apr 2021 12:42:18 +0000 (14:42 +0200)
committersonartech <sonartech@sonarsource.com>
Thu, 29 Apr 2021 20:03:27 +0000 (20:03 +0000)
server/sonar-web/src/main/js/apps/permissions/shared/components/GroupHolder.tsx
server/sonar-web/src/main/js/apps/permissions/shared/components/UserHolder.tsx
server/sonar-web/src/main/js/apps/permissions/shared/components/__tests__/GroupHolder-test.tsx
server/sonar-web/src/main/js/apps/permissions/shared/components/__tests__/UserHolder-test.tsx
server/sonar-web/src/main/js/apps/permissions/shared/components/__tests__/__snapshots__/GroupHolder-test.tsx.snap
server/sonar-web/src/main/js/apps/permissions/shared/components/__tests__/__snapshots__/UserHolder-test.tsx.snap
server/sonar-web/src/main/js/apps/permissions/styles.css

index 16ec9611353659765871d1c0b1a54f53c0f6f934..1c71b4e11e8ea8b44634454f0da1383c0c9c3684 100644 (file)
@@ -68,15 +68,15 @@ export default class GroupHolder extends React.PureComponent<Props, State> {
     return (
       <tr>
         <td className="nowrap text-middle">
-          <div className="display-inline-block text-middle big-spacer-right">
-            <GroupIcon />
-          </div>
-          <div className="display-inline-block text-middle">
-            <div>
-              <strong>{group.name}</strong>
-            </div>
-            <div className="little-spacer-top" style={{ whiteSpace: 'normal' }}>
-              {group.description}
+          <div className="display-flex-center">
+            <GroupIcon className="big-spacer-right" />
+            <div className="max-width-100">
+              <div className="max-width-100 text-ellipsis">
+                <strong>{group.name}</strong>
+              </div>
+              <div className="little-spacer-top" style={{ whiteSpace: 'normal' }}>
+                {group.description}
+              </div>
             </div>
           </div>
         </td>
index 61c4f40eef7bb73d1c003a3a7a5182df2df21963..40e7cb648cb1f75a29f08c75e508fc899fd34a46 100644 (file)
@@ -21,7 +21,6 @@ import { without } from 'lodash';
 import * as React from 'react';
 import { translate } from 'sonar-ui-common/helpers/l10n';
 import Avatar from '../../../../components/ui/Avatar';
-import { isSonarCloud } from '../../../../helpers/system';
 import { isPermissionDefinitionGroup } from '../../utils';
 import PermissionCell from './PermissionCell';
 
@@ -81,17 +80,11 @@ export default class UserHolder extends React.PureComponent<Props, State> {
       return (
         <tr>
           <td className="nowrap text-middle">
-            <div className="display-inline-block text-middle">
-              <div>
-                <strong>{user.name}</strong>
-              </div>
-              <div className="little-spacer-top" style={{ whiteSpace: 'normal' }}>
-                {translate(
-                  isSonarCloud()
-                    ? 'permission_templates.project_creators.explanation.sonarcloud'
-                    : 'permission_templates.project_creators.explanation'
-                )}
-              </div>
+            <div>
+              <strong>{user.name}</strong>
+            </div>
+            <div className="little-spacer-top" style={{ whiteSpace: 'normal' }}>
+              {translate('permission_templates.project_creators.explanation')}
             </div>
           </td>
           {permissionCells}
@@ -102,29 +95,20 @@ export default class UserHolder extends React.PureComponent<Props, State> {
     return (
       <tr>
         <td className="nowrap text-middle">
-          <Avatar
-            className="text-middle big-spacer-right"
-            hash={user.avatar}
-            name={user.name}
-            size={36}
-          />
-          <div className="display-inline-block text-middle">
-            {isSonarCloud() ? (
-              <>
-                <div>
-                  <strong>{user.name}</strong>
-                </div>
-                <div className="note little-spacer-top">{user.login}</div>
-              </>
-            ) : (
-              <>
-                <div>
-                  <strong>{user.name}</strong>
-                  <span className="note spacer-left">{user.login}</span>
-                </div>
-                <div className="little-spacer-top">{user.email}</div>
-              </>
-            )}
+          <div className="display-flex-center">
+            <Avatar
+              className="text-middle big-spacer-right flex-0"
+              hash={user.avatar}
+              name={user.name}
+              size={36}
+            />
+            <div className="max-width-100">
+              <div className="max-width-100 text-ellipsis">
+                <strong>{user.name}</strong>
+                <span className="note spacer-left">{user.login}</span>
+              </div>
+              <div className="little-spacer-top max-width-100 text-ellipsis">{user.email}</div>
+            </div>
           </div>
         </td>
         {permissionCells}
index 9c0eb3970441510196dceb381a7a1bebb1c18111..08889d8210e0ea7e3fc481c7a342fdf2d2c1490b 100644 (file)
 import { shallow } from 'enzyme';
 import * as React from 'react';
 import { waitAndUpdate } from 'sonar-ui-common/helpers/testUtils';
+import { mockPermissionGroup } from '../../../../../helpers/mocks/permissions';
 import GroupHolder from '../GroupHolder';
 
-const group = {
-  id: 'foobar',
-  name: 'Foobar',
-  permissions: ['bar']
-};
-
-const groupHolder = (
-  <GroupHolder
-    group={group}
-    key="foo"
-    onToggle={jest.fn(() => Promise.resolve())}
-    permissions={[
-      {
-        category: 'admin',
-        permissions: [
-          { key: 'foo', name: 'Foo', description: '' },
-          { key: 'bar', name: 'Bar', description: '' }
-        ]
-      },
-      { key: 'baz', name: 'Baz', description: '' }
-    ]}
-    selectedPermission="bar"
-  />
-);
-
 it('should render correctly', () => {
-  expect(shallow(groupHolder)).toMatchSnapshot();
+  expect(shallowRender()).toMatchSnapshot('default');
 });
 
-it('should disabled PermissionCell checkboxes when waiting for promise to return', async () => {
-  const wrapper = shallow<GroupHolder>(groupHolder);
+it('should disable PermissionCell checkboxes when waiting for promise to return', async () => {
+  const wrapper = shallowRender();
   expect(wrapper.state().loading).toEqual([]);
 
   wrapper.instance().handleCheck(true, 'baz');
@@ -66,3 +42,24 @@ it('should disabled PermissionCell checkboxes when waiting for promise to return
   await waitAndUpdate(wrapper);
   expect(wrapper.state().loading).toEqual([]);
 });
+
+function shallowRender(props: Partial<GroupHolder['props']> = {}) {
+  return shallow<GroupHolder>(
+    <GroupHolder
+      group={mockPermissionGroup({ id: 'foobar' })}
+      onToggle={jest.fn().mockResolvedValue(null)}
+      permissions={[
+        {
+          category: 'admin',
+          permissions: [
+            { key: 'foo', name: 'Foo', description: '' },
+            { key: 'bar', name: 'Bar', description: '' }
+          ]
+        },
+        { key: 'baz', name: 'Baz', description: '' }
+      ]}
+      selectedPermission="bar"
+      {...props}
+    />
+  );
+}
index 2458c2338e1d80c69d9bac7c14cb1cdf4ac60d23..da48b3cc4541346eec2ce7177af6e3622c0a76f3 100644 (file)
 import { shallow } from 'enzyme';
 import * as React from 'react';
 import { waitAndUpdate } from 'sonar-ui-common/helpers/testUtils';
-import { isSonarCloud } from '../../../../../helpers/system';
+import { mockPermissionUser } from '../../../../../helpers/mocks/permissions';
 import UserHolder from '../UserHolder';
 
-jest.mock('../../../../../helpers/system', () => ({ isSonarCloud: jest.fn() }));
-
-const user = {
-  email: 'john.doe@sonarsource.com',
-  login: 'john doe',
-  name: 'John Doe',
-  permissions: ['bar']
-};
-
-const userHolder = (
-  <UserHolder
-    key="foo"
-    onToggle={jest.fn(() => Promise.resolve())}
-    permissions={[
-      {
-        category: 'admin',
-        permissions: [
-          { key: 'foo', name: 'Foo', description: '' },
-          { key: 'bar', name: 'Bar', description: '' }
-        ]
-      },
-      { key: 'baz', name: 'Baz', description: '' }
-    ]}
-    selectedPermission="bar"
-    user={user}
-  />
-);
-
 it('should render correctly', () => {
-  expect(shallow(userHolder)).toMatchSnapshot();
+  expect(shallowRender()).toMatchSnapshot('default');
+  expect(shallowRender({ user: mockPermissionUser({ login: '<creator>' }) })).toMatchSnapshot(
+    'creator'
+  );
 });
 
 it('should disabled PermissionCell checkboxes when waiting for promise to return', async () => {
-  const wrapper = shallow<UserHolder>(userHolder);
+  const wrapper = shallowRender();
   expect(wrapper.state().loading).toEqual([]);
 
   wrapper.instance().handleCheck(true, 'baz');
@@ -71,16 +46,23 @@ it('should disabled PermissionCell checkboxes when waiting for promise to return
   expect(wrapper.state().loading).toEqual([]);
 });
 
-it('should show user details for SonarQube', () => {
-  (isSonarCloud as jest.Mock).mockReturnValue(false);
-
-  const wrapper = shallow<UserHolder>(userHolder);
-  expect(wrapper.find('.display-inline-block.text-middle')).toMatchSnapshot();
-});
-
-it('should show user details for SonarCloud', () => {
-  (isSonarCloud as jest.Mock).mockReturnValue(true);
-
-  const wrapper = shallow<UserHolder>(userHolder);
-  expect(wrapper.find('.display-inline-block.text-middle')).toMatchSnapshot();
-});
+function shallowRender(props: Partial<UserHolder['props']> = {}) {
+  return shallow<UserHolder>(
+    <UserHolder
+      onToggle={jest.fn().mockResolvedValue(null)}
+      permissions={[
+        {
+          category: 'admin',
+          permissions: [
+            { key: 'foo', name: 'Foo', description: '' },
+            { key: 'bar', name: 'Bar', description: '' }
+          ]
+        },
+        { key: 'baz', name: 'Baz', description: '' }
+      ]}
+      selectedPermission="bar"
+      user={mockPermissionUser({ email: 'john.doe@sonarsource.com', name: 'John Doe' })}
+      {...props}
+    />
+  );
+}
index 25b18f84153aa24943ddbc1dcff48182818f2cc6..c8d55b33e4786de3fe120f7595405f914d67cf13 100644 (file)
@@ -1,31 +1,35 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
-exports[`should render correctly 1`] = `
+exports[`should render correctly: default 1`] = `
 <tr>
   <td
     className="nowrap text-middle"
   >
     <div
-      className="display-inline-block text-middle big-spacer-right"
+      className="display-flex-center"
     >
-      <GroupIcon />
-    </div>
-    <div
-      className="display-inline-block text-middle"
-    >
-      <div>
-        <strong>
-          Foobar
-        </strong>
-      </div>
+      <GroupIcon
+        className="big-spacer-right"
+      />
       <div
-        className="little-spacer-top"
-        style={
-          Object {
-            "whiteSpace": "normal",
+        className="max-width-100"
+      >
+        <div
+          className="max-width-100 text-ellipsis"
+        >
+          <strong>
+            sonar-admins
+          </strong>
+        </div>
+        <div
+          className="little-spacer-top"
+          style={
+            Object {
+              "whiteSpace": "normal",
+            }
           }
-        }
-      />
+        />
+      </div>
     </div>
   </td>
   <PermissionCell
@@ -52,9 +56,9 @@ exports[`should render correctly 1`] = `
     permissionItem={
       Object {
         "id": "foobar",
-        "name": "Foobar",
+        "name": "sonar-admins",
         "permissions": Array [
-          "bar",
+          "provisioning",
         ],
       }
     }
@@ -74,9 +78,9 @@ exports[`should render correctly 1`] = `
     permissionItem={
       Object {
         "id": "foobar",
-        "name": "Foobar",
+        "name": "sonar-admins",
         "permissions": Array [
-          "bar",
+          "provisioning",
         ],
       }
     }
index 2df2eed98cdab8100d1b6c79097d769a5a9e8bc2..a132c867d355c3273f8def26e22bfe043a40a812 100644 (file)
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
-exports[`should render correctly 1`] = `
+exports[`should render correctly: creator 1`] = `
 <tr>
   <td
     className="nowrap text-middle"
   >
-    <Connect(Avatar)
-      className="text-middle big-spacer-right"
-      name="John Doe"
-      size={36}
-    />
+    <div>
+      <strong>
+        johndoe
+      </strong>
+    </div>
     <div
-      className="display-inline-block text-middle"
+      className="little-spacer-top"
+      style={
+        Object {
+          "whiteSpace": "normal",
+        }
+      }
     >
-      <div>
-        <strong>
-          John Doe
-        </strong>
-        <span
-          className="note spacer-left"
-        >
-          john doe
-        </span>
-      </div>
+      permission_templates.project_creators.explanation
+    </div>
+  </td>
+  <PermissionCell
+    key="admin"
+    loading={Array []}
+    onCheck={[Function]}
+    permission={
+      Object {
+        "category": "admin",
+        "permissions": Array [
+          Object {
+            "description": "",
+            "key": "foo",
+            "name": "Foo",
+          },
+          Object {
+            "description": "",
+            "key": "bar",
+            "name": "Bar",
+          },
+        ],
+      }
+    }
+    permissionItem={
+      Object {
+        "active": true,
+        "local": true,
+        "login": "<creator>",
+        "name": "johndoe",
+        "permissions": Array [
+          "provisioning",
+        ],
+      }
+    }
+    selectedPermission="bar"
+  />
+  <PermissionCell
+    key="baz"
+    loading={Array []}
+    onCheck={[Function]}
+    permission={
+      Object {
+        "description": "",
+        "key": "baz",
+        "name": "Baz",
+      }
+    }
+    permissionItem={
+      Object {
+        "active": true,
+        "local": true,
+        "login": "<creator>",
+        "name": "johndoe",
+        "permissions": Array [
+          "provisioning",
+        ],
+      }
+    }
+    selectedPermission="bar"
+  />
+</tr>
+`;
+
+exports[`should render correctly: default 1`] = `
+<tr>
+  <td
+    className="nowrap text-middle"
+  >
+    <div
+      className="display-flex-center"
+    >
+      <Connect(Avatar)
+        className="text-middle big-spacer-right flex-0"
+        name="John Doe"
+        size={36}
+      />
       <div
-        className="little-spacer-top"
+        className="max-width-100"
       >
-        john.doe@sonarsource.com
+        <div
+          className="max-width-100 text-ellipsis"
+        >
+          <strong>
+            John Doe
+          </strong>
+          <span
+            className="note spacer-left"
+          >
+            john.doe
+          </span>
+        </div>
+        <div
+          className="little-spacer-top max-width-100 text-ellipsis"
+        >
+          john.doe@sonarsource.com
+        </div>
       </div>
     </div>
   </td>
@@ -53,11 +141,13 @@ exports[`should render correctly 1`] = `
     }
     permissionItem={
       Object {
+        "active": true,
         "email": "john.doe@sonarsource.com",
-        "login": "john doe",
+        "local": true,
+        "login": "john.doe",
         "name": "John Doe",
         "permissions": Array [
-          "bar",
+          "provisioning",
         ],
       }
     }
@@ -76,11 +166,13 @@ exports[`should render correctly 1`] = `
     }
     permissionItem={
       Object {
+        "active": true,
         "email": "john.doe@sonarsource.com",
-        "login": "john doe",
+        "local": true,
+        "login": "john.doe",
         "name": "John Doe",
         "permissions": Array [
-          "bar",
+          "provisioning",
         ],
       }
     }
@@ -88,42 +180,3 @@ exports[`should render correctly 1`] = `
   />
 </tr>
 `;
-
-exports[`should show user details for SonarCloud 1`] = `
-<div
-  className="display-inline-block text-middle"
->
-  <div>
-    <strong>
-      John Doe
-    </strong>
-  </div>
-  <div
-    className="note little-spacer-top"
-  >
-    john doe
-  </div>
-</div>
-`;
-
-exports[`should show user details for SonarQube 1`] = `
-<div
-  className="display-inline-block text-middle"
->
-  <div>
-    <strong>
-      John Doe
-    </strong>
-    <span
-      className="note spacer-left"
-    >
-      john doe
-    </span>
-  </div>
-  <div
-    className="little-spacer-top"
-  >
-    john.doe@sonarsource.com
-  </div>
-</div>
-`;
index b138769cb142aea27284f842a1a29946b7100f99..c0ab97ffd832ede168ed63a3124751b1e59ac5ce 100644 (file)
@@ -22,7 +22,7 @@
 }
 
 .permissions-table .permission-column-inner {
-  width: 100px;
+  width: 90px;
 }
 
 .permissions-table .divider {
@@ -36,3 +36,7 @@
   height: 1px;
   width: 100%;
 }
+
+.permissions-table td:first-of-type {
+  max-width: 320px;
+}