Commit d3299796 by Tobias Skarhed Committed by GitHub

Migration: Settings forms (#24741)

* Migrate shared preferences

* Remove unused import

* Migrate org name form

* Update TeamSettings

* Convert user settings

* Fix inital default values

* Update snapshots

* Fix CI errors

* Fix failing Ci

* Update snapshots

* Large spacing

* Move use Form for OrgSettings and add FieldSet

* Remove snapshots

* Add snapshots

* Remove unused prop
parent 1e38a24b
......@@ -23,6 +23,7 @@ export { UnitPicker } from './UnitPicker/UnitPicker';
export { StatsPicker } from './StatsPicker/StatsPicker';
export { RefreshPicker } from './RefreshPicker/RefreshPicker';
export { TimeRangePicker } from './TimePicker/TimeRangePicker';
export { TimeZonePicker } from './TimePicker/TimeZonePicker';
export { TimeOfDayPicker } from './TimePicker/TimeOfDayPicker';
export { List } from './List/List';
export { TagsInput } from './TagsInput/TagsInput';
......
......@@ -10,6 +10,7 @@ import { loadOrganization, updateOrganization } from './state/actions';
import { Organization, StoreState } from 'app/types';
import { getNavModel } from 'app/core/selectors/navModel';
import { setOrganizationName } from './state/reducers';
import { VerticalGroup } from '@grafana/ui';
export interface Props {
navModel: NavModel;
......@@ -24,11 +25,8 @@ export class OrgDetailsPage extends PureComponent<Props> {
await this.props.loadOrganization();
}
onOrgNameChange = (name: string) => {
this.props.setOrganizationName(name);
};
onUpdateOrganization = () => {
onUpdateOrganization = (orgName: string) => {
this.props.setOrganizationName(orgName);
this.props.updateOrganization();
};
......@@ -40,14 +38,10 @@ export class OrgDetailsPage extends PureComponent<Props> {
<Page navModel={navModel}>
<Page.Contents isLoading={isLoading}>
{!isLoading && (
<div>
<OrgProfile
onOrgNameChange={name => this.onOrgNameChange(name)}
onSubmit={this.onUpdateOrganization}
orgName={organization.name}
/>
<VerticalGroup>
<OrgProfile onSubmit={this.onUpdateOrganization} orgName={organization.name} />
<SharedPreferences resourceUri="org" />
</div>
</VerticalGroup>
)}
</Page.Contents>
</Page>
......
......@@ -6,7 +6,6 @@ const setup = () => {
const props: Props = {
orgName: 'Main org',
onSubmit: jest.fn(),
onOrgNameChange: jest.fn(),
};
return shallow(<OrgProfile {...props} />);
......
import React, { ChangeEvent, FC } from 'react';
import { LegacyForms } from '@grafana/ui';
const { Input } = LegacyForms;
import React, { FC } from 'react';
import { Input, Field, FieldSet, Button, Form } from '@grafana/ui';
export interface Props {
orgName: string;
onSubmit: () => void;
onOrgNameChange: (orgName: string) => void;
onSubmit: (orgName: string) => void;
}
const OrgProfile: FC<Props> = ({ onSubmit, onOrgNameChange, orgName }) => {
interface FormDTO {
orgName: string;
}
const OrgProfile: FC<Props> = ({ onSubmit, orgName }) => {
return (
<div>
<h3 className="page-sub-heading">Organization profile</h3>
<form
name="orgForm"
className="gf-form-group"
onSubmit={event => {
event.preventDefault();
onSubmit();
}}
>
<div className="gf-form-inline">
<div className="gf-form max-width-28">
<span className="gf-form-label">Organization name</span>
<Input
className="gf-form-input"
type="text"
onChange={(event: ChangeEvent<HTMLInputElement>) => onOrgNameChange(event.target.value)}
value={orgName}
/>
</div>
</div>
<div className="gf-form-button-row">
<button type="submit" className="btn btn-primary">
Save
</button>
</div>
</form>
</div>
<Form defaultValues={{ orgName }} onSubmit={({ orgName }: FormDTO) => onSubmit(orgName)}>
{({ register }) => (
<FieldSet label="Organization profile">
<Field label="Organization name">
<Input name="orgName" type="text" ref={register({ required: true })} />
</Field>
<Button type="submit">Update organization name</Button>
</FieldSet>
)}
</Form>
);
};
......
......@@ -35,16 +35,15 @@ exports[`Render should render organization and preferences 1`] = `
<PageContents
isLoading={false}
>
<div>
<Component>
<OrgProfile
onOrgNameChange={[Function]}
onSubmit={[Function]}
orgName="Cool org"
/>
<SharedPreferences
resourceUri="org"
/>
</div>
</Component>
</PageContents>
</Page>
`;
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Render should render component 1`] = `
<div>
<h3
className="page-sub-heading"
>
Organization profile
</h3>
<form
className="gf-form-group"
name="orgForm"
onSubmit={[Function]}
>
<div
className="gf-form-inline"
>
<div
className="gf-form max-width-28"
>
<span
className="gf-form-label"
>
Organization name
</span>
<Input
className="gf-form-input"
onChange={[Function]}
type="text"
value="Main org"
/>
</div>
</div>
<div
className="gf-form-button-row"
>
<button
className="btn btn-primary"
type="submit"
>
Save
</button>
</div>
</form>
</div>
<Form
defaultValues={
Object {
"orgName": "Main org",
}
}
onSubmit={[Function]}
>
<Component />
</Form>
`;
......@@ -12,7 +12,7 @@ const setup = (propOverrides?: object) => {
Object.assign(props, propOverrides);
const wrapper = shallow(<TeamSettings {...props} />);
const instance = wrapper.instance() as TeamSettings;
const instance = wrapper.instance() as any;
return {
wrapper,
......@@ -27,18 +27,3 @@ describe('Render', () => {
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');
});
});
import React from 'react';
import React, { FC } from 'react';
import { connect } from 'react-redux';
import { InlineFormLabel, LegacyForms } from '@grafana/ui';
const { Input } = LegacyForms;
import { Input, Field, Form, Button, FieldSet, VerticalGroup } from '@grafana/ui';
import { SharedPreferences } from 'app/core/components/SharedPreferences/SharedPreferences';
import { updateTeam } from './state/actions';
......@@ -14,78 +13,37 @@ export interface Props {
updateTeam: typeof updateTeam;
}
interface State {
name: string;
email: string;
}
export class TeamSettings extends React.Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = {
name: props.team.name,
email: props.team.email,
};
}
onChangeName = (event: any) => {
this.setState({ name: event.target.value });
};
onChangeEmail = (event: any) => {
this.setState({ email: event.target.value });
};
onUpdate = (event: any) => {
const { name, email } = this.state;
event.preventDefault();
this.props.updateTeam(name, email);
};
render() {
const { team } = this.props;
const { name, email } = this.state;
return (
<div>
<h3 className="page-sub-heading">Team Settings</h3>
<form name="teamDetailsForm" className="gf-form-group" onSubmit={this.onUpdate}>
<div className="gf-form max-width-30">
<InlineFormLabel>Name</InlineFormLabel>
<Input
type="text"
required
value={name}
className="gf-form-input max-width-22"
onChange={this.onChangeName}
/>
</div>
<div className="gf-form max-width-30">
<InlineFormLabel tooltip="This is optional and is primarily used to set the team profile avatar (via gravatar service)">
Email
</InlineFormLabel>
<Input
type="email"
className="gf-form-input max-width-22"
value={email}
placeholder="team@email.com"
onChange={this.onChangeEmail}
/>
</div>
<div className="gf-form-button-row">
<button type="submit" className="btn btn-primary">
Update
</button>
</div>
</form>
<SharedPreferences resourceUri={`teams/${team.id}`} />
</div>
);
}
}
export const TeamSettings: FC<Props> = ({ team, updateTeam }) => {
return (
<VerticalGroup>
<FieldSet label="Team Settings">
<Form
defaultValues={{ ...team }}
onSubmit={(formTeam: Team) => {
updateTeam(formTeam.name, formTeam.email);
}}
>
{({ register }) => (
<>
<Field label="Name">
<Input name="name" ref={register({ required: true })} />
</Field>
<Field
label="Email"
description="This is optional and is primarily used to set the team profile avatar (via gravatar service)"
>
<Input placeholder="team@email.com" type="email" name="email" ref={register} />
</Field>
<Button type="submit">Update</Button>
</>
)}
</Form>
</FieldSet>
<SharedPreferences resourceUri={`teams/${team.id}`} />
</VerticalGroup>
);
};
function mapStateToProps(state: any) {
const teamId = getRouteParamsId(state.location);
......
......@@ -44,7 +44,7 @@ exports[`Render should render settings and preferences page 1`] = `
<PageContents
isLoading={true}
>
<Connect(TeamSettings) />
<Connect(Component) />
</PageContents>
</Page>
`;
......@@ -66,7 +66,7 @@ exports[`Render when feature toggle editorsCanAdmin is turned on should render s
<PageContents
isLoading={true}
>
<Connect(TeamSettings) />
<Connect(Component) />
</PageContents>
</Page>
`;
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Render should render component 1`] = `
<div>
<h3
className="page-sub-heading"
<Component>
<Component
label="Team Settings"
>
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"
<Form
defaultValues={
Object {
"avatarUrl": "some/url/",
"email": "test@test.com",
"id": 1,
"memberCount": 1,
"name": "test",
"permission": 0,
}
}
onSubmit={[Function]}
>
<button
className="btn btn-primary"
type="submit"
>
Update
</button>
</div>
</form>
<Component />
</Form>
</Component>
<SharedPreferences
resourceUri="teams/1"
/>
</div>
</Component>
`;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment