migrate core plugins from flow to typescript

This commit is contained in:
Sebastian Sdorra
2019-10-21 12:13:08 +02:00
parent 85703161f6
commit 0703f1e2bd
104 changed files with 583 additions and 93542 deletions

View File

@@ -1,14 +1,13 @@
//@flow
import React from "react";
import { translate } from "react-i18next";
import type { Repository } from "@scm-manager/ui-types";
import { Repository } from "@scm-manager/ui-types";
type Props = {
url: string,
repository: Repository,
url: string;
repository: Repository;
// context props
t: string => string
t: (p: string) => string;
};
class CloneInformation extends React.Component<Props> {
@@ -28,7 +27,8 @@ class CloneInformation extends React.Component<Props> {
<br />
cd {repository.name}
<br />
echo "# {repository.name}" > README.md
echo "# {repository.name}
" > README.md
<br />
git add README.md
<br />

View File

@@ -1,16 +1,12 @@
//@flow
import React from "react";
import { Image } from "@scm-manager/ui-components";
type Props = {
};
type Props = {};
class GitAvatar extends React.Component<Props> {
render() {
return <Image src="/images/git-logo.png" alt="Git Logo" />;
}
}
export default GitAvatar;

View File

@@ -1,11 +1,10 @@
//@flow
import React from "react";
import type { Branch } from "@scm-manager/ui-types";
import { Branch } from "@scm-manager/ui-types";
import { translate } from "react-i18next";
type Props = {
branch: Branch,
t: string => string
branch: Branch;
t: (p: string) => string;
};
class GitBranchInformation extends React.Component<Props> {

View File

@@ -1,25 +1,24 @@
//@flow
import React from "react";
import { translate } from "react-i18next";
import type { Links } from "@scm-manager/ui-types";
import { Links } from "@scm-manager/ui-types";
import { InputField, Checkbox } from "@scm-manager/ui-components";
type Configuration = {
repositoryDirectory?: string,
gcExpression?: string,
nonFastForwardDisallowed: boolean,
_links: Links
repositoryDirectory?: string;
gcExpression?: string;
nonFastForwardDisallowed: boolean;
_links: Links;
};
type Props = {
initialConfiguration: Configuration,
readOnly: boolean,
initialConfiguration: Configuration;
readOnly: boolean;
onConfigurationChange: (Configuration, boolean) => void,
onConfigurationChange: (p1: Configuration, p2: boolean) => void;
// context props
t: string => string
t: (p: string) => string;
};
type State = Configuration & {};
@@ -27,13 +26,24 @@ type State = Configuration & {};
class GitConfigurationForm extends React.Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = { ...props.initialConfiguration };
this.state = {
...props.initialConfiguration
};
}
handleChange = (value: any, name: string) => {
onGcExpressionChange = (value: string) => {
this.setState(
{
[name]: value
gcExpression: value
},
() => this.props.onConfigurationChange(this.state, true)
);
};
onNonFastForwardDisallowed = (value: boolean) => {
this.setState(
{
nonFastForwardDisallowed: value
},
() => this.props.onConfigurationChange(this.state, true)
);
@@ -50,7 +60,7 @@ class GitConfigurationForm extends React.Component<Props, State> {
label={t("scm-git-plugin.config.gcExpression")}
helpText={t("scm-git-plugin.config.gcExpressionHelpText")}
value={gcExpression}
onChange={this.handleChange}
onChange={this.onGcExpressionChange}
disabled={readOnly}
/>
<Checkbox
@@ -58,7 +68,7 @@ class GitConfigurationForm extends React.Component<Props, State> {
label={t("scm-git-plugin.config.nonFastForwardDisallowed")}
helpText={t("scm-git-plugin.config.nonFastForwardDisallowedHelpText")}
checked={nonFastForwardDisallowed}
onChange={this.handleChange}
onChange={this.onNonFastForwardDisallowed}
disabled={readOnly}
/>
</>

View File

@@ -1,32 +1,25 @@
//@flow
import React from "react";
import { translate } from "react-i18next";
import { Title, Configuration } from "@scm-manager/ui-components";
import GitConfigurationForm from "./GitConfigurationForm";
type Props = {
link: string,
link: string;
t: (string) => string
t: (p: string) => string;
};
class GitGlobalConfiguration extends React.Component<Props> {
constructor(props: Props) {
super(props);
}
render() {
const { link, t } = this.props;
return (
<div>
<Title title={t("scm-git-plugin.config.title")}/>
<Configuration link={link} render={props => <GitConfigurationForm {...props} />}/>
<Title title={t("scm-git-plugin.config.title")} />
<Configuration link={link} render={(props: any) => <GitConfigurationForm {...props} />} />
</div>
);
}
}
export default translate("plugins")(GitGlobalConfiguration);

View File

@@ -1,13 +1,12 @@
//@flow
import React from "react";
import type { Repository } from "@scm-manager/ui-types";
import { Repository } from "@scm-manager/ui-types";
import { translate } from "react-i18next";
type Props = {
repository: Repository,
target: string,
source: string,
t: string => string
repository: Repository;
target: string;
source: string;
t: (p: string) => string;
};
class GitMergeInformation extends React.Component<Props> {
@@ -23,21 +22,15 @@ class GitMergeInformation extends React.Component<Props> {
</pre>
{t("scm-git-plugin.information.merge.update")}
<pre>
<code>
git pull
</code>
<code>git pull</code>
</pre>
{t("scm-git-plugin.information.merge.merge")}
<pre>
<code>
git merge {source}
</code>
<code>git merge {source}</code>
</pre>
{t("scm-git-plugin.information.merge.resolve")}
<pre>
<code>
git add &lt;conflict file&gt;
</code>
<code>git add &lt;conflict file&gt;</code>
</pre>
{t("scm-git-plugin.information.merge.commit")}
<pre>
@@ -47,9 +40,7 @@ class GitMergeInformation extends React.Component<Props> {
</pre>
{t("scm-git-plugin.information.merge.push")}
<pre>
<code>
git push
</code>
<code>git push</code>
</pre>
</div>
);

View File

@@ -1,7 +1,6 @@
//@flow
import React from "react";
import styled from "styled-components";
import type { Repository, Link } from "@scm-manager/ui-types";
import { Repository, Link } from "@scm-manager/ui-types";
import { ButtonAddons, Button } from "@scm-manager/ui-components";
import CloneInformation from "./CloneInformation";
@@ -16,17 +15,17 @@ const Switcher = styled(ButtonAddons)`
`;
type Props = {
repository: Repository
repository: Repository;
};
type State = {
selected?: Link
selected?: Link;
};
function selectHttpOrFirst(repository: Repository) {
const protocols = repository._links["protocol"] || [];
const protocols = (repository._links["protocol"] as Link[]) || [];
for (let protocol of protocols) {
for (const protocol of protocols) {
if (protocol.name === "http") {
return protocol;
}
@@ -55,7 +54,7 @@ export default class ProtocolInformation extends React.Component<Props, State> {
renderProtocolButton = (protocol: Link) => {
const name = protocol.name || "unknown";
let color = null;
let color;
const { selected } = this.state;
if (selected && protocol.name === selected.name) {
@@ -72,23 +71,19 @@ export default class ProtocolInformation extends React.Component<Props, State> {
render() {
const { repository } = this.props;
const protocols = repository._links["protocol"];
const protocols = repository._links["protocol"] as Link[];
if (!protocols || protocols.length === 0) {
return null;
}
if (protocols.length === 1) {
return (
<CloneInformation url={protocols[0].href} repository={repository} />
);
return <CloneInformation url={protocols[0].href} repository={repository} />;
}
const { selected } = this.state;
let cloneInformation = null;
if (selected) {
cloneInformation = (
<CloneInformation repository={repository} url={selected.href} />
);
cloneInformation = <CloneInformation repository={repository} url={selected.href} />;
}
return (

View File

@@ -1,31 +1,28 @@
// @flow
import React, { FormEvent } from "react";
import React from "react";
import {apiClient, BranchSelector, ErrorPage, Loading, Subtitle, SubmitButton} from "@scm-manager/ui-components";
import type {Branch, Repository} from "@scm-manager/ui-types";
import {translate} from "react-i18next";
import { apiClient, BranchSelector, ErrorPage, Loading, Subtitle, SubmitButton } from "@scm-manager/ui-components";
import { Branch, Repository, Link } from "@scm-manager/ui-types";
import { translate } from "react-i18next";
type Props = {
repository: Repository,
t: string => string
repository: Repository;
t: (p: string) => string;
};
type State = {
loadingBranches: boolean,
loadingDefaultBranch: boolean,
submitPending: boolean,
error?: Error,
branches: Branch[],
selectedBranchName?: string,
defaultBranchChanged: boolean,
disabled: boolean
loadingBranches: boolean;
loadingDefaultBranch: boolean;
submitPending: boolean;
error?: Error;
branches: Branch[];
selectedBranchName?: string;
defaultBranchChanged: boolean;
disabled: boolean;
};
const GIT_CONFIG_CONTENT_TYPE = "application/vnd.scmm-gitConfig+json";
class RepositoryConfig extends React.Component<Props, State> {
constructor(props: Props) {
super(props);
@@ -41,19 +38,36 @@ class RepositoryConfig extends React.Component<Props, State> {
componentDidMount() {
const { repository } = this.props;
this.setState({ ...this.state, loadingBranches: true });
this.setState({
...this.state,
loadingBranches: true
});
const branchesLink = repository._links.branches as Link;
apiClient
.get(repository._links.branches.href)
.get(branchesLink.href)
.then(response => response.json())
.then(payload => payload._embedded.branches)
.then(branches =>
this.setState({ ...this.state, branches, loadingBranches: false })
this.setState({
...this.state,
branches,
loadingBranches: false
})
)
.catch(error => this.setState({ ...this.state, error }));
.catch(error =>
this.setState({
...this.state,
error
})
);
this.setState({ ...this.state, loadingDefaultBranch: true });
const configurationLink = repository._links.configuration as Link;
this.setState({
...this.state,
loadingDefaultBranch: true
});
apiClient
.get(repository._links.configuration.href)
.get(configurationLink.href)
.then(response => response.json())
.then(payload =>
this.setState({
@@ -63,31 +77,44 @@ class RepositoryConfig extends React.Component<Props, State> {
loadingDefaultBranch: false
})
)
.catch(error => this.setState({ ...this.state, error }));
.catch(error =>
this.setState({
...this.state,
error
})
);
}
branchSelected = (branch: Branch) => {
branchSelected = (branch?: Branch) => {
if (!branch) {
this.setState({ ...this.state, selectedBranchName: undefined, defaultBranchChanged: false});
this.setState({
...this.state,
selectedBranchName: undefined,
defaultBranchChanged: false
});
return;
}
this.setState({ ...this.state, selectedBranchName: branch.name, defaultBranchChanged: false });
this.setState({
...this.state,
selectedBranchName: branch.name,
defaultBranchChanged: false
});
};
submit = (event: Event) => {
submit = (event: FormEvent) => {
event.preventDefault();
const { repository } = this.props;
const newConfig = {
defaultBranch: this.state.selectedBranchName
};
this.setState({ ...this.state, submitPending: true });
this.setState({
...this.state,
submitPending: true
});
const configurationLink = repository._links.configuration as Link;
apiClient
.put(
repository._links.configuration.href,
newConfig,
GIT_CONFIG_CONTENT_TYPE
)
.put(configurationLink.href, newConfig, GIT_CONFIG_CONTENT_TYPE)
.then(() =>
this.setState({
...this.state,
@@ -95,7 +122,12 @@ class RepositoryConfig extends React.Component<Props, State> {
defaultBranchChanged: true
})
)
.catch(error => this.setState({ ...this.state, error }));
.catch(error =>
this.setState({
...this.state,
error
})
);
};
render() {
@@ -112,17 +144,19 @@ class RepositoryConfig extends React.Component<Props, State> {
);
}
const submitButton = disabled? null: <SubmitButton
label={t("scm-git-plugin.repo-config.submit")}
loading={submitPending}
disabled={!this.state.selectedBranchName}
/>;
const submitButton = disabled ? null : (
<SubmitButton
label={t("scm-git-plugin.repo-config.submit")}
loading={submitPending}
disabled={!this.state.selectedBranchName}
/>
);
if (!(loadingBranches || loadingDefaultBranch)) {
return (
<>
<hr />
<Subtitle subtitle={t("scm-git-plugin.repo-config.title")}/>
<Subtitle subtitle={t("scm-git-plugin.repo-config.title")} />
{this.renderBranchChangedNotification()}
<form onSubmit={this.submit}>
<BranchSelector
@@ -132,7 +166,7 @@ class RepositoryConfig extends React.Component<Props, State> {
selectedBranch={this.state.selectedBranchName}
disabled={disabled}
/>
{ submitButton }
{submitButton}
</form>
</>
);
@@ -148,7 +182,10 @@ class RepositoryConfig extends React.Component<Props, State> {
<button
className="delete"
onClick={() =>
this.setState({ ...this.state, defaultBranchChanged: false })
this.setState({
...this.state,
defaultBranchChanged: false
})
}
/>
{this.props.t("scm-git-plugin.repo-config.success")}

View File

@@ -1,16 +0,0 @@
// @flow
import "@scm-manager/ui-tests/i18n";
import { gitPredicate } from "./index";
describe("test git predicate", () => {
it("should return false", () => {
expect(gitPredicate()).toBe(false);
expect(gitPredicate({})).toBe(false);
expect(gitPredicate({ repository: {} })).toBe(false);
expect(gitPredicate({ repository: { type: "hg" } })).toBe(false);
});
it("should return true", () => {
expect(gitPredicate({ repository: { type: "git" } })).toBe(true);
});
});

View File

@@ -0,0 +1,31 @@
import "@scm-manager/ui-tests/i18n";
import { gitPredicate } from "./index";
describe("test git predicate", () => {
it("should return false", () => {
expect(gitPredicate(undefined)).toBe(false);
expect(gitPredicate({})).toBe(false);
expect(
gitPredicate({
repository: {}
})
).toBe(false);
expect(
gitPredicate({
repository: {
type: "hg"
}
})
).toBe(false);
});
it("should return true", () => {
expect(
gitPredicate({
repository: {
type: "git"
}
})
).toBe(true);
});
});

View File

@@ -1,10 +1,9 @@
//@flow
import React from "react";
import {binder} from "@scm-manager/ui-extensions";
import { binder } from "@scm-manager/ui-extensions";
import ProtocolInformation from "./ProtocolInformation";
import GitAvatar from "./GitAvatar";
import {ConfigurationBinder as cfgBinder} from "@scm-manager/ui-components";
import { ConfigurationBinder as cfgBinder } from "@scm-manager/ui-components";
import GitGlobalConfiguration from "./GitGlobalConfiguration";
import GitBranchInformation from "./GitBranchInformation";
import GitMergeInformation from "./GitMergeInformation";
@@ -13,33 +12,16 @@ import RepositoryConfig from "./RepositoryConfig";
// repository
// @visibleForTesting
export const gitPredicate = (props: Object) => {
export const gitPredicate = (props: any) => {
return !!(props && props.repository && props.repository.type === "git");
};
binder.bind(
"repos.repository-details.information",
ProtocolInformation,
gitPredicate
);
binder.bind(
"repos.branch-details.information",
GitBranchInformation,
gitPredicate
);
binder.bind(
"repos.repository-merge.information",
GitMergeInformation,
gitPredicate
);
binder.bind("repos.repository-details.information", ProtocolInformation, gitPredicate);
binder.bind("repos.branch-details.information", GitBranchInformation, gitPredicate);
binder.bind("repos.repository-merge.information", GitMergeInformation, gitPredicate);
binder.bind("repos.repository-avatar", GitAvatar, gitPredicate);
binder.bind("repo-config.route", RepositoryConfig, gitPredicate);
// global config
cfgBinder.bindGlobal(
"/git",
"scm-git-plugin.config.link",
"gitConfig",
GitGlobalConfiguration
);
cfgBinder.bindGlobal("/git", "scm-git-plugin.config.link", "gitConfig", GitGlobalConfiguration);