Kaynağa Gözat

team settings

Peter Holmberg 7 yıl önce
ebeveyn
işleme
b1fe0c4c7e

+ 1 - 1
public/app/features/teams/TeamPages.tsx

@@ -66,7 +66,7 @@ export class TeamPages extends PureComponent<Props, State> {
         return <TeamMembers />;
 
       case PageTypes.Settings:
-        return <TeamSettings team={team} />;
+        return <TeamSettings />;
 
       case PageTypes.GroupSync:
         return isSyncEnabled && <TeamGroupSync team={team} />;

+ 44 - 0
public/app/features/teams/TeamSettings.test.tsx

@@ -0,0 +1,44 @@
+import React from 'react';
+import { shallow } from 'enzyme';
+import { Props, TeamSettings } from './TeamSettings';
+import { getMockTeam } from './__mocks__/teamMocks';
+
+const setup = (propOverrides?: object) => {
+  const props: Props = {
+    team: getMockTeam(),
+    updateTeam: jest.fn(),
+  };
+
+  Object.assign(props, propOverrides);
+
+  const wrapper = shallow(<TeamSettings {...props} />);
+  const instance = wrapper.instance() as TeamSettings;
+
+  return {
+    wrapper,
+    instance,
+  };
+};
+
+describe('Render', () => {
+  it('should render component', () => {
+    const { wrapper } = setup();
+
+    expect(wrapper).toMatchSnapshot();
+  });
+});
+
+describe('Functions', () => {
+  it('should update team', () => {
+    const { instance } = setup();
+    const mockEvent = { preventDefault: jest.fn() };
+
+    instance.setState({
+      name: 'test11',
+    });
+
+    instance.onUpdate(mockEvent);
+
+    expect(instance.props.updateTeam).toHaveBeenCalledWith('test11', 'test@test.com');
+  });
+});

+ 44 - 15
public/app/features/teams/TeamSettings.tsx

@@ -1,41 +1,58 @@
 import React from 'react';
-import { hot } from 'react-hot-loader';
+import { connect } from 'react-redux';
 import { Label } from 'app/core/components/Forms/Forms';
 import { Team } from '../../types';
+import { updateTeam } from './state/actions';
+import { getRouteParamsId } from '../../core/selectors/location';
+import { getTeam } from './state/selectors';
 
-interface Props {
+export interface Props {
   team: Team;
+  updateTeam: typeof updateTeam;
 }
 
-export class TeamSettings extends React.Component<Props, any> {
+interface State {
+  name: string;
+  email: string;
+}
+
+export class TeamSettings extends React.Component<Props, State> {
   constructor(props) {
     super(props);
+
+    this.state = {
+      name: props.team.name,
+      email: props.team.email,
+    };
   }
 
-  onChangeName = evt => {
-    // this.props.team.setName(evt.target.value);
+  onChangeName = event => {
+    this.setState({ name: event.target.value });
   };
 
-  onChangeEmail = evt => {
-    // this.props.team.setEmail(evt.target.value);
+  onChangeEmail = event => {
+    this.setState({ email: event.target.value });
   };
 
-  onUpdate = evt => {
-    evt.preventDefault();
-    // this.props.team.update();
+  onUpdate = event => {
+    const { name, email } = this.state;
+    event.preventDefault();
+    this.props.updateTeam(name, email);
   };
 
   render() {
+    const { name, email } = this.state;
+
     return (
       <div>
         <h3 className="page-sub-heading">Team Settings</h3>
-        <form name="teamDetailsForm" className="gf-form-group">
+        <form name="teamDetailsForm" className="gf-form-group" onSubmit={this.onUpdate}>
           <div className="gf-form max-width-30">
             <Label>Name</Label>
             <input
               type="text"
               required
-              value={this.props.team.name}
+              value={name}
               className="gf-form-input max-width-22"
               onChange={this.onChangeName}
             />
@@ -47,14 +64,14 @@ export class TeamSettings extends React.Component<Props, any> {
             <input
               type="email"
               className="gf-form-input max-width-22"
-              value={this.props.team.email}
+              value={email}
               placeholder="team@email.com"
               onChange={this.onChangeEmail}
             />
           </div>
 
           <div className="gf-form-button-row">
-            <button type="submit" className="btn btn-success" onClick={this.onUpdate}>
+            <button type="submit" className="btn btn-success">
               Update
             </button>
           </div>
@@ -64,4 +81,16 @@ export class TeamSettings extends React.Component<Props, any> {
   }
 }
 
-export default hot(module)(TeamSettings);
+function mapStateToProps(state) {
+  const teamId = getRouteParamsId(state.location);
+
+  return {
+    team: getTeam(state.team, teamId),
+  };
+}
+
+const mapDispatchToProps = {
+  updateTeam,
+};
+
+export default connect(mapStateToProps, mapDispatchToProps)(TeamSettings);

+ 1 - 11
public/app/features/teams/__snapshots__/TeamPages.test.tsx.snap

@@ -52,17 +52,7 @@ exports[`Render should render settings page 1`] = `
   <div
     className="page-container page-body"
   >
-    <TeamSettings
-      team={
-        Object {
-          "avatarUrl": "some/url/",
-          "email": "test@test.com",
-          "id": 1,
-          "memberCount": 1,
-          "name": "test",
-        }
-      }
-    />
+    <Connect(TeamSettings) />
   </div>
 </div>
 `;

+ 57 - 0
public/app/features/teams/__snapshots__/TeamSettings.test.tsx.snap

@@ -0,0 +1,57 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Render should render component 1`] = `
+<div>
+  <h3
+    className="page-sub-heading"
+  >
+    Team Settings
+  </h3>
+  <form
+    className="gf-form-group"
+    name="teamDetailsForm"
+    onSubmit={[Function]}
+  >
+    <div
+      className="gf-form max-width-30"
+    >
+      <Component>
+        Name
+      </Component>
+      <input
+        className="gf-form-input max-width-22"
+        onChange={[Function]}
+        required={true}
+        type="text"
+        value="test"
+      />
+    </div>
+    <div
+      className="gf-form max-width-30"
+    >
+      <Component
+        tooltip="This is optional and is primarily used to set the team profile avatar (via gravatar service)"
+      >
+        Email
+      </Component>
+      <input
+        className="gf-form-input max-width-22"
+        onChange={[Function]}
+        placeholder="team@email.com"
+        type="email"
+        value="test@test.com"
+      />
+    </div>
+    <div
+      className="gf-form-button-row"
+    >
+      <button
+        className="btn btn-success"
+        type="submit"
+      >
+        Update
+      </button>
+    </div>
+  </form>
+</div>
+`;

+ 14 - 0
public/app/features/teams/state/actions.ts

@@ -153,6 +153,20 @@ export function removeTeamMember(id: number): ThunkResult<void> {
   };
 }
 
+export function updateTeam(name: string, email: string): ThunkResult<void> {
+  return async (dispatch, getStore) => {
+    const team = getStore().team.team;
+    await getBackendSrv()
+      .put(`/api/teams/${team.id}`, {
+        name,
+        email,
+      })
+      .then(() => {
+        dispatch(loadTeam(team.id));
+      });
+  };
+}
+
 export function deleteTeam(id: number): ThunkResult<void> {
   return async dispatch => {
     await getBackendSrv()