mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-02 03:25:56 +01:00
Improve a11y (#1841)
Improve accessibility by removing unnecessary tags without hrefs. Also remove many eslint errors and warnings.
This commit is contained in:
4
gradle/changelog/improve_a11y.yaml
Normal file
4
gradle/changelog/improve_a11y.yaml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
- type: fixed
|
||||||
|
description: Fix <a> tags without hrefs ([#1841](https://github.com/scm-manager/scm-manager/pull/1841))
|
||||||
|
- type: fixed
|
||||||
|
description: Fix eslint errors and warnings ([#1841](https://github.com/scm-manager/scm-manager/pull/1841))
|
||||||
@@ -32,7 +32,7 @@ import {
|
|||||||
Loading,
|
Loading,
|
||||||
Subtitle,
|
Subtitle,
|
||||||
Level,
|
Level,
|
||||||
SubmitButton
|
SubmitButton,
|
||||||
} from "@scm-manager/ui-components";
|
} from "@scm-manager/ui-components";
|
||||||
|
|
||||||
type Props = WithTranslation & {
|
type Props = WithTranslation & {
|
||||||
@@ -67,40 +67,40 @@ class RepositoryConfig extends React.Component<Props, State> {
|
|||||||
nonFastForwardDisallowed: false,
|
nonFastForwardDisallowed: false,
|
||||||
changesSubmitted: false,
|
changesSubmitted: false,
|
||||||
disabled: true,
|
disabled: true,
|
||||||
changed: false
|
changed: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
const { repository } = this.props;
|
const { repository } = this.props;
|
||||||
this.setState({
|
this.setState({
|
||||||
loadingBranches: true
|
loadingBranches: true,
|
||||||
});
|
});
|
||||||
const branchesLink = repository._links.branches as Link;
|
const branchesLink = repository._links.branches as Link;
|
||||||
apiClient
|
apiClient
|
||||||
.get(branchesLink.href)
|
.get(branchesLink.href)
|
||||||
.then(response => response.json())
|
.then((response) => response.json())
|
||||||
.then(payload => payload._embedded.branches)
|
.then((payload) => payload._embedded.branches)
|
||||||
.then(branches =>
|
.then((branches) =>
|
||||||
this.setState({
|
this.setState({
|
||||||
branches,
|
branches,
|
||||||
loadingBranches: false
|
loadingBranches: false,
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
.catch(error =>
|
.catch((error) =>
|
||||||
this.setState({
|
this.setState({
|
||||||
error
|
error,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
const configurationLink = repository._links.configuration as Link;
|
const configurationLink = repository._links.configuration as Link;
|
||||||
this.setState({
|
this.setState({
|
||||||
loadingDefaultBranch: true
|
loadingDefaultBranch: true,
|
||||||
});
|
});
|
||||||
apiClient
|
apiClient
|
||||||
.get(configurationLink.href)
|
.get(configurationLink.href)
|
||||||
.then(response => response.json())
|
.then((response) => response.json())
|
||||||
.then(payload => {
|
.then((payload) => {
|
||||||
const defaultBranch =
|
const defaultBranch =
|
||||||
payload.defaultBranch || this.state.branches?.filter((b: Branch) => b.defaultBranch)[0]?.name;
|
payload.defaultBranch || this.state.branches?.filter((b: Branch) => b.defaultBranch)[0]?.name;
|
||||||
this.setState({
|
this.setState({
|
||||||
@@ -108,12 +108,12 @@ class RepositoryConfig extends React.Component<Props, State> {
|
|||||||
nonFastForwardDisallowed: payload.nonFastForwardDisallowed,
|
nonFastForwardDisallowed: payload.nonFastForwardDisallowed,
|
||||||
disabled: !payload._links.update,
|
disabled: !payload._links.update,
|
||||||
loadingDefaultBranch: false,
|
loadingDefaultBranch: false,
|
||||||
changed: false
|
changed: false,
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch(error =>
|
.catch((error) =>
|
||||||
this.setState({
|
this.setState({
|
||||||
error
|
error,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -123,13 +123,13 @@ class RepositoryConfig extends React.Component<Props, State> {
|
|||||||
this.setState({
|
this.setState({
|
||||||
selectedBranchName: "",
|
selectedBranchName: "",
|
||||||
changesSubmitted: false,
|
changesSubmitted: false,
|
||||||
changed: true
|
changed: true,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.setState({
|
this.setState({
|
||||||
selectedBranchName: branch.name,
|
selectedBranchName: branch.name,
|
||||||
changesSubmitted: false,
|
changesSubmitted: false,
|
||||||
changed: true
|
changed: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -137,7 +137,7 @@ class RepositoryConfig extends React.Component<Props, State> {
|
|||||||
onNonFastForwardDisallowed = (value: boolean) => {
|
onNonFastForwardDisallowed = (value: boolean) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
nonFastForwardDisallowed: value,
|
nonFastForwardDisallowed: value,
|
||||||
changed: true
|
changed: true,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -148,10 +148,10 @@ class RepositoryConfig extends React.Component<Props, State> {
|
|||||||
const { selectedBranchName, nonFastForwardDisallowed } = this.state;
|
const { selectedBranchName, nonFastForwardDisallowed } = this.state;
|
||||||
const newConfig = {
|
const newConfig = {
|
||||||
defaultBranch: selectedBranchName,
|
defaultBranch: selectedBranchName,
|
||||||
nonFastForwardDisallowed
|
nonFastForwardDisallowed,
|
||||||
};
|
};
|
||||||
this.setState({
|
this.setState({
|
||||||
submitPending: true
|
submitPending: true,
|
||||||
});
|
});
|
||||||
const configurationLink = repository._links.configuration as Link;
|
const configurationLink = repository._links.configuration as Link;
|
||||||
apiClient
|
apiClient
|
||||||
@@ -160,12 +160,12 @@ class RepositoryConfig extends React.Component<Props, State> {
|
|||||||
this.setState({
|
this.setState({
|
||||||
submitPending: false,
|
submitPending: false,
|
||||||
changesSubmitted: true,
|
changesSubmitted: true,
|
||||||
changed: false
|
changed: false,
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
.catch(error =>
|
.catch((error) =>
|
||||||
this.setState({
|
this.setState({
|
||||||
error
|
error,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@@ -233,7 +233,7 @@ class RepositoryConfig extends React.Component<Props, State> {
|
|||||||
onClick={() =>
|
onClick={() =>
|
||||||
this.setState({
|
this.setState({
|
||||||
changesSubmitted: false,
|
changesSubmitted: false,
|
||||||
changed: false
|
changed: false,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -31,14 +31,14 @@ describe("test git predicate", () => {
|
|||||||
expect(gitPredicate({})).toBe(false);
|
expect(gitPredicate({})).toBe(false);
|
||||||
expect(
|
expect(
|
||||||
gitPredicate({
|
gitPredicate({
|
||||||
repository: {}
|
repository: {},
|
||||||
})
|
})
|
||||||
).toBe(false);
|
).toBe(false);
|
||||||
expect(
|
expect(
|
||||||
gitPredicate({
|
gitPredicate({
|
||||||
repository: {
|
repository: {
|
||||||
type: "hg"
|
type: "hg",
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
).toBe(false);
|
).toBe(false);
|
||||||
});
|
});
|
||||||
@@ -47,8 +47,8 @@ describe("test git predicate", () => {
|
|||||||
expect(
|
expect(
|
||||||
gitPredicate({
|
gitPredicate({
|
||||||
repository: {
|
repository: {
|
||||||
type: "git"
|
type: "git",
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
).toBe(true);
|
).toBe(true);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ class HgConfigurationForm extends React.Component<Props, State> {
|
|||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
...props.initialConfiguration,
|
...props.initialConfiguration,
|
||||||
validationErrors: []
|
validationErrors: [],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,7 +66,7 @@ class HgConfigurationForm extends React.Component<Props, State> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
validationErrors
|
validationErrors,
|
||||||
});
|
});
|
||||||
|
|
||||||
return validationErrors.length === 0;
|
return validationErrors.length === 0;
|
||||||
@@ -83,7 +83,7 @@ class HgConfigurationForm extends React.Component<Props, State> {
|
|||||||
this.setState(
|
this.setState(
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
{
|
{
|
||||||
[name]: value
|
[name]: value,
|
||||||
},
|
},
|
||||||
() => this.props.onConfigurationChange(this.state, this.updateValidationStatus())
|
() => this.props.onConfigurationChange(this.state, this.updateValidationStatus())
|
||||||
);
|
);
|
||||||
@@ -99,7 +99,7 @@ class HgConfigurationForm extends React.Component<Props, State> {
|
|||||||
.then(() =>
|
.then(() =>
|
||||||
apiClient
|
apiClient
|
||||||
.get((this.props.initialConfiguration._links.self as Link).href)
|
.get((this.props.initialConfiguration._links.self as Link).href)
|
||||||
.then(r => r.json())
|
.then((r) => r.json())
|
||||||
.then((config: Configuration) => this.setState({ hgBinary: config.hgBinary }))
|
.then((config: Configuration) => this.setState({ hgBinary: config.hgBinary }))
|
||||||
)
|
)
|
||||||
.then(() => this.updateValidationStatus());
|
.then(() => this.updateValidationStatus());
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ const HgRepositoryConfigurationForm: FC<Props> = ({ repository }) => {
|
|||||||
const encoding = value ? value : undefined;
|
const encoding = value ? value : undefined;
|
||||||
setConfiguration({
|
setConfiguration({
|
||||||
...configuration,
|
...configuration,
|
||||||
encoding
|
encoding,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -41,11 +41,11 @@ export const useHgRepositoryConfiguration = (repository: Repository) => {
|
|||||||
setLoading(true);
|
setLoading(true);
|
||||||
apiClient
|
apiClient
|
||||||
.get(link)
|
.get(link)
|
||||||
.then(response => response.json())
|
.then((response) => response.json())
|
||||||
.then((config: HgRepositoryConfiguration) => {
|
.then((config: HgRepositoryConfiguration) => {
|
||||||
setData(config);
|
setData(config);
|
||||||
})
|
})
|
||||||
.catch(e => setError(e))
|
.catch((e) => setError(e))
|
||||||
.finally(() => setLoading(false));
|
.finally(() => setLoading(false));
|
||||||
}
|
}
|
||||||
}, [link]);
|
}, [link]);
|
||||||
@@ -53,7 +53,7 @@ export const useHgRepositoryConfiguration = (repository: Repository) => {
|
|||||||
return {
|
return {
|
||||||
isLoading,
|
isLoading,
|
||||||
error,
|
error,
|
||||||
data
|
data,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -73,7 +73,7 @@ export const useUpdateHgRepositoryConfiguration = () => {
|
|||||||
apiClient
|
apiClient
|
||||||
.put(link, configuration, "application/vnd.scmm-hgConfig-repo+json;v=2")
|
.put(link, configuration, "application/vnd.scmm-hgConfig-repo+json;v=2")
|
||||||
.then(() => setUpdated(true))
|
.then(() => setUpdated(true))
|
||||||
.catch(e => setError(e))
|
.catch((e) => setError(e))
|
||||||
.finally(() => setLoading(false));
|
.finally(() => setLoading(false));
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -81,6 +81,6 @@ export const useUpdateHgRepositoryConfiguration = () => {
|
|||||||
isLoading,
|
isLoading,
|
||||||
error,
|
error,
|
||||||
update,
|
update,
|
||||||
updated
|
updated,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ class SvnConfigurationForm extends React.Component<Props, State> {
|
|||||||
constructor(props: Props) {
|
constructor(props: Props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
...props.initialConfiguration
|
...props.initialConfiguration,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,7 +56,7 @@ class SvnConfigurationForm extends React.Component<Props, State> {
|
|||||||
this.setState(
|
this.setState(
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
{
|
{
|
||||||
[name]: value
|
[name]: value,
|
||||||
},
|
},
|
||||||
() => this.props.onConfigurationChange(this.state, true)
|
() => this.props.onConfigurationChange(this.state, true)
|
||||||
);
|
);
|
||||||
@@ -73,7 +73,7 @@ class SvnConfigurationForm extends React.Component<Props, State> {
|
|||||||
compatibilityOption = (value: string) => {
|
compatibilityOption = (value: string) => {
|
||||||
return {
|
return {
|
||||||
value,
|
value,
|
||||||
label: this.props.t("scm-svn-plugin.config.compatibility-values." + value.toLowerCase())
|
label: this.props.t("scm-svn-plugin.config.compatibility-values." + value.toLowerCase()),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ describe("ApiProvider tests", () => {
|
|||||||
|
|
||||||
it("should register QueryClient", () => {
|
it("should register QueryClient", () => {
|
||||||
const { result } = renderHook(() => useQueryClient(), {
|
const { result } = renderHook(() => useQueryClient(), {
|
||||||
wrapper: createWrapper()
|
wrapper: createWrapper(),
|
||||||
});
|
});
|
||||||
expect(result.current).toBeDefined();
|
expect(result.current).toBeDefined();
|
||||||
});
|
});
|
||||||
@@ -48,7 +48,7 @@ describe("ApiProvider tests", () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const { result } = renderHook(() => useLegacyContext(), {
|
const { result } = renderHook(() => useLegacyContext(), {
|
||||||
wrapper: createWrapper({ onIndexFetched })
|
wrapper: createWrapper({ onIndexFetched }),
|
||||||
});
|
});
|
||||||
|
|
||||||
if (result.current?.onIndexFetched) {
|
if (result.current?.onIndexFetched) {
|
||||||
|
|||||||
@@ -31,9 +31,9 @@ import { reset } from "./reset";
|
|||||||
const queryClient = new QueryClient({
|
const queryClient = new QueryClient({
|
||||||
defaultOptions: {
|
defaultOptions: {
|
||||||
queries: {
|
queries: {
|
||||||
retry: false
|
retry: false,
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
type Props = LegacyContext & {
|
type Props = LegacyContext & {
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ describe("LegacyContext tests", () => {
|
|||||||
|
|
||||||
it("should return provided context", () => {
|
it("should return provided context", () => {
|
||||||
const { result } = renderHook(() => useLegacyContext(), {
|
const { result } = renderHook(() => useLegacyContext(), {
|
||||||
wrapper: createWrapper()
|
wrapper: createWrapper(),
|
||||||
});
|
});
|
||||||
expect(result.current).toBeDefined();
|
expect(result.current).toBeDefined();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ describe("Test admin hooks", () => {
|
|||||||
it("should get update info", async () => {
|
it("should get update info", async () => {
|
||||||
const updateInfo: UpdateInfo = {
|
const updateInfo: UpdateInfo = {
|
||||||
latestVersion: "x.y.z",
|
latestVersion: "x.y.z",
|
||||||
link: "http://heartofgold@hitchhiker.com/x.y.z"
|
link: "http://heartofgold@hitchhiker.com/x.y.z",
|
||||||
};
|
};
|
||||||
fetchMock.getOnce("/api/v2/updateInfo", updateInfo);
|
fetchMock.getOnce("/api/v2/updateInfo", updateInfo);
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ describe("Test admin hooks", () => {
|
|||||||
setIndexLink(queryClient, "updateInfo", "/updateInfo");
|
setIndexLink(queryClient, "updateInfo", "/updateInfo");
|
||||||
|
|
||||||
const { result, waitFor } = renderHook(() => useUpdateInfo(), {
|
const { result, waitFor } = renderHook(() => useUpdateInfo(), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
await waitFor(() => {
|
await waitFor(() => {
|
||||||
return !!result.current.data;
|
return !!result.current.data;
|
||||||
|
|||||||
@@ -45,9 +45,9 @@ describe("error handling tests", () => {
|
|||||||
context: [
|
context: [
|
||||||
{
|
{
|
||||||
type: "planet",
|
type: "planet",
|
||||||
id: "earth"
|
id: "earth",
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
@@ -55,9 +55,9 @@ describe("error handling tests", () => {
|
|||||||
fetchMock.restore();
|
fetchMock.restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should create a normal error, if the content type is not scmm-error", done => {
|
it("should create a normal error, if the content type is not scmm-error", (done) => {
|
||||||
fetchMock.getOnce("/api/v2/error", {
|
fetchMock.getOnce("/api/v2/error", {
|
||||||
status: 404
|
status: 404,
|
||||||
});
|
});
|
||||||
|
|
||||||
apiClient.get("/error").catch((err: Error) => {
|
apiClient.get("/error").catch((err: Error) => {
|
||||||
@@ -67,13 +67,13 @@ describe("error handling tests", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should create an backend error, if the content type is scmm-error", done => {
|
it("should create an backend error, if the content type is scmm-error", (done) => {
|
||||||
fetchMock.getOnce("/api/v2/error", {
|
fetchMock.getOnce("/api/v2/error", {
|
||||||
status: 404,
|
status: 404,
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/vnd.scmm-error+json;v=2"
|
"Content-Type": "application/vnd.scmm-error+json;v=2",
|
||||||
},
|
},
|
||||||
body: earthNotFoundError
|
body: earthNotFoundError,
|
||||||
});
|
});
|
||||||
|
|
||||||
apiClient.get("/error").catch((err: BackendError) => {
|
apiClient.get("/error").catch((err: BackendError) => {
|
||||||
@@ -87,8 +87,8 @@ describe("error handling tests", () => {
|
|||||||
expect(err.context).toEqual([
|
expect(err.context).toEqual([
|
||||||
{
|
{
|
||||||
type: "planet",
|
type: "planet",
|
||||||
id: "earth"
|
id: "earth",
|
||||||
}
|
},
|
||||||
]);
|
]);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ import {
|
|||||||
isBackendError,
|
isBackendError,
|
||||||
TOKEN_EXPIRED_ERROR_CODE,
|
TOKEN_EXPIRED_ERROR_CODE,
|
||||||
TokenExpiredError,
|
TokenExpiredError,
|
||||||
UnauthorizedError
|
UnauthorizedError,
|
||||||
} from "./errors";
|
} from "./errors";
|
||||||
|
|
||||||
type SubscriptionEvent = {
|
type SubscriptionEvent = {
|
||||||
@@ -62,12 +62,7 @@ type SubscriptionArgument = MessageListeners | SubscriptionContext;
|
|||||||
|
|
||||||
type Cancel = () => void;
|
type Cancel = () => void;
|
||||||
|
|
||||||
const sessionId = (
|
const sessionId = (Date.now().toString(36) + Math.random().toString(36).substr(2, 5)).toUpperCase();
|
||||||
Date.now().toString(36) +
|
|
||||||
Math.random()
|
|
||||||
.toString(36)
|
|
||||||
.substr(2, 5)
|
|
||||||
).toUpperCase();
|
|
||||||
|
|
||||||
const extractXsrfTokenFromJwt = (jwt: string) => {
|
const extractXsrfTokenFromJwt = (jwt: string) => {
|
||||||
const parts = jwt.split(".");
|
const parts = jwt.split(".");
|
||||||
@@ -102,7 +97,7 @@ const createRequestHeaders = () => {
|
|||||||
// identify the web interface
|
// identify the web interface
|
||||||
"X-SCM-Client": "WUI",
|
"X-SCM-Client": "WUI",
|
||||||
// identify the window session
|
// identify the window session
|
||||||
"X-SCM-Session-ID": sessionId
|
"X-SCM-Session-ID": sessionId,
|
||||||
};
|
};
|
||||||
|
|
||||||
const xsrf = extractXsrfToken();
|
const xsrf = extractXsrfToken();
|
||||||
@@ -112,10 +107,10 @@ const createRequestHeaders = () => {
|
|||||||
return headers;
|
return headers;
|
||||||
};
|
};
|
||||||
|
|
||||||
const applyFetchOptions: (p: RequestInit) => RequestInit = o => {
|
const applyFetchOptions: (p: RequestInit) => RequestInit = (o) => {
|
||||||
if (o.headers) {
|
if (o.headers) {
|
||||||
o.headers = {
|
o.headers = {
|
||||||
...createRequestHeaders()
|
...createRequestHeaders(),
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
o.headers = createRequestHeaders();
|
o.headers = createRequestHeaders();
|
||||||
@@ -174,9 +169,7 @@ class ApiClient {
|
|||||||
requestListeners: RequestListener[] = [];
|
requestListeners: RequestListener[] = [];
|
||||||
|
|
||||||
get = (url: string): Promise<Response> => {
|
get = (url: string): Promise<Response> => {
|
||||||
return this.request(url, applyFetchOptions({}))
|
return this.request(url, applyFetchOptions({})).then(handleFailure).catch(this.notifyAndRethrow);
|
||||||
.then(handleFailure)
|
|
||||||
.catch(this.notifyAndRethrow);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
post = (
|
post = (
|
||||||
@@ -203,7 +196,7 @@ class ApiClient {
|
|||||||
const options: RequestInit = {
|
const options: RequestInit = {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: formData,
|
body: formData,
|
||||||
headers: additionalHeaders
|
headers: additionalHeaders,
|
||||||
};
|
};
|
||||||
return this.httpRequestWithBinaryBody(options, url);
|
return this.httpRequestWithBinaryBody(options, url);
|
||||||
};
|
};
|
||||||
@@ -214,22 +207,18 @@ class ApiClient {
|
|||||||
|
|
||||||
head = (url: string) => {
|
head = (url: string) => {
|
||||||
let options: RequestInit = {
|
let options: RequestInit = {
|
||||||
method: "HEAD"
|
method: "HEAD",
|
||||||
};
|
};
|
||||||
options = applyFetchOptions(options);
|
options = applyFetchOptions(options);
|
||||||
return this.request(url, options)
|
return this.request(url, options).then(handleFailure).catch(this.notifyAndRethrow);
|
||||||
.then(handleFailure)
|
|
||||||
.catch(this.notifyAndRethrow);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
delete = (url: string): Promise<Response> => {
|
delete = (url: string): Promise<Response> => {
|
||||||
let options: RequestInit = {
|
let options: RequestInit = {
|
||||||
method: "DELETE"
|
method: "DELETE",
|
||||||
};
|
};
|
||||||
options = applyFetchOptions(options);
|
options = applyFetchOptions(options);
|
||||||
return this.request(url, options)
|
return this.request(url, options).then(handleFailure).catch(this.notifyAndRethrow);
|
||||||
.then(handleFailure)
|
|
||||||
.catch(this.notifyAndRethrow);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
httpRequestWithJSONBody = (
|
httpRequestWithJSONBody = (
|
||||||
@@ -241,7 +230,7 @@ class ApiClient {
|
|||||||
): Promise<Response> => {
|
): Promise<Response> => {
|
||||||
const options: RequestInit = {
|
const options: RequestInit = {
|
||||||
method: method,
|
method: method,
|
||||||
headers: additionalHeaders
|
headers: additionalHeaders,
|
||||||
};
|
};
|
||||||
if (payload) {
|
if (payload) {
|
||||||
options.body = JSON.stringify(payload);
|
options.body = JSON.stringify(payload);
|
||||||
@@ -257,7 +246,7 @@ class ApiClient {
|
|||||||
) => {
|
) => {
|
||||||
const options: RequestInit = {
|
const options: RequestInit = {
|
||||||
method: method,
|
method: method,
|
||||||
headers: additionalHeaders
|
headers: additionalHeaders,
|
||||||
};
|
};
|
||||||
options.body = payload;
|
options.body = payload;
|
||||||
return this.httpRequestWithBinaryBody(options, url, "text/plain");
|
return this.httpRequestWithBinaryBody(options, url, "text/plain");
|
||||||
@@ -273,14 +262,12 @@ class ApiClient {
|
|||||||
options.headers["Content-Type"] = contentType;
|
options.headers["Content-Type"] = contentType;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.request(url, options)
|
return this.request(url, options).then(handleFailure).catch(this.notifyAndRethrow);
|
||||||
.then(handleFailure)
|
|
||||||
.catch(this.notifyAndRethrow);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
subscribe(url: string, argument: SubscriptionArgument): Cancel {
|
subscribe(url: string, argument: SubscriptionArgument): Cancel {
|
||||||
const es = new EventSource(createUrlWithIdentifiers(url), {
|
const es = new EventSource(createUrlWithIdentifiers(url), {
|
||||||
withCredentials: true
|
withCredentials: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
let listeners: MessageListeners;
|
let listeners: MessageListeners;
|
||||||
@@ -321,11 +308,11 @@ class ApiClient {
|
|||||||
};
|
};
|
||||||
|
|
||||||
private notifyRequestListeners = (url: string, options: RequestInit) => {
|
private notifyRequestListeners = (url: string, options: RequestInit) => {
|
||||||
this.requestListeners.forEach(requestListener => requestListener(url, options));
|
this.requestListeners.forEach((requestListener) => requestListener(url, options));
|
||||||
};
|
};
|
||||||
|
|
||||||
private notifyAndRethrow = (error: Error): never => {
|
private notifyAndRethrow = (error: Error): never => {
|
||||||
this.errorListeners.forEach(errorListener => errorListener(error));
|
this.errorListeners.forEach((errorListener) => errorListener(error));
|
||||||
throw error;
|
throw error;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ describe("Test base api hooks", () => {
|
|||||||
describe("useIndex tests", () => {
|
describe("useIndex tests", () => {
|
||||||
fetchMock.get("/api/v2/", {
|
fetchMock.get("/api/v2/", {
|
||||||
version: "x.y.z",
|
version: "x.y.z",
|
||||||
_links: {}
|
_links: {},
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should return index", async () => {
|
it("should return index", async () => {
|
||||||
@@ -48,9 +48,9 @@ describe("Test base api hooks", () => {
|
|||||||
it("should call onIndexFetched of LegacyContext", async () => {
|
it("should call onIndexFetched of LegacyContext", async () => {
|
||||||
let index: IndexResources;
|
let index: IndexResources;
|
||||||
const context: LegacyContext = {
|
const context: LegacyContext = {
|
||||||
onIndexFetched: fetchedIndex => {
|
onIndexFetched: (fetchedIndex) => {
|
||||||
index = fetchedIndex;
|
index = fetchedIndex;
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
const { result, waitFor } = renderHook(() => useIndex(), { wrapper: createWrapper(context) });
|
const { result, waitFor } = renderHook(() => useIndex(), { wrapper: createWrapper(context) });
|
||||||
await waitFor(() => {
|
await waitFor(() => {
|
||||||
@@ -70,10 +70,10 @@ describe("Test base api hooks", () => {
|
|||||||
const queryClient = new QueryClient();
|
const queryClient = new QueryClient();
|
||||||
queryClient.setQueryData("index", {
|
queryClient.setQueryData("index", {
|
||||||
version: "x.y.z",
|
version: "x.y.z",
|
||||||
_links: {}
|
_links: {},
|
||||||
});
|
});
|
||||||
const { result } = renderHook(() => useIndexLink("spaceships"), {
|
const { result } = renderHook(() => useIndexLink("spaceships"), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
expect(result.current).toBeUndefined();
|
expect(result.current).toBeUndefined();
|
||||||
});
|
});
|
||||||
@@ -86,17 +86,17 @@ describe("Test base api hooks", () => {
|
|||||||
spaceships: [
|
spaceships: [
|
||||||
{
|
{
|
||||||
name: "heartOfGold",
|
name: "heartOfGold",
|
||||||
href: "/spaceships/heartOfGold"
|
href: "/spaceships/heartOfGold",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "razorCrest",
|
name: "razorCrest",
|
||||||
href: "/spaceships/razorCrest"
|
href: "/spaceships/razorCrest",
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
const { result } = renderHook(() => useIndexLink("spaceships"), {
|
const { result } = renderHook(() => useIndexLink("spaceships"), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
expect(result.current).toBeUndefined();
|
expect(result.current).toBeUndefined();
|
||||||
});
|
});
|
||||||
@@ -107,12 +107,12 @@ describe("Test base api hooks", () => {
|
|||||||
version: "x.y.z",
|
version: "x.y.z",
|
||||||
_links: {
|
_links: {
|
||||||
spaceships: {
|
spaceships: {
|
||||||
href: "/api/spaceships"
|
href: "/api/spaceships",
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
const { result } = renderHook(() => useIndexLink("spaceships"), {
|
const { result } = renderHook(() => useIndexLink("spaceships"), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
expect(result.current).toBe("/api/spaceships");
|
expect(result.current).toBe("/api/spaceships");
|
||||||
});
|
});
|
||||||
@@ -130,12 +130,12 @@ describe("Test base api hooks", () => {
|
|||||||
version: "x.y.z",
|
version: "x.y.z",
|
||||||
_links: {
|
_links: {
|
||||||
spaceships: {
|
spaceships: {
|
||||||
href: "/api/spaceships"
|
href: "/api/spaceships",
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
const { result } = renderHook(() => useIndexLinks(), {
|
const { result } = renderHook(() => useIndexLinks(), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
expect((result.current!.spaceships as Link).href).toBe("/api/spaceships");
|
expect((result.current!.spaceships as Link).href).toBe("/api/spaceships");
|
||||||
});
|
});
|
||||||
@@ -150,10 +150,10 @@ describe("Test base api hooks", () => {
|
|||||||
it("should return version", () => {
|
it("should return version", () => {
|
||||||
const queryClient = new QueryClient();
|
const queryClient = new QueryClient();
|
||||||
queryClient.setQueryData("index", {
|
queryClient.setQueryData("index", {
|
||||||
version: "x.y.z"
|
version: "x.y.z",
|
||||||
});
|
});
|
||||||
const { result } = renderHook(() => useVersion(), {
|
const { result } = renderHook(() => useVersion(), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
expect(result.current).toBe("x.y.z");
|
expect(result.current).toBe("x.y.z");
|
||||||
});
|
});
|
||||||
@@ -164,10 +164,10 @@ describe("Test base api hooks", () => {
|
|||||||
const queryClient = new QueryClient();
|
const queryClient = new QueryClient();
|
||||||
queryClient.setQueryData("index", {
|
queryClient.setQueryData("index", {
|
||||||
version: "x.y.z",
|
version: "x.y.z",
|
||||||
_links: {}
|
_links: {},
|
||||||
});
|
});
|
||||||
const { result } = renderHook(() => useRequiredIndexLink("spaceships"), {
|
const { result } = renderHook(() => useRequiredIndexLink("spaceships"), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
expect(result.error).toBeDefined();
|
expect(result.error).toBeDefined();
|
||||||
});
|
});
|
||||||
@@ -178,12 +178,12 @@ describe("Test base api hooks", () => {
|
|||||||
version: "x.y.z",
|
version: "x.y.z",
|
||||||
_links: {
|
_links: {
|
||||||
spaceships: {
|
spaceships: {
|
||||||
href: "/api/spaceships"
|
href: "/api/spaceships",
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
const { result } = renderHook(() => useRequiredIndexLink("spaceships"), {
|
const { result } = renderHook(() => useRequiredIndexLink("spaceships"), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
expect(result.current).toBe("/api/spaceships");
|
expect(result.current).toBe("/api/spaceships");
|
||||||
});
|
});
|
||||||
@@ -196,19 +196,19 @@ describe("Test base api hooks", () => {
|
|||||||
version: "x.y.z",
|
version: "x.y.z",
|
||||||
_links: {
|
_links: {
|
||||||
spaceships: {
|
spaceships: {
|
||||||
href: "/spaceships"
|
href: "/spaceships",
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const spaceship = {
|
const spaceship = {
|
||||||
name: "heartOfGold"
|
name: "heartOfGold",
|
||||||
};
|
};
|
||||||
|
|
||||||
fetchMock.get("/api/v2/spaceships", spaceship);
|
fetchMock.get("/api/v2/spaceships", spaceship);
|
||||||
|
|
||||||
const { result, waitFor } = renderHook(() => useIndexJsonResource<typeof spaceship>("spaceships"), {
|
const { result, waitFor } = renderHook(() => useIndexJsonResource<typeof spaceship>("spaceships"), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
|
|
||||||
await waitFor(() => {
|
await waitFor(() => {
|
||||||
@@ -223,11 +223,11 @@ describe("Test base api hooks", () => {
|
|||||||
const queryClient = new QueryClient();
|
const queryClient = new QueryClient();
|
||||||
queryClient.setQueryData("index", {
|
queryClient.setQueryData("index", {
|
||||||
version: "x.y.z",
|
version: "x.y.z",
|
||||||
_links: {}
|
_links: {},
|
||||||
});
|
});
|
||||||
|
|
||||||
const { result } = renderHook(() => useIndexJsonResource<{}>("spaceships"), {
|
const { result } = renderHook(() => useIndexJsonResource<{}>("spaceships"), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(result.current.isLoading).toBe(false);
|
expect(result.current.isLoading).toBe(false);
|
||||||
|
|||||||
@@ -60,9 +60,9 @@ describe("Test config hooks", () => {
|
|||||||
skipFailedAuthenticators: false,
|
skipFailedAuthenticators: false,
|
||||||
_links: {
|
_links: {
|
||||||
update: {
|
update: {
|
||||||
href: "/config"
|
href: "/config",
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
@@ -75,7 +75,7 @@ describe("Test config hooks", () => {
|
|||||||
setIndexLink(queryClient, "config", "/config");
|
setIndexLink(queryClient, "config", "/config");
|
||||||
fetchMock.get("/api/v2/config", config);
|
fetchMock.get("/api/v2/config", config);
|
||||||
const { result, waitFor } = renderHook(() => useConfig(), {
|
const { result, waitFor } = renderHook(() => useConfig(), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
await waitFor(() => !!result.current.data);
|
await waitFor(() => !!result.current.data);
|
||||||
expect(result.current.data).toEqual(config);
|
expect(result.current.data).toEqual(config);
|
||||||
@@ -89,15 +89,15 @@ describe("Test config hooks", () => {
|
|||||||
|
|
||||||
const newConfig = {
|
const newConfig = {
|
||||||
...config,
|
...config,
|
||||||
baseUrl: "/hog"
|
baseUrl: "/hog",
|
||||||
};
|
};
|
||||||
|
|
||||||
fetchMock.putOnce("/api/v2/config", {
|
fetchMock.putOnce("/api/v2/config", {
|
||||||
status: 200
|
status: 200,
|
||||||
});
|
});
|
||||||
|
|
||||||
const { result, waitForNextUpdate } = renderHook(() => useUpdateConfig(), {
|
const { result, waitForNextUpdate } = renderHook(() => useUpdateConfig(), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
|
|
||||||
await act(() => {
|
await act(() => {
|
||||||
|
|||||||
@@ -30,20 +30,20 @@ import { requiredLink } from "./links";
|
|||||||
|
|
||||||
export const useConfig = (): ApiResult<Config> => {
|
export const useConfig = (): ApiResult<Config> => {
|
||||||
const indexLink = useIndexLink("config");
|
const indexLink = useIndexLink("config");
|
||||||
return useQuery<Config, Error>("config", () => apiClient.get(indexLink!).then(response => response.json()), {
|
return useQuery<Config, Error>("config", () => apiClient.get(indexLink!).then((response) => response.json()), {
|
||||||
enabled: !!indexLink
|
enabled: !!indexLink,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useUpdateConfig = () => {
|
export const useUpdateConfig = () => {
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
const { mutate, isLoading, error, data, reset } = useMutation<unknown, Error, Config>(
|
const { mutate, isLoading, error, data, reset } = useMutation<unknown, Error, Config>(
|
||||||
config => {
|
(config) => {
|
||||||
const updateUrl = requiredLink(config, "update");
|
const updateUrl = requiredLink(config, "update");
|
||||||
return apiClient.put(updateUrl, config, "application/vnd.scmm-config+json;v=2");
|
return apiClient.put(updateUrl, config, "application/vnd.scmm-config+json;v=2");
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
onSuccess: () => queryClient.invalidateQueries("config")
|
onSuccess: () => queryClient.invalidateQueries("config"),
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
return {
|
return {
|
||||||
@@ -51,6 +51,6 @@ export const useUpdateConfig = () => {
|
|||||||
isLoading,
|
isLoading,
|
||||||
error,
|
error,
|
||||||
isUpdated: !!data,
|
isUpdated: !!data,
|
||||||
reset
|
reset,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -50,26 +50,25 @@ describe("Test diff", () => {
|
|||||||
content: "0",
|
content: "0",
|
||||||
type: "insert",
|
type: "insert",
|
||||||
lineNumber: 1,
|
lineNumber: 1,
|
||||||
isInsert: true
|
isInsert: true,
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
_links: {
|
_links: {
|
||||||
lines: {
|
lines: {
|
||||||
href:
|
href: "/api/v2/repositories/scmadmin/HeartOfGold-git/content/one_to_onehundred/0.txt?start={start}&end={end}",
|
||||||
"/api/v2/repositories/scmadmin/HeartOfGold-git/content/one_to_onehundred/0.txt?start={start}&end={end}",
|
templated: true,
|
||||||
templated: true
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
|
||||||
],
|
],
|
||||||
partial: false,
|
partial: false,
|
||||||
_links: {
|
_links: {
|
||||||
self: {
|
self: {
|
||||||
href: "/api/v2/diff"
|
href: "/api/v2/diff",
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const partialDiff1: Diff = {
|
const partialDiff1: Diff = {
|
||||||
@@ -93,29 +92,28 @@ describe("Test diff", () => {
|
|||||||
content: "0",
|
content: "0",
|
||||||
type: "insert",
|
type: "insert",
|
||||||
lineNumber: 1,
|
lineNumber: 1,
|
||||||
isInsert: true
|
isInsert: true,
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
_links: {
|
_links: {
|
||||||
lines: {
|
lines: {
|
||||||
href:
|
href: "/api/v2/repositories/scmadmin/HeartOfGold-git/content/one_to_onehundred/0.txt?start={start}&end={end}",
|
||||||
"/api/v2/repositories/scmadmin/HeartOfGold-git/content/one_to_onehundred/0.txt?start={start}&end={end}",
|
templated: true,
|
||||||
templated: true
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
|
||||||
],
|
],
|
||||||
partial: true,
|
partial: true,
|
||||||
_links: {
|
_links: {
|
||||||
self: {
|
self: {
|
||||||
href: "/diff"
|
href: "/diff",
|
||||||
},
|
},
|
||||||
next: {
|
next: {
|
||||||
href: "/diff?offset=1&limit=1"
|
href: "/diff?offset=1&limit=1",
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const partialDiff2: Diff = {
|
const partialDiff2: Diff = {
|
||||||
@@ -139,26 +137,25 @@ describe("Test diff", () => {
|
|||||||
content: "1",
|
content: "1",
|
||||||
type: "insert",
|
type: "insert",
|
||||||
lineNumber: 1,
|
lineNumber: 1,
|
||||||
isInsert: true
|
isInsert: true,
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
_links: {
|
_links: {
|
||||||
lines: {
|
lines: {
|
||||||
href:
|
href: "/api/v2/repositories/scmadmin/HeartOfGold-git/content/one_to_onehundred/1.txt?start={start}&end={end}",
|
||||||
"/api/v2/repositories/scmadmin/HeartOfGold-git/content/one_to_onehundred/1.txt?start={start}&end={end}",
|
templated: true,
|
||||||
templated: true
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
|
||||||
],
|
],
|
||||||
partial: false,
|
partial: false,
|
||||||
_links: {
|
_links: {
|
||||||
self: {
|
self: {
|
||||||
href: "/diff"
|
href: "/diff",
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
@@ -168,10 +165,10 @@ describe("Test diff", () => {
|
|||||||
it("should return simple parsed diff", async () => {
|
it("should return simple parsed diff", async () => {
|
||||||
fetchMock.getOnce("/api/v2/diff", {
|
fetchMock.getOnce("/api/v2/diff", {
|
||||||
body: simpleDiff,
|
body: simpleDiff,
|
||||||
headers: { "Content-Type": "application/vnd.scmm-diffparsed+json;v=2" }
|
headers: { "Content-Type": "application/vnd.scmm-diffparsed+json;v=2" },
|
||||||
});
|
});
|
||||||
const { result, waitFor } = renderHook(() => useDiff("/diff"), {
|
const { result, waitFor } = renderHook(() => useDiff("/diff"), {
|
||||||
wrapper: createWrapper()
|
wrapper: createWrapper(),
|
||||||
});
|
});
|
||||||
await waitFor(() => !!result.current.data);
|
await waitFor(() => !!result.current.data);
|
||||||
expect(result.current.data).toEqual(simpleDiff);
|
expect(result.current.data).toEqual(simpleDiff);
|
||||||
@@ -188,10 +185,10 @@ describe("Test diff", () => {
|
|||||||
+i am new!
|
+i am new!
|
||||||
\\ No newline at end of file
|
\\ No newline at end of file
|
||||||
`,
|
`,
|
||||||
headers: { "Content-Type": "text/plain" }
|
headers: { "Content-Type": "text/plain" },
|
||||||
});
|
});
|
||||||
const { result, waitFor } = renderHook(() => useDiff("/diff"), {
|
const { result, waitFor } = renderHook(() => useDiff("/diff"), {
|
||||||
wrapper: createWrapper()
|
wrapper: createWrapper(),
|
||||||
});
|
});
|
||||||
await waitFor(() => !!result.current.data);
|
await waitFor(() => !!result.current.data);
|
||||||
expect(result.current.data?.files).toHaveLength(1);
|
expect(result.current.data?.files).toHaveLength(1);
|
||||||
@@ -200,14 +197,14 @@ describe("Test diff", () => {
|
|||||||
it("should return parsed diff in multiple chunks", async () => {
|
it("should return parsed diff in multiple chunks", async () => {
|
||||||
fetchMock.getOnce("/api/v2/diff?limit=1", {
|
fetchMock.getOnce("/api/v2/diff?limit=1", {
|
||||||
body: partialDiff1,
|
body: partialDiff1,
|
||||||
headers: { "Content-Type": "application/vnd.scmm-diffparsed+json;v=2" }
|
headers: { "Content-Type": "application/vnd.scmm-diffparsed+json;v=2" },
|
||||||
});
|
});
|
||||||
fetchMock.getOnce("/api/v2/diff?offset=1&limit=1", {
|
fetchMock.getOnce("/api/v2/diff?offset=1&limit=1", {
|
||||||
body: partialDiff2,
|
body: partialDiff2,
|
||||||
headers: { "Content-Type": "application/vnd.scmm-diffparsed+json;v=2" }
|
headers: { "Content-Type": "application/vnd.scmm-diffparsed+json;v=2" },
|
||||||
});
|
});
|
||||||
const { result, waitFor, waitForNextUpdate } = renderHook(() => useDiff("/diff?limit=1"), {
|
const { result, waitFor, waitForNextUpdate } = renderHook(() => useDiff("/diff?limit=1"), {
|
||||||
wrapper: createWrapper()
|
wrapper: createWrapper(),
|
||||||
});
|
});
|
||||||
await waitFor(() => !!result.current.data);
|
await waitFor(() => !!result.current.data);
|
||||||
expect(result.current.data).toEqual(partialDiff1);
|
expect(result.current.data).toEqual(partialDiff1);
|
||||||
@@ -226,10 +223,10 @@ describe("Test diff", () => {
|
|||||||
it("should append query parameters to url which has already query params", async () => {
|
it("should append query parameters to url which has already query params", async () => {
|
||||||
fetchMock.getOnce("/api/v2/diff?format=GIT&limit=25", {
|
fetchMock.getOnce("/api/v2/diff?format=GIT&limit=25", {
|
||||||
body: simpleDiff,
|
body: simpleDiff,
|
||||||
headers: { "Content-Type": "application/vnd.scmm-diffparsed+json;v=2" }
|
headers: { "Content-Type": "application/vnd.scmm-diffparsed+json;v=2" },
|
||||||
});
|
});
|
||||||
const { result, waitFor } = renderHook(() => useDiff("/diff?format=GIT", { limit: 25 }), {
|
const { result, waitFor } = renderHook(() => useDiff("/diff?format=GIT", { limit: 25 }), {
|
||||||
wrapper: createWrapper()
|
wrapper: createWrapper(),
|
||||||
});
|
});
|
||||||
await waitFor(() => !!result.current.data);
|
await waitFor(() => !!result.current.data);
|
||||||
expect(result.current.data).toEqual(simpleDiff);
|
expect(result.current.data).toEqual(simpleDiff);
|
||||||
|
|||||||
@@ -32,10 +32,10 @@ describe("test createBackendError", () => {
|
|||||||
context: [
|
context: [
|
||||||
{
|
{
|
||||||
type: "planet",
|
type: "planet",
|
||||||
id: "earth"
|
id: "earth",
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
violations: []
|
violations: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
it("should return a default backend error", () => {
|
it("should return a default backend error", () => {
|
||||||
|
|||||||
@@ -40,21 +40,21 @@ describe("Test group hooks", () => {
|
|||||||
type: "xml",
|
type: "xml",
|
||||||
_links: {
|
_links: {
|
||||||
delete: {
|
delete: {
|
||||||
href: "/groups/jedis"
|
href: "/groups/jedis",
|
||||||
},
|
},
|
||||||
update: {
|
update: {
|
||||||
href: "/groups/jedis"
|
href: "/groups/jedis",
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
_embedded: {
|
_embedded: {
|
||||||
members: []
|
members: [],
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const jedisCollection = {
|
const jedisCollection = {
|
||||||
_embedded: {
|
_embedded: {
|
||||||
groups: [jedis]
|
groups: [jedis],
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
@@ -67,7 +67,7 @@ describe("Test group hooks", () => {
|
|||||||
setIndexLink(queryClient, "groups", "/groups");
|
setIndexLink(queryClient, "groups", "/groups");
|
||||||
fetchMock.get("/api/v2/groups", jedisCollection);
|
fetchMock.get("/api/v2/groups", jedisCollection);
|
||||||
const { result, waitFor } = renderHook(() => useGroups(), {
|
const { result, waitFor } = renderHook(() => useGroups(), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
await waitFor(() => !!result.current.data);
|
await waitFor(() => !!result.current.data);
|
||||||
expect(result.current.data).toEqual(jedisCollection);
|
expect(result.current.data).toEqual(jedisCollection);
|
||||||
@@ -78,11 +78,11 @@ describe("Test group hooks", () => {
|
|||||||
setIndexLink(queryClient, "groups", "/groups");
|
setIndexLink(queryClient, "groups", "/groups");
|
||||||
fetchMock.get("/api/v2/groups", jedisCollection, {
|
fetchMock.get("/api/v2/groups", jedisCollection, {
|
||||||
query: {
|
query: {
|
||||||
page: "42"
|
page: "42",
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
const { result, waitFor } = renderHook(() => useGroups({ page: 42 }), {
|
const { result, waitFor } = renderHook(() => useGroups({ page: 42 }), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
await waitFor(() => !!result.current.data);
|
await waitFor(() => !!result.current.data);
|
||||||
expect(result.current.data).toEqual(jedisCollection);
|
expect(result.current.data).toEqual(jedisCollection);
|
||||||
@@ -93,11 +93,11 @@ describe("Test group hooks", () => {
|
|||||||
setIndexLink(queryClient, "groups", "/groups");
|
setIndexLink(queryClient, "groups", "/groups");
|
||||||
fetchMock.get("/api/v2/groups", jedisCollection, {
|
fetchMock.get("/api/v2/groups", jedisCollection, {
|
||||||
query: {
|
query: {
|
||||||
q: "jedis"
|
q: "jedis",
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
const { result, waitFor } = renderHook(() => useGroups({ search: "jedis" }), {
|
const { result, waitFor } = renderHook(() => useGroups({ search: "jedis" }), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
await waitFor(() => !!result.current.data);
|
await waitFor(() => !!result.current.data);
|
||||||
expect(result.current.data).toEqual(jedisCollection);
|
expect(result.current.data).toEqual(jedisCollection);
|
||||||
@@ -108,7 +108,7 @@ describe("Test group hooks", () => {
|
|||||||
setIndexLink(queryClient, "groups", "/groups");
|
setIndexLink(queryClient, "groups", "/groups");
|
||||||
fetchMock.get("/api/v2/groups", jedisCollection);
|
fetchMock.get("/api/v2/groups", jedisCollection);
|
||||||
const { result, waitFor } = renderHook(() => useGroups(), {
|
const { result, waitFor } = renderHook(() => useGroups(), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
await waitFor(() => !!result.current.data);
|
await waitFor(() => !!result.current.data);
|
||||||
expect(queryClient.getQueryData(["group", "jedis"])).toEqual(jedis);
|
expect(queryClient.getQueryData(["group", "jedis"])).toEqual(jedis);
|
||||||
@@ -121,7 +121,7 @@ describe("Test group hooks", () => {
|
|||||||
setIndexLink(queryClient, "groups", "/groups");
|
setIndexLink(queryClient, "groups", "/groups");
|
||||||
fetchMock.get("/api/v2/groups/jedis", jedis);
|
fetchMock.get("/api/v2/groups/jedis", jedis);
|
||||||
const { result, waitFor } = renderHook(() => useGroup("jedis"), {
|
const { result, waitFor } = renderHook(() => useGroup("jedis"), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
await waitFor(() => !!result.current.data);
|
await waitFor(() => !!result.current.data);
|
||||||
expect(result.current.data).toEqual(jedis);
|
expect(result.current.data).toEqual(jedis);
|
||||||
@@ -136,14 +136,14 @@ describe("Test group hooks", () => {
|
|||||||
fetchMock.postOnce("/api/v2/groups", {
|
fetchMock.postOnce("/api/v2/groups", {
|
||||||
status: 201,
|
status: 201,
|
||||||
headers: {
|
headers: {
|
||||||
Location: "/groups/jedis"
|
Location: "/groups/jedis",
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
fetchMock.getOnce("/api/v2/groups/jedis", jedis);
|
fetchMock.getOnce("/api/v2/groups/jedis", jedis);
|
||||||
|
|
||||||
const { result, waitForNextUpdate } = renderHook(() => useCreateGroup(), {
|
const { result, waitForNextUpdate } = renderHook(() => useCreateGroup(), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
|
|
||||||
await act(() => {
|
await act(() => {
|
||||||
@@ -160,13 +160,13 @@ describe("Test group hooks", () => {
|
|||||||
setIndexLink(queryClient, "groups", "/groups");
|
setIndexLink(queryClient, "groups", "/groups");
|
||||||
|
|
||||||
fetchMock.postOnce("/api/v2/groups", {
|
fetchMock.postOnce("/api/v2/groups", {
|
||||||
status: 201
|
status: 201,
|
||||||
});
|
});
|
||||||
|
|
||||||
fetchMock.getOnce("/api/v2/groups/jedis", jedis);
|
fetchMock.getOnce("/api/v2/groups/jedis", jedis);
|
||||||
|
|
||||||
const { result, waitForNextUpdate } = renderHook(() => useCreateGroup(), {
|
const { result, waitForNextUpdate } = renderHook(() => useCreateGroup(), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
|
|
||||||
await act(() => {
|
await act(() => {
|
||||||
@@ -185,11 +185,11 @@ describe("Test group hooks", () => {
|
|||||||
setIndexLink(queryClient, "groups", "/groups");
|
setIndexLink(queryClient, "groups", "/groups");
|
||||||
|
|
||||||
fetchMock.deleteOnce("/api/v2/groups/jedis", {
|
fetchMock.deleteOnce("/api/v2/groups/jedis", {
|
||||||
status: 200
|
status: 200,
|
||||||
});
|
});
|
||||||
|
|
||||||
const { result, waitForNextUpdate } = renderHook(() => useDeleteGroup(), {
|
const { result, waitForNextUpdate } = renderHook(() => useDeleteGroup(), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
|
|
||||||
await act(() => {
|
await act(() => {
|
||||||
@@ -212,17 +212,17 @@ describe("Test group hooks", () => {
|
|||||||
|
|
||||||
const newJedis = {
|
const newJedis = {
|
||||||
...jedis,
|
...jedis,
|
||||||
description: "may the 4th be with you"
|
description: "may the 4th be with you",
|
||||||
};
|
};
|
||||||
|
|
||||||
fetchMock.putOnce("/api/v2/groups/jedis", {
|
fetchMock.putOnce("/api/v2/groups/jedis", {
|
||||||
status: 200
|
status: 200,
|
||||||
});
|
});
|
||||||
|
|
||||||
fetchMock.getOnce("/api/v2/groups/jedis", newJedis);
|
fetchMock.getOnce("/api/v2/groups/jedis", newJedis);
|
||||||
|
|
||||||
const { result, waitForNextUpdate } = renderHook(() => useUpdateGroup(), {
|
const { result, waitForNextUpdate } = renderHook(() => useUpdateGroup(), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
|
|
||||||
await act(() => {
|
await act(() => {
|
||||||
|
|||||||
@@ -29,9 +29,9 @@ describe("requireLink tests", () => {
|
|||||||
{
|
{
|
||||||
_links: {
|
_links: {
|
||||||
spaceship: {
|
spaceship: {
|
||||||
href: "/v2/ship"
|
href: "/v2/ship",
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
"spaceship"
|
"spaceship"
|
||||||
);
|
);
|
||||||
@@ -49,14 +49,14 @@ describe("requireLink tests", () => {
|
|||||||
spaceship: [
|
spaceship: [
|
||||||
{
|
{
|
||||||
name: "one",
|
name: "one",
|
||||||
href: "/v2/one"
|
href: "/v2/one",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "two",
|
name: "two",
|
||||||
href: "/v2/two"
|
href: "/v2/two",
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
expect(() => requiredLink(object, "spaceship")).toThrowError();
|
expect(() => requiredLink(object, "spaceship")).toThrowError();
|
||||||
});
|
});
|
||||||
@@ -67,14 +67,14 @@ describe("requireLink tests", () => {
|
|||||||
spaceship: [
|
spaceship: [
|
||||||
{
|
{
|
||||||
name: "one",
|
name: "one",
|
||||||
href: "/v2/one"
|
href: "/v2/one",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "two",
|
name: "two",
|
||||||
href: "/v2/two"
|
href: "/v2/two",
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
expect(requiredLink(object, "spaceship", "one")).toBe("/v2/one");
|
expect(requiredLink(object, "spaceship", "one")).toBe("/v2/one");
|
||||||
});
|
});
|
||||||
@@ -85,14 +85,14 @@ describe("requireLink tests", () => {
|
|||||||
spaceship: [
|
spaceship: [
|
||||||
{
|
{
|
||||||
name: "one",
|
name: "one",
|
||||||
href: "/v2/one"
|
href: "/v2/one",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "two",
|
name: "two",
|
||||||
href: "/v2/two"
|
href: "/v2/two",
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
expect(() => requiredLink(object, "spaceship", "three")).toThrowError();
|
expect(() => requiredLink(object, "spaceship", "three")).toThrowError();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ describe("Test login hooks", () => {
|
|||||||
name: "tricia",
|
name: "tricia",
|
||||||
displayName: "Tricia",
|
displayName: "Tricia",
|
||||||
groups: [],
|
groups: [],
|
||||||
_links: {}
|
_links: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
describe("useMe tests", () => {
|
describe("useMe tests", () => {
|
||||||
@@ -45,7 +45,7 @@ describe("Test login hooks", () => {
|
|||||||
name: "tricia",
|
name: "tricia",
|
||||||
displayName: "Tricia",
|
displayName: "Tricia",
|
||||||
groups: [],
|
groups: [],
|
||||||
_links: {}
|
_links: {},
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should return me", async () => {
|
it("should return me", async () => {
|
||||||
@@ -65,9 +65,9 @@ describe("Test login hooks", () => {
|
|||||||
|
|
||||||
let me: Me;
|
let me: Me;
|
||||||
const context: LegacyContext = {
|
const context: LegacyContext = {
|
||||||
onMeFetched: fetchedMe => {
|
onMeFetched: (fetchedMe) => {
|
||||||
me = fetchedMe;
|
me = fetchedMe;
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const { result, waitFor } = renderHook(() => useMe(), { wrapper: createWrapper(context, queryClient) });
|
const { result, waitFor } = renderHook(() => useMe(), { wrapper: createWrapper(context, queryClient) });
|
||||||
@@ -130,7 +130,7 @@ describe("Test login hooks", () => {
|
|||||||
name: "_anonymous",
|
name: "_anonymous",
|
||||||
displayName: "Anonymous",
|
displayName: "Anonymous",
|
||||||
groups: [],
|
groups: [],
|
||||||
_links: {}
|
_links: {},
|
||||||
});
|
});
|
||||||
const { result } = renderHook(() => useSubject(), { wrapper: createWrapper(undefined, queryClient) });
|
const { result } = renderHook(() => useSubject(), { wrapper: createWrapper(undefined, queryClient) });
|
||||||
|
|
||||||
@@ -158,8 +158,8 @@ describe("Test login hooks", () => {
|
|||||||
cookie: true,
|
cookie: true,
|
||||||
grant_type: "password",
|
grant_type: "password",
|
||||||
username: "tricia",
|
username: "tricia",
|
||||||
password: "hitchhikersSecret!"
|
password: "hitchhikersSecret!",
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// required because we invalidate the whole cache and react-query refetches the index
|
// required because we invalidate the whole cache and react-query refetches the index
|
||||||
@@ -167,13 +167,13 @@ describe("Test login hooks", () => {
|
|||||||
version: "x.y.z",
|
version: "x.y.z",
|
||||||
_links: {
|
_links: {
|
||||||
login: {
|
login: {
|
||||||
href: "/second/login"
|
href: "/second/login",
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const { result, waitForNextUpdate } = renderHook(() => useLogin(), {
|
const { result, waitForNextUpdate } = renderHook(() => useLogin(), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
const { login } = result.current;
|
const { login } = result.current;
|
||||||
expect(login).toBeDefined();
|
expect(login).toBeDefined();
|
||||||
@@ -194,7 +194,7 @@ describe("Test login hooks", () => {
|
|||||||
queryClient.setQueryData("me", tricia);
|
queryClient.setQueryData("me", tricia);
|
||||||
|
|
||||||
const { result } = renderHook(() => useLogin(), {
|
const { result } = renderHook(() => useLogin(), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(result.current.login).toBeUndefined();
|
expect(result.current.login).toBeUndefined();
|
||||||
@@ -209,7 +209,7 @@ describe("Test login hooks", () => {
|
|||||||
fetchMock.deleteOnce("/api/v2/logout", {});
|
fetchMock.deleteOnce("/api/v2/logout", {});
|
||||||
|
|
||||||
const { result, waitForNextUpdate } = renderHook(() => useLogout(), {
|
const { result, waitForNextUpdate } = renderHook(() => useLogout(), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
const { logout } = result.current;
|
const { logout } = result.current;
|
||||||
expect(logout).toBeDefined();
|
expect(logout).toBeDefined();
|
||||||
@@ -229,7 +229,7 @@ describe("Test login hooks", () => {
|
|||||||
setEmptyIndex(queryClient);
|
setEmptyIndex(queryClient);
|
||||||
|
|
||||||
const { result } = renderHook(() => useLogout(), {
|
const { result } = renderHook(() => useLogout(), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
|
|
||||||
const { logout } = result.current;
|
const { logout } = result.current;
|
||||||
|
|||||||
@@ -32,13 +32,13 @@ import { useReset } from "./reset";
|
|||||||
export const useMe = (): ApiResult<Me> => {
|
export const useMe = (): ApiResult<Me> => {
|
||||||
const legacy = useLegacyContext();
|
const legacy = useLegacyContext();
|
||||||
const link = useIndexLink("me");
|
const link = useIndexLink("me");
|
||||||
return useQuery<Me, Error>("me", () => apiClient.get(link!).then(response => response.json()), {
|
return useQuery<Me, Error>("me", () => apiClient.get(link!).then((response) => response.json()), {
|
||||||
enabled: !!link,
|
enabled: !!link,
|
||||||
onSuccess: me => {
|
onSuccess: (me) => {
|
||||||
if (legacy.onMeFetched) {
|
if (legacy.onMeFetched) {
|
||||||
legacy.onMeFetched(me);
|
legacy.onMeFetched(me);
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -60,7 +60,7 @@ export const useSubject = () => {
|
|||||||
isAnonymous,
|
isAnonymous,
|
||||||
isLoading,
|
isLoading,
|
||||||
error,
|
error,
|
||||||
me
|
me,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -75,9 +75,9 @@ export const useLogin = () => {
|
|||||||
const link = useIndexLink("login");
|
const link = useIndexLink("login");
|
||||||
const reset = useReset();
|
const reset = useReset();
|
||||||
const { mutate, isLoading, error } = useMutation<unknown, Error, Credentials>(
|
const { mutate, isLoading, error } = useMutation<unknown, Error, Credentials>(
|
||||||
credentials => apiClient.post(link!, credentials),
|
(credentials) => apiClient.post(link!, credentials),
|
||||||
{
|
{
|
||||||
onSuccess: reset
|
onSuccess: reset,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -91,7 +91,7 @@ export const useLogin = () => {
|
|||||||
return {
|
return {
|
||||||
login: link ? login : undefined,
|
login: link ? login : undefined,
|
||||||
isLoading,
|
isLoading,
|
||||||
error
|
error,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -104,14 +104,14 @@ export const useLogout = () => {
|
|||||||
const reset = useReset();
|
const reset = useReset();
|
||||||
|
|
||||||
const { mutate, isLoading, error, data } = useMutation<LogoutResponse, Error, unknown>(
|
const { mutate, isLoading, error, data } = useMutation<LogoutResponse, Error, unknown>(
|
||||||
() => apiClient.delete(link!).then(r => (r.status === 200 ? r.json() : {})),
|
() => apiClient.delete(link!).then((r) => (r.status === 200 ? r.json() : {})),
|
||||||
{
|
{
|
||||||
onSuccess: response => {
|
onSuccess: (response) => {
|
||||||
if (response?.logoutRedirect) {
|
if (response?.logoutRedirect) {
|
||||||
window.location.assign(response.logoutRedirect);
|
window.location.assign(response.logoutRedirect);
|
||||||
}
|
}
|
||||||
return reset();
|
return reset();
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -122,6 +122,6 @@ export const useLogout = () => {
|
|||||||
return {
|
return {
|
||||||
logout: link && !data ? logout : undefined,
|
logout: link && !data ? logout : undefined,
|
||||||
isLoading,
|
isLoading,
|
||||||
error
|
error,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -38,14 +38,14 @@ describe("Test namespace hooks", () => {
|
|||||||
namespaces: [
|
namespaces: [
|
||||||
{
|
{
|
||||||
namespace: "spaceships",
|
namespace: "spaceships",
|
||||||
_links: {}
|
_links: {},
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const { result, waitFor } = renderHook(() => useNamespaces(), {
|
const { result, waitFor } = renderHook(() => useNamespaces(), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
await waitFor(() => {
|
await waitFor(() => {
|
||||||
return !!result.current.data;
|
return !!result.current.data;
|
||||||
@@ -61,11 +61,11 @@ describe("Test namespace hooks", () => {
|
|||||||
fetchMock.get("/api/v2/ns", {
|
fetchMock.get("/api/v2/ns", {
|
||||||
current: "awesome",
|
current: "awesome",
|
||||||
available: [],
|
available: [],
|
||||||
_links: {}
|
_links: {},
|
||||||
});
|
});
|
||||||
|
|
||||||
const { result, waitFor } = renderHook(() => useNamespaceStrategies(), {
|
const { result, waitFor } = renderHook(() => useNamespaceStrategies(), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
await waitFor(() => {
|
await waitFor(() => {
|
||||||
return !!result.current.data;
|
return !!result.current.data;
|
||||||
@@ -80,11 +80,11 @@ describe("Test namespace hooks", () => {
|
|||||||
setIndexLink(queryClient, "namespaces", "/ns");
|
setIndexLink(queryClient, "namespaces", "/ns");
|
||||||
fetchMock.get("/api/v2/ns/awesome", {
|
fetchMock.get("/api/v2/ns/awesome", {
|
||||||
namespace: "awesome",
|
namespace: "awesome",
|
||||||
_links: {}
|
_links: {},
|
||||||
});
|
});
|
||||||
|
|
||||||
const { result, waitFor } = renderHook(() => useNamespace("awesome"), {
|
const { result, waitFor } = renderHook(() => useNamespace("awesome"), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
await waitFor(() => {
|
await waitFor(() => {
|
||||||
return !!result.current.data;
|
return !!result.current.data;
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ export const useNamespaces = () => {
|
|||||||
export const useNamespace = (name: string): ApiResult<Namespace> => {
|
export const useNamespace = (name: string): ApiResult<Namespace> => {
|
||||||
const namespacesLink = useRequiredIndexLink("namespaces");
|
const namespacesLink = useRequiredIndexLink("namespaces");
|
||||||
return useQuery<Namespace, Error>(["namespace", name], () =>
|
return useQuery<Namespace, Error>(["namespace", name], () =>
|
||||||
apiClient.get(concat(namespacesLink, name)).then(response => response.json())
|
apiClient.get(concat(namespacesLink, name)).then((response) => response.json())
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -40,26 +40,28 @@ const waitForRestartAfter = (
|
|||||||
const endTime = Number(new Date()) + 60000;
|
const endTime = Number(new Date()) + 60000;
|
||||||
let started = false;
|
let started = false;
|
||||||
|
|
||||||
const executor = <T = any>(data: T) => (resolve: (result: T) => void, reject: (error: Error) => void) => {
|
const executor =
|
||||||
// we need some initial delay
|
<T = any>(data: T) =>
|
||||||
if (!started) {
|
(resolve: (result: T) => void, reject: (error: Error) => void) => {
|
||||||
started = true;
|
// we need some initial delay
|
||||||
setTimeout(executor(data), initialDelay, resolve, reject);
|
if (!started) {
|
||||||
} else {
|
started = true;
|
||||||
apiClient
|
setTimeout(executor(data), initialDelay, resolve, reject);
|
||||||
.get("")
|
} else {
|
||||||
.then(() => resolve(data))
|
apiClient
|
||||||
.catch(() => {
|
.get("")
|
||||||
if (Number(new Date()) < endTime) {
|
.then(() => resolve(data))
|
||||||
setTimeout(executor(data), timeout, resolve, reject);
|
.catch(() => {
|
||||||
} else {
|
if (Number(new Date()) < endTime) {
|
||||||
reject(new Error("timeout reached"));
|
setTimeout(executor(data), timeout, resolve, reject);
|
||||||
}
|
} else {
|
||||||
});
|
reject(new Error("timeout reached"));
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return promise.then(data => new Promise<void>(executor(data)));
|
return promise.then((data) => new Promise<void>(executor(data)));
|
||||||
};
|
};
|
||||||
|
|
||||||
export type UseAvailablePluginsOptions = {
|
export type UseAvailablePluginsOptions = {
|
||||||
@@ -70,10 +72,10 @@ export const useAvailablePlugins = ({ enabled }: UseAvailablePluginsOptions = {}
|
|||||||
const indexLink = useRequiredIndexLink("availablePlugins");
|
const indexLink = useRequiredIndexLink("availablePlugins");
|
||||||
return useQuery<PluginCollection, Error>(
|
return useQuery<PluginCollection, Error>(
|
||||||
["plugins", "available"],
|
["plugins", "available"],
|
||||||
() => apiClient.get(indexLink).then(response => response.json()),
|
() => apiClient.get(indexLink).then((response) => response.json()),
|
||||||
{
|
{
|
||||||
enabled,
|
enabled,
|
||||||
retry: 3
|
retry: 3,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@@ -86,10 +88,10 @@ export const useInstalledPlugins = ({ enabled }: UseInstalledPluginsOptions = {}
|
|||||||
const indexLink = useRequiredIndexLink("installedPlugins");
|
const indexLink = useRequiredIndexLink("installedPlugins");
|
||||||
return useQuery<PluginCollection, Error>(
|
return useQuery<PluginCollection, Error>(
|
||||||
["plugins", "installed"],
|
["plugins", "installed"],
|
||||||
() => apiClient.get(indexLink).then(response => response.json()),
|
() => apiClient.get(indexLink).then((response) => response.json()),
|
||||||
{
|
{
|
||||||
enabled,
|
enabled,
|
||||||
retry: 3
|
retry: 3,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@@ -98,10 +100,10 @@ export const usePendingPlugins = (): ApiResult<PendingPlugins> => {
|
|||||||
const indexLink = useIndexLink("pendingPlugins");
|
const indexLink = useIndexLink("pendingPlugins");
|
||||||
return useQuery<PendingPlugins, Error>(
|
return useQuery<PendingPlugins, Error>(
|
||||||
["plugins", "pending"],
|
["plugins", "pending"],
|
||||||
() => apiClient.get(indexLink!).then(response => response.json()),
|
() => apiClient.get(indexLink!).then((response) => response.json()),
|
||||||
{
|
{
|
||||||
enabled: !!indexLink,
|
enabled: !!indexLink,
|
||||||
retry: 3
|
retry: 3,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@@ -133,19 +135,19 @@ export const useInstallPlugin = () => {
|
|||||||
return promise;
|
return promise;
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
onSuccess: () => queryClient.invalidateQueries("plugins")
|
onSuccess: () => queryClient.invalidateQueries("plugins"),
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
return {
|
return {
|
||||||
install: (plugin: Plugin, restartOptions: RestartOptions = {}) =>
|
install: (plugin: Plugin, restartOptions: RestartOptions = {}) =>
|
||||||
mutate({
|
mutate({
|
||||||
plugin,
|
plugin,
|
||||||
restartOptions
|
restartOptions,
|
||||||
}),
|
}),
|
||||||
isLoading,
|
isLoading,
|
||||||
error,
|
error,
|
||||||
data,
|
data,
|
||||||
isInstalled: !!data
|
isInstalled: !!data,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -160,18 +162,18 @@ export const useUninstallPlugin = () => {
|
|||||||
return promise;
|
return promise;
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
onSuccess: () => queryClient.invalidateQueries("plugins")
|
onSuccess: () => queryClient.invalidateQueries("plugins"),
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
return {
|
return {
|
||||||
uninstall: (plugin: Plugin, restartOptions: RestartOptions = {}) =>
|
uninstall: (plugin: Plugin, restartOptions: RestartOptions = {}) =>
|
||||||
mutate({
|
mutate({
|
||||||
plugin,
|
plugin,
|
||||||
restartOptions
|
restartOptions,
|
||||||
}),
|
}),
|
||||||
isLoading,
|
isLoading,
|
||||||
error,
|
error,
|
||||||
isUninstalled: !!data
|
isUninstalled: !!data,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -194,18 +196,18 @@ export const useUpdatePlugins = () => {
|
|||||||
return promise;
|
return promise;
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
onSuccess: () => queryClient.invalidateQueries("plugins")
|
onSuccess: () => queryClient.invalidateQueries("plugins"),
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
return {
|
return {
|
||||||
update: (plugin: Plugin | PluginCollection, restartOptions: RestartOptions = {}) =>
|
update: (plugin: Plugin | PluginCollection, restartOptions: RestartOptions = {}) =>
|
||||||
mutate({
|
mutate({
|
||||||
plugins: plugin,
|
plugins: plugin,
|
||||||
restartOptions
|
restartOptions,
|
||||||
}),
|
}),
|
||||||
isLoading,
|
isLoading,
|
||||||
error,
|
error,
|
||||||
isUpdated: !!data
|
isUpdated: !!data,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -220,7 +222,7 @@ export const useExecutePendingPlugins = () => {
|
|||||||
({ pending, restartOptions }) =>
|
({ pending, restartOptions }) =>
|
||||||
waitForRestartAfter(apiClient.post(requiredLink(pending, "execute")), restartOptions),
|
waitForRestartAfter(apiClient.post(requiredLink(pending, "execute")), restartOptions),
|
||||||
{
|
{
|
||||||
onSuccess: () => queryClient.invalidateQueries("plugins")
|
onSuccess: () => queryClient.invalidateQueries("plugins"),
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
return {
|
return {
|
||||||
@@ -228,22 +230,22 @@ export const useExecutePendingPlugins = () => {
|
|||||||
mutate({ pending, restartOptions }),
|
mutate({ pending, restartOptions }),
|
||||||
isLoading,
|
isLoading,
|
||||||
error,
|
error,
|
||||||
isExecuted: !!data
|
isExecuted: !!data,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useCancelPendingPlugins = () => {
|
export const useCancelPendingPlugins = () => {
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
const { mutate, isLoading, error, data } = useMutation<unknown, Error, PendingPlugins>(
|
const { mutate, isLoading, error, data } = useMutation<unknown, Error, PendingPlugins>(
|
||||||
pending => apiClient.post(requiredLink(pending, "cancel")),
|
(pending) => apiClient.post(requiredLink(pending, "cancel")),
|
||||||
{
|
{
|
||||||
onSuccess: () => queryClient.invalidateQueries("plugins")
|
onSuccess: () => queryClient.invalidateQueries("plugins"),
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
return {
|
return {
|
||||||
update: (pending: PendingPlugins) => mutate(pending),
|
update: (pending: PendingPlugins) => mutate(pending),
|
||||||
isLoading,
|
isLoading,
|
||||||
error,
|
error,
|
||||||
isCancelled: !!data
|
isCancelled: !!data,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -32,8 +32,9 @@ import { act } from "react-test-renderer";
|
|||||||
import {
|
import {
|
||||||
useCreateRepositoryRole,
|
useCreateRepositoryRole,
|
||||||
useDeleteRepositoryRole,
|
useDeleteRepositoryRole,
|
||||||
useRepositoryRole, useRepositoryRoles,
|
useRepositoryRole,
|
||||||
useUpdateRepositoryRole
|
useRepositoryRoles,
|
||||||
|
useUpdateRepositoryRole,
|
||||||
} from "./repository-roles";
|
} from "./repository-roles";
|
||||||
|
|
||||||
describe("Test repository-roles hooks", () => {
|
describe("Test repository-roles hooks", () => {
|
||||||
@@ -43,12 +44,12 @@ describe("Test repository-roles hooks", () => {
|
|||||||
verbs: ["rocking"],
|
verbs: ["rocking"],
|
||||||
_links: {
|
_links: {
|
||||||
delete: {
|
delete: {
|
||||||
href: "/repositoryRoles/theroleingstones"
|
href: "/repositoryRoles/theroleingstones",
|
||||||
},
|
},
|
||||||
update: {
|
update: {
|
||||||
href: "/repositoryRoles/theroleingstones"
|
href: "/repositoryRoles/theroleingstones",
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const roleCollection: RepositoryRoleCollection = {
|
const roleCollection: RepositoryRoleCollection = {
|
||||||
@@ -56,8 +57,8 @@ describe("Test repository-roles hooks", () => {
|
|||||||
pageTotal: 0,
|
pageTotal: 0,
|
||||||
_links: {},
|
_links: {},
|
||||||
_embedded: {
|
_embedded: {
|
||||||
repositoryRoles: [role]
|
repositoryRoles: [role],
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
@@ -70,7 +71,7 @@ describe("Test repository-roles hooks", () => {
|
|||||||
setIndexLink(queryClient, "repositoryRoles", "/repositoryRoles");
|
setIndexLink(queryClient, "repositoryRoles", "/repositoryRoles");
|
||||||
fetchMock.get("/api/v2/repositoryRoles", roleCollection);
|
fetchMock.get("/api/v2/repositoryRoles", roleCollection);
|
||||||
const { result, waitFor } = renderHook(() => useRepositoryRoles(), {
|
const { result, waitFor } = renderHook(() => useRepositoryRoles(), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
await waitFor(() => !!result.current.data);
|
await waitFor(() => !!result.current.data);
|
||||||
expect(result.current.data).toEqual(roleCollection);
|
expect(result.current.data).toEqual(roleCollection);
|
||||||
@@ -81,11 +82,11 @@ describe("Test repository-roles hooks", () => {
|
|||||||
setIndexLink(queryClient, "repositoryRoles", "/repositoryRoles");
|
setIndexLink(queryClient, "repositoryRoles", "/repositoryRoles");
|
||||||
fetchMock.get("/api/v2/repositoryRoles", roleCollection, {
|
fetchMock.get("/api/v2/repositoryRoles", roleCollection, {
|
||||||
query: {
|
query: {
|
||||||
page: "42"
|
page: "42",
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
const { result, waitFor } = renderHook(() => useRepositoryRoles({ page: 42 }), {
|
const { result, waitFor } = renderHook(() => useRepositoryRoles({ page: 42 }), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
await waitFor(() => !!result.current.data);
|
await waitFor(() => !!result.current.data);
|
||||||
expect(result.current.data).toEqual(roleCollection);
|
expect(result.current.data).toEqual(roleCollection);
|
||||||
@@ -96,7 +97,7 @@ describe("Test repository-roles hooks", () => {
|
|||||||
setIndexLink(queryClient, "repositoryRoles", "/repositoryRoles");
|
setIndexLink(queryClient, "repositoryRoles", "/repositoryRoles");
|
||||||
fetchMock.get("/api/v2/repositoryRoles", roleCollection);
|
fetchMock.get("/api/v2/repositoryRoles", roleCollection);
|
||||||
const { result, waitFor } = renderHook(() => useRepositoryRoles(), {
|
const { result, waitFor } = renderHook(() => useRepositoryRoles(), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
await waitFor(() => !!result.current.data);
|
await waitFor(() => !!result.current.data);
|
||||||
expect(queryClient.getQueryData(["repositoryRole", roleName])).toEqual(role);
|
expect(queryClient.getQueryData(["repositoryRole", roleName])).toEqual(role);
|
||||||
@@ -109,7 +110,7 @@ describe("Test repository-roles hooks", () => {
|
|||||||
setIndexLink(queryClient, "repositoryRoles", "/repositoryRoles");
|
setIndexLink(queryClient, "repositoryRoles", "/repositoryRoles");
|
||||||
fetchMock.get("/api/v2/repositoryRoles/" + roleName, role);
|
fetchMock.get("/api/v2/repositoryRoles/" + roleName, role);
|
||||||
const { result, waitFor } = renderHook(() => useRepositoryRole(roleName), {
|
const { result, waitFor } = renderHook(() => useRepositoryRole(roleName), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
await waitFor(() => !!result.current.data);
|
await waitFor(() => !!result.current.data);
|
||||||
expect(result.current.data).toEqual(role);
|
expect(result.current.data).toEqual(role);
|
||||||
@@ -124,14 +125,14 @@ describe("Test repository-roles hooks", () => {
|
|||||||
fetchMock.postOnce("/api/v2/repositoryRoles", {
|
fetchMock.postOnce("/api/v2/repositoryRoles", {
|
||||||
status: 201,
|
status: 201,
|
||||||
headers: {
|
headers: {
|
||||||
Location: "/repositoryRoles/" + roleName
|
Location: "/repositoryRoles/" + roleName,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
fetchMock.getOnce("/api/v2/repositoryRoles/" + roleName, role);
|
fetchMock.getOnce("/api/v2/repositoryRoles/" + roleName, role);
|
||||||
|
|
||||||
const { result, waitForNextUpdate } = renderHook(() => useCreateRepositoryRole(), {
|
const { result, waitForNextUpdate } = renderHook(() => useCreateRepositoryRole(), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
|
|
||||||
await act(() => {
|
await act(() => {
|
||||||
@@ -148,13 +149,13 @@ describe("Test repository-roles hooks", () => {
|
|||||||
setIndexLink(queryClient, "repositoryRoles", "/repositoryRoles");
|
setIndexLink(queryClient, "repositoryRoles", "/repositoryRoles");
|
||||||
|
|
||||||
fetchMock.postOnce("/api/v2/repositoryRoles", {
|
fetchMock.postOnce("/api/v2/repositoryRoles", {
|
||||||
status: 201
|
status: 201,
|
||||||
});
|
});
|
||||||
|
|
||||||
fetchMock.getOnce("/api/v2/repositoryRoles/" + roleName, role);
|
fetchMock.getOnce("/api/v2/repositoryRoles/" + roleName, role);
|
||||||
|
|
||||||
const { result, waitForNextUpdate } = renderHook(() => useCreateRepositoryRole(), {
|
const { result, waitForNextUpdate } = renderHook(() => useCreateRepositoryRole(), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
|
|
||||||
await act(() => {
|
await act(() => {
|
||||||
@@ -173,11 +174,11 @@ describe("Test repository-roles hooks", () => {
|
|||||||
setIndexLink(queryClient, "repositoryRoles", "/repositoryRoles");
|
setIndexLink(queryClient, "repositoryRoles", "/repositoryRoles");
|
||||||
|
|
||||||
fetchMock.deleteOnce("/api/v2/repositoryRoles/" + roleName, {
|
fetchMock.deleteOnce("/api/v2/repositoryRoles/" + roleName, {
|
||||||
status: 200
|
status: 200,
|
||||||
});
|
});
|
||||||
|
|
||||||
const { result, waitForNextUpdate } = renderHook(() => useDeleteRepositoryRole(), {
|
const { result, waitForNextUpdate } = renderHook(() => useDeleteRepositoryRole(), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
|
|
||||||
await act(() => {
|
await act(() => {
|
||||||
@@ -200,15 +201,15 @@ describe("Test repository-roles hooks", () => {
|
|||||||
|
|
||||||
const newRole: RepositoryRole = {
|
const newRole: RepositoryRole = {
|
||||||
...role,
|
...role,
|
||||||
name: "newname"
|
name: "newname",
|
||||||
};
|
};
|
||||||
|
|
||||||
fetchMock.putOnce("/api/v2/repositoryRoles/" + roleName, {
|
fetchMock.putOnce("/api/v2/repositoryRoles/" + roleName, {
|
||||||
status: 200
|
status: 200,
|
||||||
});
|
});
|
||||||
|
|
||||||
const { result, waitForNextUpdate } = renderHook(() => useUpdateRepositoryRole(), {
|
const { result, waitForNextUpdate } = renderHook(() => useUpdateRepositoryRole(), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
|
|
||||||
await act(() => {
|
await act(() => {
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import { QueryClient, useQueryClient } from "react-query";
|
|||||||
|
|
||||||
export const reset = (queryClient: QueryClient) => {
|
export const reset = (queryClient: QueryClient) => {
|
||||||
queryClient.removeQueries({
|
queryClient.removeQueries({
|
||||||
predicate: ({ queryKey }) => queryKey !== "index"
|
predicate: ({ queryKey }) => queryKey !== "index",
|
||||||
});
|
});
|
||||||
return queryClient.invalidateQueries("index");
|
return queryClient.invalidateQueries("index");
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -35,9 +35,9 @@ describe("Test sources hooks", () => {
|
|||||||
type: "git",
|
type: "git",
|
||||||
_links: {
|
_links: {
|
||||||
sources: {
|
sources: {
|
||||||
href: "/src"
|
href: "/src",
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const readmeMd: File = {
|
const readmeMd: File = {
|
||||||
@@ -49,8 +49,8 @@ describe("Test sources hooks", () => {
|
|||||||
description: "Awesome readme",
|
description: "Awesome readme",
|
||||||
_links: {},
|
_links: {},
|
||||||
_embedded: {
|
_embedded: {
|
||||||
children: []
|
children: [],
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const rootDirectory: File = {
|
const rootDirectory: File = {
|
||||||
@@ -60,8 +60,8 @@ describe("Test sources hooks", () => {
|
|||||||
revision: "abc",
|
revision: "abc",
|
||||||
_links: {},
|
_links: {},
|
||||||
_embedded: {
|
_embedded: {
|
||||||
children: [readmeMd]
|
children: [readmeMd],
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const sepecialMd: File = {
|
const sepecialMd: File = {
|
||||||
@@ -73,20 +73,20 @@ describe("Test sources hooks", () => {
|
|||||||
description: "Awesome special file",
|
description: "Awesome special file",
|
||||||
_links: {},
|
_links: {},
|
||||||
_embedded: {
|
_embedded: {
|
||||||
children: []
|
children: [],
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const sepecialMdPartial: File = {
|
const sepecialMdPartial: File = {
|
||||||
...sepecialMd,
|
...sepecialMd,
|
||||||
partialResult: true,
|
partialResult: true,
|
||||||
computationAborted: false
|
computationAborted: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
const sepecialMdComputationAborted: File = {
|
const sepecialMdComputationAborted: File = {
|
||||||
...sepecialMd,
|
...sepecialMd,
|
||||||
partialResult: true,
|
partialResult: true,
|
||||||
computationAborted: true
|
computationAborted: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
const mainDirectoryTruncated: File = {
|
const mainDirectoryTruncated: File = {
|
||||||
@@ -97,20 +97,20 @@ describe("Test sources hooks", () => {
|
|||||||
truncated: true,
|
truncated: true,
|
||||||
_links: {
|
_links: {
|
||||||
proceed: {
|
proceed: {
|
||||||
href: "src/2"
|
href: "src/2",
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
_embedded: {
|
_embedded: {
|
||||||
children: []
|
children: [],
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const mainDirectory: File = {
|
const mainDirectory: File = {
|
||||||
...mainDirectoryTruncated,
|
...mainDirectoryTruncated,
|
||||||
truncated: false,
|
truncated: false,
|
||||||
_embedded: {
|
_embedded: {
|
||||||
children: [sepecialMd]
|
children: [sepecialMd],
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
@@ -128,7 +128,7 @@ describe("Test sources hooks", () => {
|
|||||||
const queryClient = createInfiniteCachingClient();
|
const queryClient = createInfiniteCachingClient();
|
||||||
fetchMock.getOnce("/api/v2/src", rootDirectory);
|
fetchMock.getOnce("/api/v2/src", rootDirectory);
|
||||||
const { result, waitFor } = renderHook(() => useSources(puzzle42), {
|
const { result, waitFor } = renderHook(() => useSources(puzzle42), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
await waitFor(() => !!result.current.data);
|
await waitFor(() => !!result.current.data);
|
||||||
expect(result.current.data).toEqual(rootDirectory);
|
expect(result.current.data).toEqual(rootDirectory);
|
||||||
@@ -138,7 +138,7 @@ describe("Test sources hooks", () => {
|
|||||||
const queryClient = createInfiniteCachingClient();
|
const queryClient = createInfiniteCachingClient();
|
||||||
fetchMock.getOnce("/api/v2/src/abc/README.md", readmeMd);
|
fetchMock.getOnce("/api/v2/src/abc/README.md", readmeMd);
|
||||||
const { result, waitFor } = renderHook(() => useSources(puzzle42, { revision: "abc", path: "README.md" }), {
|
const { result, waitFor } = renderHook(() => useSources(puzzle42, { revision: "abc", path: "README.md" }), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
await waitFor(() => !!result.current.data);
|
await waitFor(() => !!result.current.data);
|
||||||
expect(result.current.data).toEqual(readmeMd);
|
expect(result.current.data).toEqual(readmeMd);
|
||||||
@@ -149,7 +149,7 @@ describe("Test sources hooks", () => {
|
|||||||
fetchMock.getOnce("/api/v2/src", mainDirectoryTruncated);
|
fetchMock.getOnce("/api/v2/src", mainDirectoryTruncated);
|
||||||
fetchMock.getOnce("/api/v2/src/2", mainDirectory);
|
fetchMock.getOnce("/api/v2/src/2", mainDirectory);
|
||||||
const { result, waitFor, waitForNextUpdate } = renderHook(() => useSources(puzzle42), {
|
const { result, waitFor, waitForNextUpdate } = renderHook(() => useSources(puzzle42), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
await waitFor(() => !!result.current.data);
|
await waitFor(() => !!result.current.data);
|
||||||
|
|
||||||
@@ -172,11 +172,11 @@ describe("Test sources hooks", () => {
|
|||||||
{
|
{
|
||||||
...mainDirectory,
|
...mainDirectory,
|
||||||
_embedded: {
|
_embedded: {
|
||||||
children: [sepecialMdPartial]
|
children: [sepecialMdPartial],
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
repeat: 1
|
repeat: 1,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
fetchMock.get(
|
fetchMock.get(
|
||||||
@@ -184,17 +184,17 @@ describe("Test sources hooks", () => {
|
|||||||
{
|
{
|
||||||
...mainDirectory,
|
...mainDirectory,
|
||||||
_embedded: {
|
_embedded: {
|
||||||
children: [sepecialMd]
|
children: [sepecialMd],
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
repeat: 1,
|
repeat: 1,
|
||||||
overwriteRoutes: false
|
overwriteRoutes: false,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
const { result, waitFor } = renderHook(() => useSources(puzzle42, { refetchPartialInterval: 100 }), {
|
const { result, waitFor } = renderHook(() => useSources(puzzle42, { refetchPartialInterval: 100 }), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
|
|
||||||
await waitFor(() => !!firstChild(result.current.data));
|
await waitFor(() => !!firstChild(result.current.data));
|
||||||
@@ -210,23 +210,23 @@ describe("Test sources hooks", () => {
|
|||||||
// should never be called
|
// should never be called
|
||||||
fetchMock.getOnce("/api/v2/src/abc/main/special.md", sepecialMd, {
|
fetchMock.getOnce("/api/v2/src/abc/main/special.md", sepecialMd, {
|
||||||
repeat: 1,
|
repeat: 1,
|
||||||
overwriteRoutes: false
|
overwriteRoutes: false,
|
||||||
});
|
});
|
||||||
const { result, waitFor } = renderHook(
|
const { result, waitFor } = renderHook(
|
||||||
() =>
|
() =>
|
||||||
useSources(puzzle42, {
|
useSources(puzzle42, {
|
||||||
revision: "abc",
|
revision: "abc",
|
||||||
path: "main/special.md",
|
path: "main/special.md",
|
||||||
refetchPartialInterval: 100
|
refetchPartialInterval: 100,
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
await waitFor(() => !!result.current.data);
|
await waitFor(() => !!result.current.data);
|
||||||
expect(result.current.data).toEqual(sepecialMdComputationAborted);
|
expect(result.current.data).toEqual(sepecialMdComputationAborted);
|
||||||
|
|
||||||
await new Promise(r => setTimeout(r, 200));
|
await new Promise((r) => setTimeout(r, 200));
|
||||||
expect(result.current.data).toEqual(sepecialMdComputationAborted);
|
expect(result.current.data).toEqual(sepecialMdComputationAborted);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -37,25 +37,25 @@ export type UseSourcesOptions = {
|
|||||||
|
|
||||||
const UseSourcesDefaultOptions: UseSourcesOptions = {
|
const UseSourcesDefaultOptions: UseSourcesOptions = {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
refetchPartialInterval: 3000
|
refetchPartialInterval: 3000,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useSources = (repository: Repository, opts: UseSourcesOptions = UseSourcesDefaultOptions) => {
|
export const useSources = (repository: Repository, opts: UseSourcesOptions = UseSourcesDefaultOptions) => {
|
||||||
const options = {
|
const options = {
|
||||||
...UseSourcesDefaultOptions,
|
...UseSourcesDefaultOptions,
|
||||||
...opts
|
...opts,
|
||||||
};
|
};
|
||||||
const link = createSourcesLink(repository, options);
|
const link = createSourcesLink(repository, options);
|
||||||
const { isLoading, error, data, isFetchingNextPage, fetchNextPage, refetch } = useInfiniteQuery<File, Error, File>(
|
const { isLoading, error, data, isFetchingNextPage, fetchNextPage, refetch } = useInfiniteQuery<File, Error, File>(
|
||||||
repoQueryKey(repository, "sources", options.revision || "", options.path || ""),
|
repoQueryKey(repository, "sources", options.revision || "", options.path || ""),
|
||||||
({ pageParam }) => {
|
({ pageParam }) => {
|
||||||
return apiClient.get(pageParam || link).then(response => response.json());
|
return apiClient.get(pageParam || link).then((response) => response.json());
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
enabled: options.enabled,
|
enabled: options.enabled,
|
||||||
getNextPageParam: lastPage => {
|
getNextPageParam: (lastPage) => {
|
||||||
return (lastPage._links.proceed as Link)?.href;
|
return (lastPage._links.proceed as Link)?.href;
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -64,7 +64,7 @@ export const useSources = (repository: Repository, opts: UseSourcesOptions = Use
|
|||||||
const intervalId = setInterval(() => {
|
const intervalId = setInterval(() => {
|
||||||
if (isPartial(file)) {
|
if (isPartial(file)) {
|
||||||
refetch({
|
refetch({
|
||||||
throwOnError: true
|
throwOnError: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, options.refetchPartialInterval);
|
}, options.refetchPartialInterval);
|
||||||
@@ -79,7 +79,7 @@ export const useSources = (repository: Repository, opts: UseSourcesOptions = Use
|
|||||||
fetchNextPage: () => {
|
fetchNextPage: () => {
|
||||||
// wrapped because we do not want to leak react-query types in our api
|
// wrapped because we do not want to leak react-query types in our api
|
||||||
fetchNextPage();
|
fetchNextPage();
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -108,8 +108,8 @@ const merge = (files?: File[]): File | undefined => {
|
|||||||
...lastPage,
|
...lastPage,
|
||||||
_embedded: {
|
_embedded: {
|
||||||
...lastPage._embedded,
|
...lastPage._embedded,
|
||||||
children
|
children,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -36,9 +36,9 @@ describe("Test Tag hooks", () => {
|
|||||||
type: "git",
|
type: "git",
|
||||||
_links: {
|
_links: {
|
||||||
tags: {
|
tags: {
|
||||||
href: "/hog/tags"
|
href: "/hog/tags",
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const changeset: Changeset = {
|
const changeset: Changeset = {
|
||||||
@@ -46,14 +46,14 @@ describe("Test Tag hooks", () => {
|
|||||||
description: "Awesome change",
|
description: "Awesome change",
|
||||||
date: new Date(),
|
date: new Date(),
|
||||||
author: {
|
author: {
|
||||||
name: "Arthur Dent"
|
name: "Arthur Dent",
|
||||||
},
|
},
|
||||||
_embedded: {},
|
_embedded: {},
|
||||||
_links: {
|
_links: {
|
||||||
tag: {
|
tag: {
|
||||||
href: "/hog/tag"
|
href: "/hog/tag",
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const tagOneDotZero = {
|
const tagOneDotZero = {
|
||||||
@@ -61,17 +61,17 @@ describe("Test Tag hooks", () => {
|
|||||||
revision: "42",
|
revision: "42",
|
||||||
signatures: [],
|
signatures: [],
|
||||||
_links: {
|
_links: {
|
||||||
"delete": {
|
delete: {
|
||||||
href: "/hog/tags/1.0"
|
href: "/hog/tags/1.0",
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const tags: TagCollection = {
|
const tags: TagCollection = {
|
||||||
_embedded: {
|
_embedded: {
|
||||||
tags: [tagOneDotZero]
|
tags: [tagOneDotZero],
|
||||||
},
|
},
|
||||||
_links: {}
|
_links: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
const queryClient = createInfiniteCachingClient();
|
const queryClient = createInfiniteCachingClient();
|
||||||
@@ -87,7 +87,7 @@ describe("Test Tag hooks", () => {
|
|||||||
fetchMock.getOnce("/api/v2/hog/tags", tags);
|
fetchMock.getOnce("/api/v2/hog/tags", tags);
|
||||||
|
|
||||||
const { result, waitFor } = renderHook(() => useTags(repository), {
|
const { result, waitFor } = renderHook(() => useTags(repository), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
await waitFor(() => {
|
await waitFor(() => {
|
||||||
return !!result.current.data;
|
return !!result.current.data;
|
||||||
@@ -114,7 +114,7 @@ describe("Test Tag hooks", () => {
|
|||||||
fetchMock.getOnce("/api/v2/hog/tags/1.0", tagOneDotZero);
|
fetchMock.getOnce("/api/v2/hog/tags/1.0", tagOneDotZero);
|
||||||
|
|
||||||
const { result, waitFor } = renderHook(() => useTag(repository, "1.0"), {
|
const { result, waitFor } = renderHook(() => useTag(repository, "1.0"), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
await waitFor(() => {
|
await waitFor(() => {
|
||||||
return !!result.current.data;
|
return !!result.current.data;
|
||||||
@@ -141,14 +141,14 @@ describe("Test Tag hooks", () => {
|
|||||||
fetchMock.postOnce("/api/v2/hog/tag", {
|
fetchMock.postOnce("/api/v2/hog/tag", {
|
||||||
status: 201,
|
status: 201,
|
||||||
headers: {
|
headers: {
|
||||||
Location: "/hog/tags/1.0"
|
Location: "/hog/tags/1.0",
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
fetchMock.getOnce("/api/v2/hog/tags/1.0", tagOneDotZero);
|
fetchMock.getOnce("/api/v2/hog/tags/1.0", tagOneDotZero);
|
||||||
|
|
||||||
const { result, waitForNextUpdate } = renderHook(() => useCreateTag(repository, changeset), {
|
const { result, waitForNextUpdate } = renderHook(() => useCreateTag(repository, changeset), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
|
|
||||||
await act(() => {
|
await act(() => {
|
||||||
@@ -195,11 +195,11 @@ describe("Test Tag hooks", () => {
|
|||||||
|
|
||||||
it("should fail without location header", async () => {
|
it("should fail without location header", async () => {
|
||||||
fetchMock.postOnce("/api/v2/hog/tag", {
|
fetchMock.postOnce("/api/v2/hog/tag", {
|
||||||
status: 201
|
status: 201,
|
||||||
});
|
});
|
||||||
|
|
||||||
const { result, waitForNextUpdate } = renderHook(() => useCreateTag(repository, changeset), {
|
const { result, waitForNextUpdate } = renderHook(() => useCreateTag(repository, changeset), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
|
|
||||||
await act(() => {
|
await act(() => {
|
||||||
@@ -215,11 +215,11 @@ describe("Test Tag hooks", () => {
|
|||||||
describe("useDeleteTags tests", () => {
|
describe("useDeleteTags tests", () => {
|
||||||
const deleteTag = async () => {
|
const deleteTag = async () => {
|
||||||
fetchMock.deleteOnce("/api/v2/hog/tags/1.0", {
|
fetchMock.deleteOnce("/api/v2/hog/tags/1.0", {
|
||||||
status: 204
|
status: 204,
|
||||||
});
|
});
|
||||||
|
|
||||||
const { result, waitForNextUpdate } = renderHook(() => useDeleteTag(repository), {
|
const { result, waitForNextUpdate } = renderHook(() => useDeleteTag(repository), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
|
|
||||||
await act(() => {
|
await act(() => {
|
||||||
|
|||||||
@@ -28,9 +28,9 @@ const createInfiniteCachingClient = () => {
|
|||||||
return new QueryClient({
|
return new QueryClient({
|
||||||
defaultOptions: {
|
defaultOptions: {
|
||||||
queries: {
|
queries: {
|
||||||
staleTime: Infinity
|
staleTime: Infinity,
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -22,22 +22,22 @@
|
|||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { QueryClient} from "react-query";
|
import { QueryClient } from "react-query";
|
||||||
|
|
||||||
export const setIndexLink = (queryClient: QueryClient, name: string, href: string) => {
|
export const setIndexLink = (queryClient: QueryClient, name: string, href: string) => {
|
||||||
queryClient.setQueryData("index", {
|
queryClient.setQueryData("index", {
|
||||||
version: "x.y.z",
|
version: "x.y.z",
|
||||||
_links: {
|
_links: {
|
||||||
[name]: {
|
[name]: {
|
||||||
href: href
|
href: href,
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const setEmptyIndex = (queryClient: QueryClient) => {
|
export const setEmptyIndex = (queryClient: QueryClient) => {
|
||||||
queryClient.setQueryData("index", {
|
queryClient.setQueryData("index", {
|
||||||
version: "x.y.z",
|
version: "x.y.z",
|
||||||
_links: {}
|
_links: {},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -22,12 +22,7 @@
|
|||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {
|
import { concat, getNamespaceAndPageFromMatch, getQueryStringFromLocation, withEndingSlash } from "./urls";
|
||||||
concat,
|
|
||||||
getNamespaceAndPageFromMatch,
|
|
||||||
getQueryStringFromLocation,
|
|
||||||
withEndingSlash
|
|
||||||
} from "./urls";
|
|
||||||
|
|
||||||
describe("tests for withEndingSlash", () => {
|
describe("tests for withEndingSlash", () => {
|
||||||
it("should append missing slash", () => {
|
it("should append missing slash", () => {
|
||||||
@@ -50,7 +45,7 @@ describe("concat tests", () => {
|
|||||||
describe("tests for getNamespaceAndPageFromMatch", () => {
|
describe("tests for getNamespaceAndPageFromMatch", () => {
|
||||||
function createMatch(namespace?: string, page?: string) {
|
function createMatch(namespace?: string, page?: string) {
|
||||||
return {
|
return {
|
||||||
params: { namespace, page }
|
params: { namespace, page },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,7 +83,7 @@ describe("tests for getNamespaceAndPageFromMatch", () => {
|
|||||||
describe("tests for getQueryStringFromLocation", () => {
|
describe("tests for getQueryStringFromLocation", () => {
|
||||||
function createLocation(search: string) {
|
function createLocation(search: string) {
|
||||||
return {
|
return {
|
||||||
search
|
search,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ import {
|
|||||||
useDeleteUser,
|
useDeleteUser,
|
||||||
useUpdateUser,
|
useUpdateUser,
|
||||||
useUser,
|
useUser,
|
||||||
useUsers
|
useUsers,
|
||||||
} from "./users";
|
} from "./users";
|
||||||
|
|
||||||
describe("Test user hooks", () => {
|
describe("Test user hooks", () => {
|
||||||
@@ -48,21 +48,21 @@ describe("Test user hooks", () => {
|
|||||||
name: "yoda",
|
name: "yoda",
|
||||||
_links: {
|
_links: {
|
||||||
delete: {
|
delete: {
|
||||||
href: "/users/yoda"
|
href: "/users/yoda",
|
||||||
},
|
},
|
||||||
update: {
|
update: {
|
||||||
href: "/users/yoda"
|
href: "/users/yoda",
|
||||||
},
|
},
|
||||||
convertToInternal: {
|
convertToInternal: {
|
||||||
href: "/users/yoda/convertToInternal"
|
href: "/users/yoda/convertToInternal",
|
||||||
},
|
},
|
||||||
convertToExternal: {
|
convertToExternal: {
|
||||||
href: "/users/yoda/convertToExternal"
|
href: "/users/yoda/convertToExternal",
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
_embedded: {
|
_embedded: {
|
||||||
members: []
|
members: [],
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const userCollection: UserCollection = {
|
const userCollection: UserCollection = {
|
||||||
@@ -70,8 +70,8 @@ describe("Test user hooks", () => {
|
|||||||
page: 0,
|
page: 0,
|
||||||
pageTotal: 0,
|
pageTotal: 0,
|
||||||
_embedded: {
|
_embedded: {
|
||||||
users: [yoda]
|
users: [yoda],
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
@@ -84,7 +84,7 @@ describe("Test user hooks", () => {
|
|||||||
setIndexLink(queryClient, "users", "/users");
|
setIndexLink(queryClient, "users", "/users");
|
||||||
fetchMock.get("/api/v2/users", userCollection);
|
fetchMock.get("/api/v2/users", userCollection);
|
||||||
const { result, waitFor } = renderHook(() => useUsers(), {
|
const { result, waitFor } = renderHook(() => useUsers(), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
await waitFor(() => !!result.current.data);
|
await waitFor(() => !!result.current.data);
|
||||||
expect(result.current.data).toEqual(userCollection);
|
expect(result.current.data).toEqual(userCollection);
|
||||||
@@ -95,11 +95,11 @@ describe("Test user hooks", () => {
|
|||||||
setIndexLink(queryClient, "users", "/users");
|
setIndexLink(queryClient, "users", "/users");
|
||||||
fetchMock.get("/api/v2/users", userCollection, {
|
fetchMock.get("/api/v2/users", userCollection, {
|
||||||
query: {
|
query: {
|
||||||
page: "42"
|
page: "42",
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
const { result, waitFor } = renderHook(() => useUsers({ page: 42 }), {
|
const { result, waitFor } = renderHook(() => useUsers({ page: 42 }), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
await waitFor(() => !!result.current.data);
|
await waitFor(() => !!result.current.data);
|
||||||
expect(result.current.data).toEqual(userCollection);
|
expect(result.current.data).toEqual(userCollection);
|
||||||
@@ -110,11 +110,11 @@ describe("Test user hooks", () => {
|
|||||||
setIndexLink(queryClient, "users", "/users");
|
setIndexLink(queryClient, "users", "/users");
|
||||||
fetchMock.get("/api/v2/users", userCollection, {
|
fetchMock.get("/api/v2/users", userCollection, {
|
||||||
query: {
|
query: {
|
||||||
q: "yoda"
|
q: "yoda",
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
const { result, waitFor } = renderHook(() => useUsers({ search: "yoda" }), {
|
const { result, waitFor } = renderHook(() => useUsers({ search: "yoda" }), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
await waitFor(() => !!result.current.data);
|
await waitFor(() => !!result.current.data);
|
||||||
expect(result.current.data).toEqual(userCollection);
|
expect(result.current.data).toEqual(userCollection);
|
||||||
@@ -125,7 +125,7 @@ describe("Test user hooks", () => {
|
|||||||
setIndexLink(queryClient, "users", "/users");
|
setIndexLink(queryClient, "users", "/users");
|
||||||
fetchMock.get("/api/v2/users", userCollection);
|
fetchMock.get("/api/v2/users", userCollection);
|
||||||
const { result, waitFor } = renderHook(() => useUsers(), {
|
const { result, waitFor } = renderHook(() => useUsers(), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
await waitFor(() => !!result.current.data);
|
await waitFor(() => !!result.current.data);
|
||||||
expect(queryClient.getQueryData(["user", "yoda"])).toEqual(yoda);
|
expect(queryClient.getQueryData(["user", "yoda"])).toEqual(yoda);
|
||||||
@@ -138,7 +138,7 @@ describe("Test user hooks", () => {
|
|||||||
setIndexLink(queryClient, "users", "/users");
|
setIndexLink(queryClient, "users", "/users");
|
||||||
fetchMock.get("/api/v2/users/yoda", yoda);
|
fetchMock.get("/api/v2/users/yoda", yoda);
|
||||||
const { result, waitFor } = renderHook(() => useUser("yoda"), {
|
const { result, waitFor } = renderHook(() => useUser("yoda"), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
await waitFor(() => !!result.current.data);
|
await waitFor(() => !!result.current.data);
|
||||||
expect(result.current.data).toEqual(yoda);
|
expect(result.current.data).toEqual(yoda);
|
||||||
@@ -153,14 +153,14 @@ describe("Test user hooks", () => {
|
|||||||
fetchMock.postOnce("/api/v2/users", {
|
fetchMock.postOnce("/api/v2/users", {
|
||||||
status: 201,
|
status: 201,
|
||||||
headers: {
|
headers: {
|
||||||
Location: "/users/yoda"
|
Location: "/users/yoda",
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
fetchMock.getOnce("/api/v2/users/yoda", yoda);
|
fetchMock.getOnce("/api/v2/users/yoda", yoda);
|
||||||
|
|
||||||
const { result, waitForNextUpdate } = renderHook(() => useCreateUser(), {
|
const { result, waitForNextUpdate } = renderHook(() => useCreateUser(), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
|
|
||||||
await act(() => {
|
await act(() => {
|
||||||
@@ -177,13 +177,13 @@ describe("Test user hooks", () => {
|
|||||||
setIndexLink(queryClient, "users", "/users");
|
setIndexLink(queryClient, "users", "/users");
|
||||||
|
|
||||||
fetchMock.postOnce("/api/v2/users", {
|
fetchMock.postOnce("/api/v2/users", {
|
||||||
status: 201
|
status: 201,
|
||||||
});
|
});
|
||||||
|
|
||||||
fetchMock.getOnce("/api/v2/users/yoda", yoda);
|
fetchMock.getOnce("/api/v2/users/yoda", yoda);
|
||||||
|
|
||||||
const { result, waitForNextUpdate } = renderHook(() => useCreateUser(), {
|
const { result, waitForNextUpdate } = renderHook(() => useCreateUser(), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
|
|
||||||
await act(() => {
|
await act(() => {
|
||||||
@@ -202,11 +202,11 @@ describe("Test user hooks", () => {
|
|||||||
setIndexLink(queryClient, "users", "/users");
|
setIndexLink(queryClient, "users", "/users");
|
||||||
|
|
||||||
fetchMock.deleteOnce("/api/v2/users/yoda", {
|
fetchMock.deleteOnce("/api/v2/users/yoda", {
|
||||||
status: 200
|
status: 200,
|
||||||
});
|
});
|
||||||
|
|
||||||
const { result, waitForNextUpdate } = renderHook(() => useDeleteUser(), {
|
const { result, waitForNextUpdate } = renderHook(() => useDeleteUser(), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
|
|
||||||
await act(() => {
|
await act(() => {
|
||||||
@@ -229,17 +229,17 @@ describe("Test user hooks", () => {
|
|||||||
|
|
||||||
const newJedis = {
|
const newJedis = {
|
||||||
...yoda,
|
...yoda,
|
||||||
description: "may the 4th be with you"
|
description: "may the 4th be with you",
|
||||||
};
|
};
|
||||||
|
|
||||||
fetchMock.putOnce("/api/v2/users/yoda", {
|
fetchMock.putOnce("/api/v2/users/yoda", {
|
||||||
status: 200
|
status: 200,
|
||||||
});
|
});
|
||||||
|
|
||||||
fetchMock.getOnce("/api/v2/users/yoda", newJedis);
|
fetchMock.getOnce("/api/v2/users/yoda", newJedis);
|
||||||
|
|
||||||
const { result, waitForNextUpdate } = renderHook(() => useUpdateUser(), {
|
const { result, waitForNextUpdate } = renderHook(() => useUpdateUser(), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
|
|
||||||
await act(() => {
|
await act(() => {
|
||||||
@@ -261,11 +261,11 @@ describe("Test user hooks", () => {
|
|||||||
const queryClient = createInfiniteCachingClient();
|
const queryClient = createInfiniteCachingClient();
|
||||||
|
|
||||||
fetchMock.putOnce("/api/v2/users/yoda/convertToInternal", {
|
fetchMock.putOnce("/api/v2/users/yoda/convertToInternal", {
|
||||||
status: 200
|
status: 200,
|
||||||
});
|
});
|
||||||
|
|
||||||
const { result, waitForNextUpdate } = renderHook(() => useConvertToInternal(), {
|
const { result, waitForNextUpdate } = renderHook(() => useConvertToInternal(), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
|
|
||||||
await act(() => {
|
await act(() => {
|
||||||
@@ -287,11 +287,11 @@ describe("Test user hooks", () => {
|
|||||||
const queryClient = createInfiniteCachingClient();
|
const queryClient = createInfiniteCachingClient();
|
||||||
|
|
||||||
fetchMock.putOnce("/api/v2/users/yoda/convertToExternal", {
|
fetchMock.putOnce("/api/v2/users/yoda/convertToExternal", {
|
||||||
status: 200
|
status: 200,
|
||||||
});
|
});
|
||||||
|
|
||||||
const { result, waitForNextUpdate } = renderHook(() => useConvertToExternal(), {
|
const { result, waitForNextUpdate } = renderHook(() => useConvertToExternal(), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
|
|
||||||
await act(() => {
|
await act(() => {
|
||||||
|
|||||||
@@ -24,6 +24,6 @@
|
|||||||
|
|
||||||
export const createQueryString = (params: Record<string, string>) => {
|
export const createQueryString = (params: Record<string, string>) => {
|
||||||
return Object.keys(params)
|
return Object.keys(params)
|
||||||
.map(k => encodeURIComponent(k) + "=" + encodeURIComponent(params[k]))
|
.map((k) => encodeURIComponent(k) + "=" + encodeURIComponent(params[k]))
|
||||||
.join("&");
|
.join("&");
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ class Autocomplete extends React.Component<Props, State> {
|
|||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
placeholder: "Type here",
|
placeholder: "Type here",
|
||||||
loadingMessage: "Loading...",
|
loadingMessage: "Loading...",
|
||||||
noOptionsMessage: "No suggestion available"
|
noOptionsMessage: "No suggestion available",
|
||||||
};
|
};
|
||||||
|
|
||||||
handleInputChange = (newValue: ValueType<SelectValue>, action: ActionMeta) => {
|
handleInputChange = (newValue: ValueType<SelectValue>, action: ActionMeta) => {
|
||||||
@@ -64,7 +64,7 @@ class Autocomplete extends React.Component<Props, State> {
|
|||||||
selectValue: ValueType<SelectValue>,
|
selectValue: ValueType<SelectValue>,
|
||||||
selectOptions: readonly SelectValue[]
|
selectOptions: readonly SelectValue[]
|
||||||
): boolean => {
|
): boolean => {
|
||||||
const isNotDuplicated = !selectOptions.map(option => option.label).includes(inputValue);
|
const isNotDuplicated = !selectOptions.map((option) => option.label).includes(inputValue);
|
||||||
const isNotEmpty = inputValue !== "";
|
const isNotEmpty = inputValue !== "";
|
||||||
return isNotEmpty && isNotDuplicated;
|
return isNotEmpty && isNotDuplicated;
|
||||||
};
|
};
|
||||||
@@ -79,7 +79,7 @@ class Autocomplete extends React.Component<Props, State> {
|
|||||||
noOptionsMessage,
|
noOptionsMessage,
|
||||||
loadSuggestions,
|
loadSuggestions,
|
||||||
creatable,
|
creatable,
|
||||||
className
|
className,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
return (
|
return (
|
||||||
<div className={classNames("field", className)}>
|
<div className={classNames("field", className)}>
|
||||||
@@ -95,13 +95,13 @@ class Autocomplete extends React.Component<Props, State> {
|
|||||||
loadingMessage={() => loadingMessage}
|
loadingMessage={() => loadingMessage}
|
||||||
noOptionsMessage={() => noOptionsMessage}
|
noOptionsMessage={() => noOptionsMessage}
|
||||||
isValidNewOption={this.isValidNewOption}
|
isValidNewOption={this.isValidNewOption}
|
||||||
onCreateOption={value => {
|
onCreateOption={(value) => {
|
||||||
this.selectValue({
|
this.selectValue({
|
||||||
label: value,
|
label: value,
|
||||||
value: {
|
value: {
|
||||||
id: value,
|
id: value,
|
||||||
displayName: value
|
displayName: value,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -41,5 +41,5 @@ const Wrapper = styled.div`
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
storiesOf("BranchSelector", module)
|
storiesOf("BranchSelector", module)
|
||||||
.addDecorator(storyFn => <Wrapper>{storyFn()}</Wrapper>)
|
.addDecorator((storyFn) => <Wrapper>{storyFn()}</Wrapper>)
|
||||||
.add("Default", () => <BranchSelector branches={branches} onSelectBranch={branchSelected} label="Select Branch" />);
|
.add("Default", () => <BranchSelector branches={branches} onSelectBranch={branchSelected} label="Select Branch" />);
|
||||||
|
|||||||
@@ -128,7 +128,10 @@ const Breadcrumb: FC<Props> = ({
|
|||||||
if (path) {
|
if (path) {
|
||||||
const paths = path.split("/");
|
const paths = path.split("/");
|
||||||
return paths.map((pathFragment, index) => {
|
return paths.map((pathFragment, index) => {
|
||||||
let currPath = paths.slice(0, index + 1).map(encodeURIComponent).join("/");
|
let currPath = paths
|
||||||
|
.slice(0, index + 1)
|
||||||
|
.map(encodeURIComponent)
|
||||||
|
.join("/");
|
||||||
if (!currPath.endsWith("/")) {
|
if (!currPath.endsWith("/")) {
|
||||||
currPath = currPath + "/";
|
currPath = currPath + "/";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,8 +43,8 @@ const footerRight = <small>right footer</small>;
|
|||||||
const baseDate = "2020-03-26T12:13:42+02:00";
|
const baseDate = "2020-03-26T12:13:42+02:00";
|
||||||
|
|
||||||
storiesOf("CardColumn", module)
|
storiesOf("CardColumn", module)
|
||||||
.addDecorator(story => <MemoryRouter initialEntries={["/"]}>{story()}</MemoryRouter>)
|
.addDecorator((story) => <MemoryRouter initialEntries={["/"]}>{story()}</MemoryRouter>)
|
||||||
.addDecorator(storyFn => <Wrapper>{storyFn()}</Wrapper>)
|
.addDecorator((storyFn) => <Wrapper>{storyFn()}</Wrapper>)
|
||||||
.add("Default", () => (
|
.add("Default", () => (
|
||||||
<CardColumn
|
<CardColumn
|
||||||
link={link}
|
link={link}
|
||||||
|
|||||||
@@ -69,13 +69,12 @@ const CardColumn: FC<Props> = ({
|
|||||||
createLink = <Link className="overlay-column" to={link} />;
|
createLink = <Link className="overlay-column" to={link} />;
|
||||||
} else if (action) {
|
} else if (action) {
|
||||||
createLink = (
|
createLink = (
|
||||||
<a
|
<button
|
||||||
className="overlay-column"
|
className="overlay-column"
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
action();
|
action();
|
||||||
}}
|
}}
|
||||||
href="#"
|
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ type Props = {
|
|||||||
className?: string;
|
className?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
const HelpIcon: FC<Props> = ({ className }) => <Icon name="question-circle" color="blue-light" className={className} alt="" />;
|
const HelpIcon: FC<Props> = ({ className }) => (
|
||||||
|
<Icon name="question-circle" color="blue-light" className={className} alt="" />
|
||||||
|
);
|
||||||
|
|
||||||
export default HelpIcon;
|
export default HelpIcon;
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ const colors = ["primary", "link", "info", "success", "warning", "danger", "whit
|
|||||||
const sizing = ["xs", "sm", "lg", "2x", "3x", "5x", "7x", "10x"];
|
const sizing = ["xs", "sm", "lg", "2x", "3x", "5x", "7x", "10x"];
|
||||||
|
|
||||||
storiesOf("Icon", module)
|
storiesOf("Icon", module)
|
||||||
.addDecorator(storyFn => <Wrapper>{storyFn()}</Wrapper>)
|
.addDecorator((storyFn) => <Wrapper>{storyFn()}</Wrapper>)
|
||||||
.add("Default", () => (
|
.add("Default", () => (
|
||||||
<>
|
<>
|
||||||
<Icon name="cat" />
|
<Icon name="cat" />
|
||||||
@@ -48,7 +48,7 @@ storiesOf("Icon", module)
|
|||||||
.add("Colors", () => (
|
.add("Colors", () => (
|
||||||
<>
|
<>
|
||||||
<Icon title="default color" name="cat" />
|
<Icon title="default color" name="cat" />
|
||||||
{colors.map(color => (
|
{colors.map((color) => (
|
||||||
<Icon key={color} title={color} name="cat" color={color} />
|
<Icon key={color} title={color} name="cat" color={color} />
|
||||||
))}
|
))}
|
||||||
</>
|
</>
|
||||||
@@ -56,7 +56,7 @@ storiesOf("Icon", module)
|
|||||||
.add("Sizing", () => (
|
.add("Sizing", () => (
|
||||||
<>
|
<>
|
||||||
<Icon title="default size" name="cat" />
|
<Icon title="default size" name="cat" />
|
||||||
{sizing.map(size => (
|
{sizing.map((size) => (
|
||||||
<Icon key={size} title={"fa-" + size} name={"cat fa-" + size} />
|
<Icon key={size} title={"fa-" + size} name={"cat fa-" + size} />
|
||||||
))}
|
))}
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ const RoutingDecorator = (story: () => ReactNode) => <MemoryRouter initialEntrie
|
|||||||
|
|
||||||
storiesOf("Notification", module)
|
storiesOf("Notification", module)
|
||||||
.addDecorator(RoutingDecorator)
|
.addDecorator(RoutingDecorator)
|
||||||
.addDecorator(storyFn => <Wrapper>{storyFn()}</Wrapper>)
|
.addDecorator((storyFn) => <Wrapper>{storyFn()}</Wrapper>)
|
||||||
.add("Primary", () => <Notification type="primary">{content}</Notification>)
|
.add("Primary", () => <Notification type="primary">{content}</Notification>)
|
||||||
.add("Success", () => <Notification type="success">{content}</Notification>)
|
.add("Success", () => <Notification type="success">{content}</Notification>)
|
||||||
.add("Info", () => <Notification type="info">{content}</Notification>)
|
.add("Info", () => <Notification type="info">{content}</Notification>)
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ import Paginator from "./Paginator";
|
|||||||
|
|
||||||
xdescribe("paginator rendering tests", () => {
|
xdescribe("paginator rendering tests", () => {
|
||||||
const dummyLink = {
|
const dummyLink = {
|
||||||
href: "https://dummy"
|
href: "https://dummy",
|
||||||
};
|
};
|
||||||
|
|
||||||
it("should render all buttons but disabled, without links", () => {
|
it("should render all buttons but disabled, without links", () => {
|
||||||
@@ -36,13 +36,13 @@ xdescribe("paginator rendering tests", () => {
|
|||||||
page: 10,
|
page: 10,
|
||||||
pageTotal: 20,
|
pageTotal: 20,
|
||||||
_links: {},
|
_links: {},
|
||||||
_embedded: {}
|
_embedded: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
const paginator = shallow(<Paginator collection={collection} />);
|
const paginator = shallow(<Paginator collection={collection} />);
|
||||||
const buttons = paginator.find("Button");
|
const buttons = paginator.find("Button");
|
||||||
expect(buttons.length).toBe(7);
|
expect(buttons.length).toBe(7);
|
||||||
buttons.forEach(button => {
|
buttons.forEach((button) => {
|
||||||
// @ts-ignore ???
|
// @ts-ignore ???
|
||||||
expect(button.props.disabled).toBeTruthy();
|
expect(button.props.disabled).toBeTruthy();
|
||||||
});
|
});
|
||||||
@@ -55,9 +55,9 @@ xdescribe("paginator rendering tests", () => {
|
|||||||
_links: {
|
_links: {
|
||||||
first: dummyLink,
|
first: dummyLink,
|
||||||
next: dummyLink,
|
next: dummyLink,
|
||||||
last: dummyLink
|
last: dummyLink,
|
||||||
},
|
},
|
||||||
_embedded: {}
|
_embedded: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
const paginator = shallow(<Paginator collection={collection} />);
|
const paginator = shallow(<Paginator collection={collection} />);
|
||||||
@@ -92,9 +92,9 @@ xdescribe("paginator rendering tests", () => {
|
|||||||
first: dummyLink,
|
first: dummyLink,
|
||||||
prev: dummyLink,
|
prev: dummyLink,
|
||||||
next: dummyLink,
|
next: dummyLink,
|
||||||
last: dummyLink
|
last: dummyLink,
|
||||||
},
|
},
|
||||||
_embedded: {}
|
_embedded: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
const paginator = shallow(<Paginator collection={collection} />);
|
const paginator = shallow(<Paginator collection={collection} />);
|
||||||
@@ -132,9 +132,9 @@ xdescribe("paginator rendering tests", () => {
|
|||||||
pageTotal: 148,
|
pageTotal: 148,
|
||||||
_links: {
|
_links: {
|
||||||
first: dummyLink,
|
first: dummyLink,
|
||||||
prev: dummyLink
|
prev: dummyLink,
|
||||||
},
|
},
|
||||||
_embedded: {}
|
_embedded: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
const paginator = shallow(<Paginator collection={collection} />);
|
const paginator = shallow(<Paginator collection={collection} />);
|
||||||
@@ -169,9 +169,9 @@ xdescribe("paginator rendering tests", () => {
|
|||||||
first: dummyLink,
|
first: dummyLink,
|
||||||
prev: dummyLink,
|
prev: dummyLink,
|
||||||
next: dummyLink,
|
next: dummyLink,
|
||||||
last: dummyLink
|
last: dummyLink,
|
||||||
},
|
},
|
||||||
_embedded: {}
|
_embedded: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
const paginator = shallow(<Paginator collection={collection} />);
|
const paginator = shallow(<Paginator collection={collection} />);
|
||||||
@@ -211,9 +211,9 @@ xdescribe("paginator rendering tests", () => {
|
|||||||
first: dummyLink,
|
first: dummyLink,
|
||||||
prev: dummyLink,
|
prev: dummyLink,
|
||||||
next: dummyLink,
|
next: dummyLink,
|
||||||
last: dummyLink
|
last: dummyLink,
|
||||||
},
|
},
|
||||||
_embedded: {}
|
_embedded: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
const paginator = shallow(<Paginator collection={collection} />);
|
const paginator = shallow(<Paginator collection={collection} />);
|
||||||
@@ -258,12 +258,12 @@ xdescribe("paginator rendering tests", () => {
|
|||||||
_links: {
|
_links: {
|
||||||
first: dummyLink,
|
first: dummyLink,
|
||||||
prev: {
|
prev: {
|
||||||
href: "https://www.scm-manager.org"
|
href: "https://www.scm-manager.org",
|
||||||
},
|
},
|
||||||
next: dummyLink,
|
next: dummyLink,
|
||||||
last: dummyLink
|
last: dummyLink,
|
||||||
},
|
},
|
||||||
_embedded: {}
|
_embedded: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
let urlToOpen;
|
let urlToOpen;
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ class ProtectedRoute extends Component<Props> {
|
|||||||
constructor(props: Props) {
|
constructor(props: Props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
error: undefined
|
error: undefined,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,8 +49,8 @@ class ProtectedRoute extends Component<Props> {
|
|||||||
to={{
|
to={{
|
||||||
pathname: "/login",
|
pathname: "/login",
|
||||||
state: {
|
state: {
|
||||||
from: routeProps.location
|
from: routeProps.location,
|
||||||
}
|
},
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ const Tag: FC<Props> = ({
|
|||||||
}
|
}
|
||||||
let showDelete = null;
|
let showDelete = null;
|
||||||
if (onRemove) {
|
if (onRemove) {
|
||||||
showDelete = <a className="tag is-delete" onClick={onRemove} />;
|
showDelete = <button className="tag is-delete" onClick={onRemove} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -46,40 +46,40 @@ export default {
|
|||||||
type: "normal",
|
type: "normal",
|
||||||
oldLineNumber: 5,
|
oldLineNumber: 5,
|
||||||
newLineNumber: 5,
|
newLineNumber: 5,
|
||||||
isNormal: true
|
isNormal: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
content: "and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).",
|
content: "and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).",
|
||||||
type: "normal",
|
type: "normal",
|
||||||
oldLineNumber: 6,
|
oldLineNumber: 6,
|
||||||
newLineNumber: 6,
|
newLineNumber: 6,
|
||||||
isNormal: true
|
isNormal: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
content: "",
|
content: "",
|
||||||
type: "normal",
|
type: "normal",
|
||||||
oldLineNumber: 7,
|
oldLineNumber: 7,
|
||||||
newLineNumber: 7,
|
newLineNumber: 7,
|
||||||
isNormal: true
|
isNormal: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
content: "## Unreleased",
|
content: "## Unreleased",
|
||||||
type: "delete",
|
type: "delete",
|
||||||
lineNumber: 8,
|
lineNumber: 8,
|
||||||
isDelete: true
|
isDelete: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
content: "## [2.7.1] - 2020-10-14",
|
content: "## [2.7.1] - 2020-10-14",
|
||||||
type: "insert",
|
type: "insert",
|
||||||
lineNumber: 8,
|
lineNumber: 8,
|
||||||
isInsert: true
|
isInsert: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
content: "### Fixed",
|
content: "### Fixed",
|
||||||
type: "normal",
|
type: "normal",
|
||||||
oldLineNumber: 9,
|
oldLineNumber: 9,
|
||||||
newLineNumber: 9,
|
newLineNumber: 9,
|
||||||
isNormal: true
|
isNormal: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
content:
|
content:
|
||||||
@@ -87,7 +87,7 @@ export default {
|
|||||||
type: "normal",
|
type: "normal",
|
||||||
oldLineNumber: 10,
|
oldLineNumber: 10,
|
||||||
newLineNumber: 10,
|
newLineNumber: 10,
|
||||||
isNormal: true
|
isNormal: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
content:
|
content:
|
||||||
@@ -95,24 +95,22 @@ export default {
|
|||||||
type: "normal",
|
type: "normal",
|
||||||
oldLineNumber: 11,
|
oldLineNumber: 11,
|
||||||
newLineNumber: 11,
|
newLineNumber: 11,
|
||||||
isNormal: true
|
isNormal: true,
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
_links: {
|
_links: {
|
||||||
lines: {
|
lines: {
|
||||||
href:
|
href: "http://localhost:8081/scm/api/v2/repositories/scmadmin/scm-manager/content/fbffdea2a566dc4ac54ea38d4aade5aaf541e7f2/CHANGELOG.md?start={start}&end={end}",
|
||||||
"http://localhost:8081/scm/api/v2/repositories/scmadmin/scm-manager/content/fbffdea2a566dc4ac54ea38d4aade5aaf541e7f2/CHANGELOG.md?start={start}&end={end}",
|
templated: true,
|
||||||
templated: true
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
|
||||||
],
|
],
|
||||||
_links: {
|
_links: {
|
||||||
self: {
|
self: {
|
||||||
href:
|
href: "http://localhost:8081/scm/api/v2/repositories/scmadmin/scm-manager/diff/fbffdea2a566dc4ac54ea38d4aade5aaf541e7f2/parsed",
|
||||||
"http://localhost:8081/scm/api/v2/repositories/scmadmin/scm-manager/diff/fbffdea2a566dc4ac54ea38d4aade5aaf541e7f2/parsed"
|
},
|
||||||
}
|
},
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {Changeset, ChangesetCollection, PagedCollection} from "@scm-manager/ui-types";
|
import { Changeset, ChangesetCollection, PagedCollection } from "@scm-manager/ui-types";
|
||||||
|
|
||||||
const one: Changeset = {
|
const one: Changeset = {
|
||||||
id: "a88567ef1e9528a700555cad8c4576b72fc7c6dd",
|
id: "a88567ef1e9528a700555cad8c4576b72fc7c6dd",
|
||||||
@@ -33,31 +33,26 @@ const one: Changeset = {
|
|||||||
contributors: [
|
contributors: [
|
||||||
{
|
{
|
||||||
type: "Committed-by",
|
type: "Committed-by",
|
||||||
person: { mail: "zaphod.beeblebrox@hitchhiker.cm", name: "Zaphod Beeblebrox" }
|
person: { mail: "zaphod.beeblebrox@hitchhiker.cm", name: "Zaphod Beeblebrox" },
|
||||||
},
|
},
|
||||||
{ type: "Co-authored-by", person: { mail: "ford.prefect@hitchhiker.com", name: "Ford Prefect" } }
|
{ type: "Co-authored-by", person: { mail: "ford.prefect@hitchhiker.com", name: "Ford Prefect" } },
|
||||||
],
|
],
|
||||||
_links: {
|
_links: {
|
||||||
self: {
|
self: {
|
||||||
href:
|
href: "http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/changesets/a88567ef1e9528a700555cad8c4576b72fc7c6dd",
|
||||||
"http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/changesets/a88567ef1e9528a700555cad8c4576b72fc7c6dd"
|
|
||||||
},
|
},
|
||||||
diff: {
|
diff: {
|
||||||
href:
|
href: "http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/diff/a88567ef1e9528a700555cad8c4576b72fc7c6dd",
|
||||||
"http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/diff/a88567ef1e9528a700555cad8c4576b72fc7c6dd"
|
|
||||||
},
|
},
|
||||||
sources: {
|
sources: {
|
||||||
href:
|
href: "http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/sources/a88567ef1e9528a700555cad8c4576b72fc7c6dd",
|
||||||
"http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/sources/a88567ef1e9528a700555cad8c4576b72fc7c6dd"
|
|
||||||
},
|
},
|
||||||
modifications: {
|
modifications: {
|
||||||
href:
|
href: "http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/modifications/a88567ef1e9528a700555cad8c4576b72fc7c6dd",
|
||||||
"http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/modifications/a88567ef1e9528a700555cad8c4576b72fc7c6dd"
|
|
||||||
},
|
},
|
||||||
diffParsed: {
|
diffParsed: {
|
||||||
href:
|
href: "http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/diff/a88567ef1e9528a700555cad8c4576b72fc7c6dd/parsed",
|
||||||
"http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/diff/a88567ef1e9528a700555cad8c4576b72fc7c6dd/parsed"
|
},
|
||||||
}
|
|
||||||
},
|
},
|
||||||
_embedded: {
|
_embedded: {
|
||||||
tags: [],
|
tags: [],
|
||||||
@@ -67,17 +62,15 @@ const one: Changeset = {
|
|||||||
id: "d21cc6c359270aef2196796f4d96af65f51866dc",
|
id: "d21cc6c359270aef2196796f4d96af65f51866dc",
|
||||||
_links: {
|
_links: {
|
||||||
self: {
|
self: {
|
||||||
href:
|
href: "http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/changesets/d21cc6c359270aef2196796f4d96af65f51866dc",
|
||||||
"http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/changesets/d21cc6c359270aef2196796f4d96af65f51866dc"
|
|
||||||
},
|
},
|
||||||
diff: {
|
diff: {
|
||||||
href:
|
href: "http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/diff/d21cc6c359270aef2196796f4d96af65f51866dc",
|
||||||
"http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/diff/d21cc6c359270aef2196796f4d96af65f51866dc"
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
],
|
||||||
]
|
},
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const two: Changeset = {
|
const two: Changeset = {
|
||||||
@@ -88,30 +81,25 @@ const two: Changeset = {
|
|||||||
contributors: [
|
contributors: [
|
||||||
{
|
{
|
||||||
type: "Committed-by",
|
type: "Committed-by",
|
||||||
person: { mail: "zaphod.beeblebrox@hitchhiker.cm", name: "Zaphod Beeblebrox" }
|
person: { mail: "zaphod.beeblebrox@hitchhiker.cm", name: "Zaphod Beeblebrox" },
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
_links: {
|
_links: {
|
||||||
self: {
|
self: {
|
||||||
href:
|
href: "http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/changesets/d21cc6c359270aef2196796f4d96af65f51866dc",
|
||||||
"http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/changesets/d21cc6c359270aef2196796f4d96af65f51866dc"
|
|
||||||
},
|
},
|
||||||
diff: {
|
diff: {
|
||||||
href:
|
href: "http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/diff/d21cc6c359270aef2196796f4d96af65f51866dc",
|
||||||
"http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/diff/d21cc6c359270aef2196796f4d96af65f51866dc"
|
|
||||||
},
|
},
|
||||||
sources: {
|
sources: {
|
||||||
href:
|
href: "http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/sources/d21cc6c359270aef2196796f4d96af65f51866dc",
|
||||||
"http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/sources/d21cc6c359270aef2196796f4d96af65f51866dc"
|
|
||||||
},
|
},
|
||||||
modifications: {
|
modifications: {
|
||||||
href:
|
href: "http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/modifications/d21cc6c359270aef2196796f4d96af65f51866dc",
|
||||||
"http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/modifications/d21cc6c359270aef2196796f4d96af65f51866dc"
|
|
||||||
},
|
},
|
||||||
diffParsed: {
|
diffParsed: {
|
||||||
href:
|
href: "http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/diff/d21cc6c359270aef2196796f4d96af65f51866dc/parsed",
|
||||||
"http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/diff/d21cc6c359270aef2196796f4d96af65f51866dc/parsed"
|
},
|
||||||
}
|
|
||||||
},
|
},
|
||||||
_embedded: {
|
_embedded: {
|
||||||
tags: [],
|
tags: [],
|
||||||
@@ -121,17 +109,15 @@ const two: Changeset = {
|
|||||||
id: "e163c8f632db571c9aa51a8eb440e37cf550b825",
|
id: "e163c8f632db571c9aa51a8eb440e37cf550b825",
|
||||||
_links: {
|
_links: {
|
||||||
self: {
|
self: {
|
||||||
href:
|
href: "http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/changesets/e163c8f632db571c9aa51a8eb440e37cf550b825",
|
||||||
"http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/changesets/e163c8f632db571c9aa51a8eb440e37cf550b825"
|
|
||||||
},
|
},
|
||||||
diff: {
|
diff: {
|
||||||
href:
|
href: "http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/diff/e163c8f632db571c9aa51a8eb440e37cf550b825",
|
||||||
"http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/diff/e163c8f632db571c9aa51a8eb440e37cf550b825"
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
],
|
||||||
]
|
},
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const three: Changeset = {
|
const three: Changeset = {
|
||||||
@@ -142,27 +128,22 @@ const three: Changeset = {
|
|||||||
contributors: [],
|
contributors: [],
|
||||||
_links: {
|
_links: {
|
||||||
self: {
|
self: {
|
||||||
href:
|
href: "http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/changesets/e163c8f632db571c9aa51a8eb440e37cf550b825",
|
||||||
"http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/changesets/e163c8f632db571c9aa51a8eb440e37cf550b825"
|
|
||||||
},
|
},
|
||||||
diff: {
|
diff: {
|
||||||
href:
|
href: "http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/diff/e163c8f632db571c9aa51a8eb440e37cf550b825",
|
||||||
"http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/diff/e163c8f632db571c9aa51a8eb440e37cf550b825"
|
|
||||||
},
|
},
|
||||||
sources: {
|
sources: {
|
||||||
href:
|
href: "http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/sources/e163c8f632db571c9aa51a8eb440e37cf550b825",
|
||||||
"http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/sources/e163c8f632db571c9aa51a8eb440e37cf550b825"
|
|
||||||
},
|
},
|
||||||
modifications: {
|
modifications: {
|
||||||
href:
|
href: "http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/modifications/e163c8f632db571c9aa51a8eb440e37cf550b825",
|
||||||
"http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/modifications/e163c8f632db571c9aa51a8eb440e37cf550b825"
|
|
||||||
},
|
},
|
||||||
diffParsed: {
|
diffParsed: {
|
||||||
href:
|
href: "http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/diff/e163c8f632db571c9aa51a8eb440e37cf550b825/parsed",
|
||||||
"http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/diff/e163c8f632db571c9aa51a8eb440e37cf550b825/parsed"
|
},
|
||||||
}
|
|
||||||
},
|
},
|
||||||
_embedded: { tags: [], branches: [], parents: [] }
|
_embedded: { tags: [], branches: [], parents: [] },
|
||||||
};
|
};
|
||||||
|
|
||||||
const four: Changeset = {
|
const four: Changeset = {
|
||||||
@@ -173,29 +154,24 @@ const four: Changeset = {
|
|||||||
contributors: [
|
contributors: [
|
||||||
{ type: "Co-authored-by", person: { mail: "ford.prefect@hitchhiker.com", name: "Ford Prefect" } },
|
{ type: "Co-authored-by", person: { mail: "ford.prefect@hitchhiker.com", name: "Ford Prefect" } },
|
||||||
{ type: "Co-authored-by", person: { mail: "zaphod.beeblebrox@hitchhiker.cm", name: "Zaphod Beeblebrox" } },
|
{ type: "Co-authored-by", person: { mail: "zaphod.beeblebrox@hitchhiker.cm", name: "Zaphod Beeblebrox" } },
|
||||||
{ type: "Co-authored-by", person: { mail: "trillian@hitchhiker.cm", name: "Tricia Marie McMillan" } }
|
{ type: "Co-authored-by", person: { mail: "trillian@hitchhiker.cm", name: "Tricia Marie McMillan" } },
|
||||||
],
|
],
|
||||||
_links: {
|
_links: {
|
||||||
self: {
|
self: {
|
||||||
href:
|
href: "http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/changesets/b6c6f8fbd0d490936fae7d26ffdd4695cc2a0930",
|
||||||
"http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/changesets/b6c6f8fbd0d490936fae7d26ffdd4695cc2a0930"
|
|
||||||
},
|
},
|
||||||
diff: {
|
diff: {
|
||||||
href:
|
href: "http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/diff/b6c6f8fbd0d490936fae7d26ffdd4695cc2a0930",
|
||||||
"http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/diff/b6c6f8fbd0d490936fae7d26ffdd4695cc2a0930"
|
|
||||||
},
|
},
|
||||||
sources: {
|
sources: {
|
||||||
href:
|
href: "http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/sources/b6c6f8fbd0d490936fae7d26ffdd4695cc2a0930",
|
||||||
"http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/sources/b6c6f8fbd0d490936fae7d26ffdd4695cc2a0930"
|
|
||||||
},
|
},
|
||||||
modifications: {
|
modifications: {
|
||||||
href:
|
href: "http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/modifications/b6c6f8fbd0d490936fae7d26ffdd4695cc2a0930",
|
||||||
"http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/modifications/b6c6f8fbd0d490936fae7d26ffdd4695cc2a0930"
|
|
||||||
},
|
},
|
||||||
diffParsed: {
|
diffParsed: {
|
||||||
href:
|
href: "http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/diff/b6c6f8fbd0d490936fae7d26ffdd4695cc2a0930/parsed",
|
||||||
"http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/diff/b6c6f8fbd0d490936fae7d26ffdd4695cc2a0930/parsed"
|
},
|
||||||
}
|
|
||||||
},
|
},
|
||||||
_embedded: {
|
_embedded: {
|
||||||
tags: [],
|
tags: [],
|
||||||
@@ -205,17 +181,15 @@ const four: Changeset = {
|
|||||||
id: "a88567ef1e9528a700555cad8c4576b72fc7c6dd",
|
id: "a88567ef1e9528a700555cad8c4576b72fc7c6dd",
|
||||||
_links: {
|
_links: {
|
||||||
self: {
|
self: {
|
||||||
href:
|
href: "http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/changesets/a88567ef1e9528a700555cad8c4576b72fc7c6dd",
|
||||||
"http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/changesets/a88567ef1e9528a700555cad8c4576b72fc7c6dd"
|
|
||||||
},
|
},
|
||||||
diff: {
|
diff: {
|
||||||
href:
|
href: "http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/diff/a88567ef1e9528a700555cad8c4576b72fc7c6dd",
|
||||||
"http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/diff/a88567ef1e9528a700555cad8c4576b72fc7c6dd"
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
],
|
||||||
]
|
},
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const five: Changeset = {
|
const five: Changeset = {
|
||||||
@@ -225,25 +199,20 @@ const five: Changeset = {
|
|||||||
description: "HOG-42 Change mail to arthur@guide.galaxy\n\n",
|
description: "HOG-42 Change mail to arthur@guide.galaxy\n\n",
|
||||||
_links: {
|
_links: {
|
||||||
self: {
|
self: {
|
||||||
href:
|
href: "http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/changesets/d21cc6c359270aef2196796f4d96af65f51866dc",
|
||||||
"http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/changesets/d21cc6c359270aef2196796f4d96af65f51866dc"
|
|
||||||
},
|
},
|
||||||
diff: {
|
diff: {
|
||||||
href:
|
href: "http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/diff/d21cc6c359270aef2196796f4d96af65f51866dc",
|
||||||
"http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/diff/d21cc6c359270aef2196796f4d96af65f51866dc"
|
|
||||||
},
|
},
|
||||||
sources: {
|
sources: {
|
||||||
href:
|
href: "http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/sources/d21cc6c359270aef2196796f4d96af65f51866dc",
|
||||||
"http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/sources/d21cc6c359270aef2196796f4d96af65f51866dc"
|
|
||||||
},
|
},
|
||||||
modifications: {
|
modifications: {
|
||||||
href:
|
href: "http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/modifications/d21cc6c359270aef2196796f4d96af65f51866dc",
|
||||||
"http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/modifications/d21cc6c359270aef2196796f4d96af65f51866dc"
|
|
||||||
},
|
},
|
||||||
diffParsed: {
|
diffParsed: {
|
||||||
href:
|
href: "http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/diff/d21cc6c359270aef2196796f4d96af65f51866dc/parsed",
|
||||||
"http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/diff/d21cc6c359270aef2196796f4d96af65f51866dc/parsed"
|
},
|
||||||
}
|
|
||||||
},
|
},
|
||||||
_embedded: {
|
_embedded: {
|
||||||
tags: [],
|
tags: [],
|
||||||
@@ -253,17 +222,15 @@ const five: Changeset = {
|
|||||||
id: "e163c8f632db571c9aa51a8eb440e37cf550b825",
|
id: "e163c8f632db571c9aa51a8eb440e37cf550b825",
|
||||||
_links: {
|
_links: {
|
||||||
self: {
|
self: {
|
||||||
href:
|
href: "http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/changesets/e163c8f632db571c9aa51a8eb440e37cf550b825",
|
||||||
"http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/changesets/e163c8f632db571c9aa51a8eb440e37cf550b825"
|
|
||||||
},
|
},
|
||||||
diff: {
|
diff: {
|
||||||
href:
|
href: "http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/diff/e163c8f632db571c9aa51a8eb440e37cf550b825",
|
||||||
"http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/diff/e163c8f632db571c9aa51a8eb440e37cf550b825"
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
],
|
||||||
]
|
},
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const changesets: ChangesetCollection = {
|
const changesets: ChangesetCollection = {
|
||||||
@@ -271,27 +238,24 @@ const changesets: ChangesetCollection = {
|
|||||||
pageTotal: 1,
|
pageTotal: 1,
|
||||||
_links: {
|
_links: {
|
||||||
self: {
|
self: {
|
||||||
href:
|
href: "http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/branches/master/changesets/?page=0&pageSize=10",
|
||||||
"http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/branches/master/changesets/?page=0&pageSize=10"
|
|
||||||
},
|
},
|
||||||
first: {
|
first: {
|
||||||
href:
|
href: "http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/branches/master/changesets/?page=0&pageSize=10",
|
||||||
"http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/branches/master/changesets/?page=0&pageSize=10"
|
|
||||||
},
|
},
|
||||||
last: {
|
last: {
|
||||||
href:
|
href: "http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/branches/master/changesets/?page=0&pageSize=10",
|
||||||
"http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/branches/master/changesets/?page=0&pageSize=10"
|
},
|
||||||
}
|
|
||||||
},
|
},
|
||||||
_embedded: {
|
_embedded: {
|
||||||
changesets: [one, two, three, four],
|
changesets: [one, two, three, four],
|
||||||
branch: {
|
branch: {
|
||||||
name: "master",
|
name: "master",
|
||||||
_links: {
|
_links: {
|
||||||
self: { href: "http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/branches/master" }
|
self: { href: "http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/branches/master" },
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export { one, two, three, four, five };
|
export { one, two, three, four, five };
|
||||||
|
|||||||
@@ -37,31 +37,31 @@ export default {
|
|||||||
permissions: { href: "http://localhost:8081/scm/api/v2/repositories/scmadmin/Git/permissions/" },
|
permissions: { href: "http://localhost:8081/scm/api/v2/repositories/scmadmin/Git/permissions/" },
|
||||||
protocol: [
|
protocol: [
|
||||||
{ href: "ssh://scmadmin@localhost:4567/repo/scmadmin/Git", name: "ssh" },
|
{ href: "ssh://scmadmin@localhost:4567/repo/scmadmin/Git", name: "ssh" },
|
||||||
{ href: "http://localhost:8081/scm/repo/scmadmin/Git", name: "http" }
|
{ href: "http://localhost:8081/scm/repo/scmadmin/Git", name: "http" },
|
||||||
],
|
],
|
||||||
tags: { href: "http://localhost:8081/scm/api/v2/repositories/scmadmin/Git/tags/" },
|
tags: { href: "http://localhost:8081/scm/api/v2/repositories/scmadmin/Git/tags/" },
|
||||||
branches: { href: "http://localhost:8081/scm/api/v2/repositories/scmadmin/Git/branches/" },
|
branches: { href: "http://localhost:8081/scm/api/v2/repositories/scmadmin/Git/branches/" },
|
||||||
incomingChangesets: {
|
incomingChangesets: {
|
||||||
href: "http://localhost:8081/scm/api/v2/repositories/scmadmin/Git/incoming/{source}/{target}/changesets",
|
href: "http://localhost:8081/scm/api/v2/repositories/scmadmin/Git/incoming/{source}/{target}/changesets",
|
||||||
templated: true
|
templated: true,
|
||||||
},
|
},
|
||||||
incomingDiff: {
|
incomingDiff: {
|
||||||
href: "http://localhost:8081/scm/api/v2/repositories/scmadmin/Git/incoming/{source}/{target}/diff",
|
href: "http://localhost:8081/scm/api/v2/repositories/scmadmin/Git/incoming/{source}/{target}/diff",
|
||||||
templated: true
|
templated: true,
|
||||||
},
|
},
|
||||||
incomingDiffParsed: {
|
incomingDiffParsed: {
|
||||||
href: "http://localhost:8081/scm/api/v2/repositories/scmadmin/Git/incoming/{source}/{target}/diff/parsed",
|
href: "http://localhost:8081/scm/api/v2/repositories/scmadmin/Git/incoming/{source}/{target}/diff/parsed",
|
||||||
templated: true
|
templated: true,
|
||||||
},
|
},
|
||||||
changesets: { href: "http://localhost:8081/scm/api/v2/repositories/scmadmin/Git/changesets/" },
|
changesets: { href: "http://localhost:8081/scm/api/v2/repositories/scmadmin/Git/changesets/" },
|
||||||
sources: { href: "http://localhost:8081/scm/api/v2/repositories/scmadmin/Git/sources/" },
|
sources: { href: "http://localhost:8081/scm/api/v2/repositories/scmadmin/Git/sources/" },
|
||||||
authorMappingConfig: {
|
authorMappingConfig: {
|
||||||
href: "http://localhost:8081/scm/api/v2/authormapping/configuration/scmadmin/Git"
|
href: "http://localhost:8081/scm/api/v2/authormapping/configuration/scmadmin/Git",
|
||||||
},
|
},
|
||||||
unfavorize: { href: "http://localhost:8081/scm/api/v2/unfavorize/scmadmin/Git" },
|
unfavorize: { href: "http://localhost:8081/scm/api/v2/unfavorize/scmadmin/Git" },
|
||||||
favorites: [
|
favorites: [
|
||||||
{ href: "http://localhost:8081/scm/api/v2/unfavorize/scmadmin/Git", name: "unfavorize" },
|
{ href: "http://localhost:8081/scm/api/v2/unfavorize/scmadmin/Git", name: "unfavorize" },
|
||||||
{ href: "http://localhost:8081/scm/api/v2/favorize/scmadmin/Git", name: "favorize" }
|
{ href: "http://localhost:8081/scm/api/v2/favorize/scmadmin/Git", name: "favorize" },
|
||||||
]
|
],
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -21,9 +21,9 @@
|
|||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
import React, { MouseEvent, ReactNode } from "react";
|
import React, { FC, MouseEvent, ReactNode } from "react";
|
||||||
import classNames from "classnames";
|
import classNames from "classnames";
|
||||||
import { RouteComponentProps, withRouter } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import Icon from "../Icon";
|
import Icon from "../Icon";
|
||||||
import { createAttributesForTesting } from "../devBuild";
|
import { createAttributesForTesting } from "../devBuild";
|
||||||
|
|
||||||
@@ -42,90 +42,79 @@ export type ButtonProps = {
|
|||||||
testId?: string;
|
testId?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
type Props = ButtonProps &
|
type Props = ButtonProps & {
|
||||||
RouteComponentProps & {
|
type?: "button" | "submit" | "reset";
|
||||||
type?: "button" | "submit" | "reset";
|
color?: string;
|
||||||
color?: string;
|
};
|
||||||
|
|
||||||
|
const Button: FC<Props> = ({
|
||||||
|
link,
|
||||||
|
className,
|
||||||
|
icon,
|
||||||
|
fullWidth,
|
||||||
|
reducedMobile,
|
||||||
|
testId,
|
||||||
|
children,
|
||||||
|
label,
|
||||||
|
type = "button",
|
||||||
|
title,
|
||||||
|
loading,
|
||||||
|
disabled,
|
||||||
|
action,
|
||||||
|
color = "default",
|
||||||
|
}) => {
|
||||||
|
const renderIcon = () => {
|
||||||
|
return <>{icon ? <Icon name={icon} color="inherit" className="is-medium pr-1" /> : null}</>;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Button extends React.Component<Props> {
|
if (link) {
|
||||||
static defaultProps: Partial<Props> = {
|
|
||||||
type: "button",
|
|
||||||
color: "default",
|
|
||||||
};
|
|
||||||
|
|
||||||
onClick = (event: React.MouseEvent) => {
|
|
||||||
const { action, link, history } = this.props;
|
|
||||||
if (action) {
|
|
||||||
action(event);
|
|
||||||
} else if (link) {
|
|
||||||
history.push(link);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const {
|
|
||||||
label,
|
|
||||||
title,
|
|
||||||
loading,
|
|
||||||
disabled,
|
|
||||||
type,
|
|
||||||
color,
|
|
||||||
className,
|
|
||||||
icon,
|
|
||||||
fullWidth,
|
|
||||||
reducedMobile,
|
|
||||||
children,
|
|
||||||
testId,
|
|
||||||
} = this.props;
|
|
||||||
if (icon) {
|
|
||||||
return (
|
|
||||||
<button
|
|
||||||
type={type}
|
|
||||||
title={title}
|
|
||||||
disabled={disabled}
|
|
||||||
onClick={this.onClick}
|
|
||||||
className={classNames(
|
|
||||||
"button",
|
|
||||||
"is-" + color,
|
|
||||||
{ "is-loading": loading },
|
|
||||||
{ "is-fullwidth": fullWidth },
|
|
||||||
{ "is-reduced-mobile": reducedMobile },
|
|
||||||
className
|
|
||||||
)}
|
|
||||||
{...createAttributesForTesting(testId)}
|
|
||||||
>
|
|
||||||
<span className="icon is-medium">
|
|
||||||
<Icon name={icon} color="inherit" />
|
|
||||||
</span>
|
|
||||||
{(label || children) && (
|
|
||||||
<span>
|
|
||||||
{label} {children}
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</button>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<button
|
<Link
|
||||||
type={type}
|
|
||||||
title={title}
|
|
||||||
disabled={disabled}
|
|
||||||
onClick={this.onClick}
|
|
||||||
className={classNames(
|
className={classNames(
|
||||||
"button",
|
"button",
|
||||||
"is-" + color,
|
"is-" + color,
|
||||||
{ "is-loading": loading },
|
{ "is-loading": loading },
|
||||||
{ "is-fullwidth": fullWidth },
|
{ "is-fullwidth": fullWidth },
|
||||||
|
{ "is-reduced-mobile": reducedMobile },
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...createAttributesForTesting(testId)}
|
to={link}
|
||||||
|
aria-label={label}
|
||||||
>
|
>
|
||||||
{label} {children}
|
{renderIcon()}{" "}
|
||||||
</button>
|
{(label || children) && (
|
||||||
|
<>
|
||||||
|
{label} {children}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Link>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
export default withRouter(Button);
|
return (
|
||||||
|
<button
|
||||||
|
type={type}
|
||||||
|
title={title}
|
||||||
|
disabled={disabled}
|
||||||
|
onClick={(event) => action && action(event)}
|
||||||
|
className={classNames(
|
||||||
|
"button",
|
||||||
|
"is-" + color,
|
||||||
|
{ "is-loading": loading },
|
||||||
|
{ "is-fullwidth": fullWidth },
|
||||||
|
{ "is-reduced-mobile": reducedMobile },
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...createAttributesForTesting(testId)}
|
||||||
|
>
|
||||||
|
{renderIcon()}{" "}
|
||||||
|
{(label || children) && (
|
||||||
|
<>
|
||||||
|
{label} {children}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Button;
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ class ButtonAddons extends React.Component<Props> {
|
|||||||
const { className, children } = this.props;
|
const { className, children } = this.props;
|
||||||
|
|
||||||
const childWrapper: ReactNode[] = [];
|
const childWrapper: ReactNode[] = [];
|
||||||
React.Children.forEach(children, child => {
|
React.Children.forEach(children, (child) => {
|
||||||
if (child) {
|
if (child) {
|
||||||
childWrapper.push(
|
childWrapper.push(
|
||||||
<p className="control" key={childWrapper.length}>
|
<p className="control" key={childWrapper.length}>
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ class ButtonGroup extends React.Component<Props> {
|
|||||||
const { className, children } = this.props;
|
const { className, children } = this.props;
|
||||||
|
|
||||||
const childWrapper: ReactNode[] = [];
|
const childWrapper: ReactNode[] = [];
|
||||||
React.Children.forEach(children, child => {
|
React.Children.forEach(children, (child) => {
|
||||||
if (child) {
|
if (child) {
|
||||||
childWrapper.push(
|
childWrapper.push(
|
||||||
<div className="control" key={childWrapper.length}>
|
<div className="control" key={childWrapper.length}>
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ type SubmitButtonProps = ButtonProps & {
|
|||||||
|
|
||||||
class SubmitButton extends React.Component<SubmitButtonProps> {
|
class SubmitButton extends React.Component<SubmitButtonProps> {
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
scrollToTop: true
|
scrollToTop: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ storiesOf("Buttons/Button", module)
|
|||||||
.addDecorator(RoutingDecorator)
|
.addDecorator(RoutingDecorator)
|
||||||
.add("Colors", () => (
|
.add("Colors", () => (
|
||||||
<div>
|
<div>
|
||||||
{colors.map(color => (
|
{colors.map((color) => (
|
||||||
<Spacing key={color}>
|
<Spacing key={color}>
|
||||||
<Button color={color} label={color} />
|
<Button color={color} label={color} />
|
||||||
</Spacing>
|
</Spacing>
|
||||||
@@ -62,7 +62,7 @@ storiesOf("Buttons/Button", module)
|
|||||||
))
|
))
|
||||||
.add("Disabled", () => (
|
.add("Disabled", () => (
|
||||||
<div>
|
<div>
|
||||||
{colors.map(color => (
|
{colors.map((color) => (
|
||||||
<Spacing key={color}>
|
<Spacing key={color}>
|
||||||
<Button color={color} label={color} disabled={true} />
|
<Button color={color} label={color} disabled={true} />
|
||||||
</Spacing>
|
</Spacing>
|
||||||
|
|||||||
@@ -26,12 +26,12 @@ import { byKey, byValueLength, byNestedKeys } from "./comparators";
|
|||||||
|
|
||||||
const createObject = (key: string, value?: string) => {
|
const createObject = (key: string, value?: string) => {
|
||||||
return {
|
return {
|
||||||
[key]: value
|
[key]: value,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const createObjects = (key: string, values: Array<string | undefined>) => {
|
const createObjects = (key: string, values: Array<string | undefined>) => {
|
||||||
return values.map(v => createObject(key, v));
|
return values.map((v) => createObject(key, v));
|
||||||
};
|
};
|
||||||
|
|
||||||
describe("key comparator tests", () => {
|
describe("key comparator tests", () => {
|
||||||
@@ -98,18 +98,18 @@ describe("nested key comparator tests", () => {
|
|||||||
const createObject = (key: string, nested?: string, value?: string) => {
|
const createObject = (key: string, nested?: string, value?: string) => {
|
||||||
if (!nested) {
|
if (!nested) {
|
||||||
return {
|
return {
|
||||||
[key]: undefined
|
[key]: undefined,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
[key]: {
|
[key]: {
|
||||||
[nested]: value
|
[nested]: value,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const createObjects = (key: string, nested: string, values: Array<string | undefined>) => {
|
const createObjects = (key: string, nested: string, values: Array<string | undefined>) => {
|
||||||
return values.map(v => createObject(key, nested, v));
|
return values.map((v) => createObject(key, nested, v));
|
||||||
};
|
};
|
||||||
|
|
||||||
it("should sort array", () => {
|
it("should sort array", () => {
|
||||||
|
|||||||
@@ -95,5 +95,5 @@ export const byNestedKeys = (key: string, nestedKey: string) => {
|
|||||||
export default {
|
export default {
|
||||||
byKey,
|
byKey,
|
||||||
byValueLength,
|
byValueLength,
|
||||||
byNestedKeys
|
byNestedKeys,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ export const createAttributesForTesting = (testId?: string) => {
|
|||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
"data-testid": normalizeTestId(testId)
|
"data-testid": normalizeTestId(testId),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ const AutocompleteAddEntryToTableField: FC<Props> = ({
|
|||||||
loadSuggestions,
|
loadSuggestions,
|
||||||
placeholder,
|
placeholder,
|
||||||
loadingMessage,
|
loadingMessage,
|
||||||
noOptionsMessage
|
noOptionsMessage,
|
||||||
}) => {
|
}) => {
|
||||||
const [selectedValue, setSelectedValue] = useState<SelectValue | undefined>(undefined);
|
const [selectedValue, setSelectedValue] = useState<SelectValue | undefined>(undefined);
|
||||||
|
|
||||||
|
|||||||
@@ -64,8 +64,8 @@ const ReactHookForm: FC = () => {
|
|||||||
const { register, handleSubmit } = useForm<Settings>({
|
const { register, handleSubmit } = useForm<Settings>({
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
disabled: true,
|
disabled: true,
|
||||||
readonly: true
|
readonly: true,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
const [stored, setStored] = useState<Settings>();
|
const [stored, setStored] = useState<Settings>();
|
||||||
|
|
||||||
@@ -106,7 +106,7 @@ const LegacyEvents: FC = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
storiesOf("Forms/Checkbox", module)
|
storiesOf("Forms/Checkbox", module)
|
||||||
.addDecorator(storyFn => <MemoryRouter>{storyFn()}</MemoryRouter>)
|
.addDecorator((storyFn) => <MemoryRouter>{storyFn()}</MemoryRouter>)
|
||||||
.add("Default", () => (
|
.add("Default", () => (
|
||||||
<Spacing>
|
<Spacing>
|
||||||
<Checkbox label="Not checked" checked={false} />
|
<Checkbox label="Not checked" checked={false} />
|
||||||
|
|||||||
@@ -41,10 +41,10 @@ storiesOf("Forms/DropDown", module)
|
|||||||
options={[
|
options={[
|
||||||
"The Hitchhiker's Guide to the Galaxy",
|
"The Hitchhiker's Guide to the Galaxy",
|
||||||
"Dirk Gently’s Holistic Detective Agency",
|
"Dirk Gently’s Holistic Detective Agency",
|
||||||
"The Meaning Of Liff"
|
"The Meaning Of Liff",
|
||||||
]}
|
]}
|
||||||
preselectedOption={"dirk"}
|
preselectedOption={"dirk"}
|
||||||
optionSelected={selection => {
|
optionSelected={(selection) => {
|
||||||
// nothing to do
|
// nothing to do
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
@@ -54,7 +54,7 @@ storiesOf("Forms/DropDown", module)
|
|||||||
optionValues={["alpha", "beta", "gamma"]}
|
optionValues={["alpha", "beta", "gamma"]}
|
||||||
options={["A", "B", "C"]}
|
options={["A", "B", "C"]}
|
||||||
preselectedOption={"D"}
|
preselectedOption={"D"}
|
||||||
optionSelected={selection => {
|
optionSelected={(selection) => {
|
||||||
// nothing to do
|
// nothing to do
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ class DropDown extends React.Component<Props> {
|
|||||||
render() {
|
render() {
|
||||||
const { options, optionValues, preselectedOption, className, disabled } = this.props;
|
const { options, optionValues, preselectedOption, className, disabled } = this.props;
|
||||||
|
|
||||||
if (preselectedOption && options.filter(o => o === preselectedOption).length === 0) {
|
if (preselectedOption && options.filter((o) => o === preselectedOption).length === 0) {
|
||||||
options.push(preselectedOption);
|
options.push(preselectedOption);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ const FilterInput: FC<Props> = ({ filter, value, testId, placeholder, autoFocus,
|
|||||||
type="search"
|
type="search"
|
||||||
placeholder={placeholder || t("filterEntries")}
|
placeholder={placeholder || t("filterEntries")}
|
||||||
value={stateValue}
|
value={stateValue}
|
||||||
onChange={event => setStateValue(event.target.value)}
|
onChange={(event) => setStateValue(event.target.value)}
|
||||||
autoFocus={autoFocus || false}
|
autoFocus={autoFocus || false}
|
||||||
/>
|
/>
|
||||||
<span className="icon is-small is-left">
|
<span className="icon is-small is-left">
|
||||||
|
|||||||
@@ -36,11 +36,11 @@ type Props = WithTranslation & {
|
|||||||
class MemberNameTagGroup extends React.Component<Props> {
|
class MemberNameTagGroup extends React.Component<Props> {
|
||||||
render() {
|
render() {
|
||||||
const { members, label, helpText, t } = this.props;
|
const { members, label, helpText, t } = this.props;
|
||||||
const membersExtended = members.map(id => {
|
const membersExtended = members.map((id) => {
|
||||||
return {
|
return {
|
||||||
id,
|
id,
|
||||||
displayName: id,
|
displayName: id,
|
||||||
mail: ""
|
mail: "",
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
return (
|
return (
|
||||||
@@ -54,7 +54,7 @@ class MemberNameTagGroup extends React.Component<Props> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
removeEntry = (membersExtended: DisplayedUser[]) => {
|
removeEntry = (membersExtended: DisplayedUser[]) => {
|
||||||
const members = membersExtended.map(function(item) {
|
const members = membersExtended.map(function (item) {
|
||||||
return item["id"];
|
return item["id"];
|
||||||
});
|
});
|
||||||
this.props.memberListChanged(members);
|
this.props.memberListChanged(members);
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ class PasswordConfirmation extends React.Component<Props, State> {
|
|||||||
password: "",
|
password: "",
|
||||||
confirmedPassword: "",
|
confirmedPassword: "",
|
||||||
passwordValid: true,
|
passwordValid: true,
|
||||||
passwordConfirmationFailed: false
|
passwordConfirmationFailed: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,7 +53,7 @@ class PasswordConfirmation extends React.Component<Props, State> {
|
|||||||
password: "",
|
password: "",
|
||||||
confirmedPassword: "",
|
confirmedPassword: "",
|
||||||
passwordValid: true,
|
passwordValid: true,
|
||||||
passwordConfirmationFailed: false
|
passwordConfirmationFailed: false,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,7 +101,7 @@ class PasswordConfirmation extends React.Component<Props, State> {
|
|||||||
this.setState(
|
this.setState(
|
||||||
{
|
{
|
||||||
confirmedPassword,
|
confirmedPassword,
|
||||||
passwordConfirmationFailed: !passwordConfirmed
|
passwordConfirmationFailed: !passwordConfirmed,
|
||||||
},
|
},
|
||||||
this.propagateChange
|
this.propagateChange
|
||||||
);
|
);
|
||||||
@@ -114,7 +114,7 @@ class PasswordConfirmation extends React.Component<Props, State> {
|
|||||||
{
|
{
|
||||||
passwordValid: this.validatePassword(password),
|
passwordValid: this.validatePassword(password),
|
||||||
passwordConfirmationFailed,
|
passwordConfirmationFailed,
|
||||||
password: password
|
password: password,
|
||||||
},
|
},
|
||||||
this.propagateChange
|
this.propagateChange
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ const LegacyEvents: FC = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
storiesOf("Forms/Radio", module)
|
storiesOf("Forms/Radio", module)
|
||||||
.addDecorator(storyFn => <MemoryRouter>{storyFn()}</MemoryRouter>)
|
.addDecorator((storyFn) => <MemoryRouter>{storyFn()}</MemoryRouter>)
|
||||||
.add("Default", () => (
|
.add("Default", () => (
|
||||||
<Spacing>
|
<Spacing>
|
||||||
<Radio label="Not checked" checked={false} />
|
<Radio label="Not checked" checked={false} />
|
||||||
|
|||||||
@@ -187,8 +187,8 @@ const PreselectOption: FC = () => {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "USCSS Prometheus",
|
label: "USCSS Prometheus",
|
||||||
value: "uscss-prometheus"
|
value: "uscss-prometheus",
|
||||||
}
|
},
|
||||||
]}
|
]}
|
||||||
onChange={setValue}
|
onChange={setValue}
|
||||||
value={value}
|
value={value}
|
||||||
@@ -204,5 +204,4 @@ storiesOf("Forms/Select", module)
|
|||||||
.add("Ref", () => <Ref />)
|
.add("Ref", () => <Ref />)
|
||||||
.add("Legacy Events", () => <LegacyEvents />)
|
.add("Legacy Events", () => <LegacyEvents />)
|
||||||
.add("ReactHookForm", () => <ReactHookForm />)
|
.add("ReactHookForm", () => <ReactHookForm />)
|
||||||
.add("Preselect option", () => <PreselectOption />)
|
.add("Preselect option", () => <PreselectOption />);
|
||||||
;
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
// this aliases are only to map from spotter detection to prismjs
|
// this aliases are only to map from spotter detection to prismjs
|
||||||
const languageAliases: { [key: string]: string } = {
|
const languageAliases: { [key: string]: string } = {
|
||||||
golang: "go"
|
golang: "go",
|
||||||
};
|
};
|
||||||
|
|
||||||
export const defaultLanguage = "text";
|
export const defaultLanguage = "text";
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ const trillian: Me = {
|
|||||||
displayName: "Trillian McMillian",
|
displayName: "Trillian McMillian",
|
||||||
mail: "tricia@hitchhiker.com",
|
mail: "tricia@hitchhiker.com",
|
||||||
groups: ["crew"],
|
groups: ["crew"],
|
||||||
_links: {}
|
_links: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
const bindAvatar = (binder: Binder, avatar: string) => {
|
const bindAvatar = (binder: Binder, avatar: string) => {
|
||||||
@@ -65,7 +65,7 @@ const withBinder = (binder: Binder) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
storiesOf("Footer", module)
|
storiesOf("Footer", module)
|
||||||
.addDecorator(story => <MemoryRouter initialEntries={["/"]}>{story()}</MemoryRouter>)
|
.addDecorator((story) => <MemoryRouter initialEntries={["/"]}>{story()}</MemoryRouter>)
|
||||||
.add("Default", () => {
|
.add("Default", () => {
|
||||||
return <Footer me={trillian} version="2.0.0" links={{}} />;
|
return <Footer me={trillian} version="2.0.0" links={{}} />;
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ const SecondaryColumn = styled.div<{ collapsed: boolean }>`
|
|||||||
/* In Bulma there is unfortunately no intermediate step between .is-1 and .is-2, hence the size.
|
/* In Bulma there is unfortunately no intermediate step between .is-1 and .is-2, hence the size.
|
||||||
Navigation size should be as constant as possible. */
|
Navigation size should be as constant as possible. */
|
||||||
flex: none;
|
flex: none;
|
||||||
width: ${props => (props.collapsed ? "5.5rem" : "20.5rem")};
|
width: ${(props) => (props.collapsed ? "5.5rem" : "20.5rem")};
|
||||||
max-width: ${(props: { collapsed: boolean }) => (props.collapsed ? "11.3%" : "25%")};
|
max-width: ${(props: { collapsed: boolean }) => (props.collapsed ? "11.3%" : "25%")};
|
||||||
/* Render this column to full size if column construct breaks (page size too small). */
|
/* Render this column to full size if column construct breaks (page size too small). */
|
||||||
@media (max-width: 785px) {
|
@media (max-width: 785px) {
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ type Props = {
|
|||||||
className?: string;
|
className?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
const Title: FC<Props> = ({ title, preventRefreshingPageTitle, customPageTitle, className , children}) => {
|
const Title: FC<Props> = ({ title, preventRefreshingPageTitle, customPageTitle, className, children }) => {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!preventRefreshingPageTitle) {
|
if (!preventRefreshingPageTitle) {
|
||||||
if (customPageTitle) {
|
if (customPageTitle) {
|
||||||
@@ -51,7 +51,7 @@ const Title: FC<Props> = ({ title, preventRefreshingPageTitle, customPageTitle,
|
|||||||
};
|
};
|
||||||
|
|
||||||
Title.defaultProps = {
|
Title.defaultProps = {
|
||||||
preventRefreshingPageTitle: false
|
preventRefreshingPageTitle: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Title;
|
export default Title;
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ type Props = {
|
|||||||
value: string;
|
value: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
const MarkdownCodeRenderer: FC<Props> = props => {
|
const MarkdownCodeRenderer: FC<Props> = (props) => {
|
||||||
const binder = useBinder();
|
const binder = useBinder();
|
||||||
const indexLinks = useIndexLinks();
|
const indexLinks = useIndexLinks();
|
||||||
const { language } = props;
|
const { language } = props;
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ const MarkdownHeadingRenderer: FC<Props> = ({ children, level, permalink, id })
|
|||||||
<Icon name="link" onClick={copyPermalink} alt={t("sources.content.copyPermalink")} />
|
<Icon name="link" onClick={copyPermalink} alt={t("sources.content.copyPermalink")} />
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
);
|
);
|
||||||
const headingElement = React.createElement("h" + level, {id: anchorId}, [...reactChildren, CopyButton]);
|
const headingElement = React.createElement("h" + level, { id: anchorId }, [...reactChildren, CopyButton]);
|
||||||
const href = urls.withContextPath(location.pathname + "#" + anchorId);
|
const href = urls.withContextPath(location.pathname + "#" + anchorId);
|
||||||
const permalinkHref =
|
const permalinkHref =
|
||||||
window.location.protocol +
|
window.location.protocol +
|
||||||
@@ -110,7 +110,7 @@ const MarkdownHeadingRenderer: FC<Props> = ({ children, level, permalink, id })
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const create = (permalink: string): FC<Props> => {
|
export const create = (permalink: string): FC<Props> => {
|
||||||
return props => <MarkdownHeadingRenderer {...props} permalink={permalink} />;
|
return (props) => <MarkdownHeadingRenderer {...props} permalink={permalink} />;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default MarkdownHeadingRenderer;
|
export default MarkdownHeadingRenderer;
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ import {
|
|||||||
isExternalLink,
|
isExternalLink,
|
||||||
isLinkWithProtocol,
|
isLinkWithProtocol,
|
||||||
createLocalLink,
|
createLocalLink,
|
||||||
isInternalScmRepoLink
|
isInternalScmRepoLink,
|
||||||
} from "./MarkdownLinkRenderer";
|
} from "./MarkdownLinkRenderer";
|
||||||
|
|
||||||
describe("test isAnchorLink", () => {
|
describe("test isAnchorLink", () => {
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ const MarkdownLinkRenderer: FC<Props> = ({ href = "", base, children, ...props }
|
|||||||
// we use a factory method, because react-markdown does not pass
|
// we use a factory method, because react-markdown does not pass
|
||||||
// base as prop down to our link component.
|
// base as prop down to our link component.
|
||||||
export const create = (base?: string, protocolExtensions: ProtocolLinkRendererExtensionMap = {}): FC<LinkProps> => {
|
export const create = (base?: string, protocolExtensions: ProtocolLinkRendererExtensionMap = {}): FC<LinkProps> => {
|
||||||
return props => {
|
return (props) => {
|
||||||
const protocolLinkContext = isLinkWithProtocol(props.href || "");
|
const protocolLinkContext = isLinkWithProtocol(props.href || "");
|
||||||
if (protocolLinkContext) {
|
if (protocolLinkContext) {
|
||||||
const { link, protocol } = protocolLinkContext;
|
const { link, protocol } = protocolLinkContext;
|
||||||
|
|||||||
@@ -46,8 +46,8 @@ const Spacing = styled.div`
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
storiesOf("MarkdownView", module)
|
storiesOf("MarkdownView", module)
|
||||||
.addDecorator(story => <MemoryRouter initialEntries={["/"]}>{story()}</MemoryRouter>)
|
.addDecorator((story) => <MemoryRouter initialEntries={["/"]}>{story()}</MemoryRouter>)
|
||||||
.addDecorator(story => <Spacing>{story()}</Spacing>)
|
.addDecorator((story) => <Spacing>{story()}</Spacing>)
|
||||||
.add("Default", () => <MarkdownView content={TestPage} skipHtml={false} />)
|
.add("Default", () => <MarkdownView content={TestPage} skipHtml={false} />)
|
||||||
.add("Skip Html", () => <MarkdownView content={TestPage} skipHtml={true} />)
|
.add("Skip Html", () => <MarkdownView content={TestPage} skipHtml={true} />)
|
||||||
.add("Code without Lang", () => <MarkdownView content={MarkdownWithoutLang} skipHtml={false} />)
|
.add("Code without Lang", () => <MarkdownView content={MarkdownWithoutLang} skipHtml={false} />)
|
||||||
@@ -63,7 +63,7 @@ storiesOf("MarkdownView", module)
|
|||||||
const binder = new Binder("custom protocol link renderer");
|
const binder = new Binder("custom protocol link renderer");
|
||||||
binder.bind("markdown-renderer.link.protocol", {
|
binder.bind("markdown-renderer.link.protocol", {
|
||||||
protocol: "scw",
|
protocol: "scw",
|
||||||
renderer: ProtocolLinkRenderer
|
renderer: ProtocolLinkRenderer,
|
||||||
} as ProtocolLinkRendererExtension);
|
} as ProtocolLinkRendererExtension);
|
||||||
return (
|
return (
|
||||||
<BinderContext.Provider value={binder}>
|
<BinderContext.Provider value={binder}>
|
||||||
@@ -75,7 +75,7 @@ storiesOf("MarkdownView", module)
|
|||||||
const binder = new Binder("custom protocol link renderer");
|
const binder = new Binder("custom protocol link renderer");
|
||||||
binder.bind("markdown-renderer.link.protocol", {
|
binder.bind("markdown-renderer.link.protocol", {
|
||||||
protocol: "scw",
|
protocol: "scw",
|
||||||
renderer: ProtocolLinkRenderer
|
renderer: ProtocolLinkRenderer,
|
||||||
} as ProtocolLinkRendererExtension);
|
} as ProtocolLinkRendererExtension);
|
||||||
return (
|
return (
|
||||||
<BinderContext.Provider value={binder}>
|
<BinderContext.Provider value={binder}>
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ const MarkdownErrorNotification: FC = () => {
|
|||||||
</pre>
|
</pre>
|
||||||
<p>
|
<p>
|
||||||
{t("markdownErrorNotification.spec")}:{" "}
|
{t("markdownErrorNotification.spec")}:{" "}
|
||||||
<a href="https://github.github.com/gfm/" target="_blank">
|
<a href="https://github.github.com/gfm/" target="_blank" rel="noreferrer">
|
||||||
GitHub Flavored Markdown Spec
|
GitHub Flavored Markdown Spec
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
@@ -99,13 +99,13 @@ class MarkdownView extends React.Component<Props, State> {
|
|||||||
|
|
||||||
static defaultProps: Partial<Props> = {
|
static defaultProps: Partial<Props> = {
|
||||||
enableAnchorHeadings: false,
|
enableAnchorHeadings: false,
|
||||||
skipHtml: false
|
skipHtml: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(props: Props) {
|
constructor(props: Props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
contentRef: null
|
contentRef: null,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,7 +143,7 @@ class MarkdownView extends React.Component<Props, State> {
|
|||||||
basePath,
|
basePath,
|
||||||
permalink,
|
permalink,
|
||||||
t,
|
t,
|
||||||
mdastPlugins = []
|
mdastPlugins = [],
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
const rendererFactory = this.context.getExtension("markdown-renderer-factory");
|
const rendererFactory = this.context.getExtension("markdown-renderer-factory");
|
||||||
@@ -200,25 +200,25 @@ class MarkdownView extends React.Component<Props, State> {
|
|||||||
sanitize,
|
sanitize,
|
||||||
merge(gh, {
|
merge(gh, {
|
||||||
attributes: {
|
attributes: {
|
||||||
code: ["className"] // Allow className for code elements, this is necessary to extract the code language
|
code: ["className"], // Allow className for code elements, this is necessary to extract the code language
|
||||||
},
|
},
|
||||||
clobberPrefix: "", // Do not prefix user-provided ids and class names,
|
clobberPrefix: "", // Do not prefix user-provided ids and class names,
|
||||||
protocols: {
|
protocols: {
|
||||||
href: Object.keys(protocolLinkRendererExtensions)
|
href: Object.keys(protocolLinkRendererExtensions),
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
.use(rehype2react, {
|
.use(rehype2react, {
|
||||||
createElement: React.createElement,
|
createElement: React.createElement,
|
||||||
passNode: true,
|
passNode: true,
|
||||||
components: createComponentList(remarkRendererList, { permalink })
|
components: createComponentList(remarkRendererList, { permalink }),
|
||||||
});
|
});
|
||||||
|
|
||||||
const renderedMarkdown: any = processor.processSync(content).result;
|
const renderedMarkdown: any = processor.processSync(content).result;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ErrorBoundary fallback={MarkdownErrorNotification}>
|
<ErrorBoundary fallback={MarkdownErrorNotification}>
|
||||||
<div ref={el => this.setState({ contentRef: el })} className="content is-word-break">
|
<div ref={(el) => this.setState({ contentRef: el })} className="content is-word-break">
|
||||||
{renderedMarkdown}
|
{renderedMarkdown}
|
||||||
</div>
|
</div>
|
||||||
</ErrorBoundary>
|
</ErrorBoundary>
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
import {
|
import {
|
||||||
createRemark2RehypeCodeRendererAdapter,
|
createRemark2RehypeCodeRendererAdapter,
|
||||||
createRemark2RehypeHeadingRendererAdapterFactory,
|
createRemark2RehypeHeadingRendererAdapterFactory,
|
||||||
createRemark2RehypeLinkRendererAdapter
|
createRemark2RehypeLinkRendererAdapter,
|
||||||
} from "./remarkToRehypeRendererAdapters";
|
} from "./remarkToRehypeRendererAdapters";
|
||||||
|
|
||||||
export type CreateComponentListOptions = {
|
export type CreateComponentListOptions = {
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ export default function createMdastPlugin(plugin: AstPlugin): any {
|
|||||||
return function attach() {
|
return function attach() {
|
||||||
return function transform(tree: any) {
|
return function transform(tree: any) {
|
||||||
plugin({
|
plugin({
|
||||||
visit: (type, visitor) => visit(tree, type, visitor)
|
visit: (type, visitor) => visit(tree, type, visitor),
|
||||||
});
|
});
|
||||||
return tree;
|
return tree;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -35,4 +35,4 @@ export type ProtocolLinkRendererExtension = {
|
|||||||
|
|
||||||
export type ProtocolLinkRendererExtensionMap = {
|
export type ProtocolLinkRendererExtensionMap = {
|
||||||
[protocol: string]: FC<ProtocolLinkRendererProps>;
|
[protocol: string]: FC<ProtocolLinkRendererProps>;
|
||||||
}
|
};
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ export const createTransformer = (t: TFunction): AstPlugin => {
|
|||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
children.push({
|
children.push({
|
||||||
type: "text",
|
type: "text",
|
||||||
value: nodeText.substring(0, i)
|
value: nodeText.substring(0, i),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,14 +69,14 @@ export const createTransformer = (t: TFunction): AstPlugin => {
|
|||||||
title: t("changeset.shortlink.title", {
|
title: t("changeset.shortlink.title", {
|
||||||
namespace: m[1],
|
namespace: m[1],
|
||||||
name: m[2],
|
name: m[2],
|
||||||
id: m[3]
|
id: m[3],
|
||||||
}),
|
}),
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
type: "text",
|
type: "text",
|
||||||
value: m[0]
|
value: m[0],
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
nodeText = nodeText.substring(i + m[0].length);
|
nodeText = nodeText.substring(i + m[0].length);
|
||||||
@@ -85,13 +85,13 @@ export const createTransformer = (t: TFunction): AstPlugin => {
|
|||||||
if (nodeText.length > 0) {
|
if (nodeText.length > 0) {
|
||||||
children.push({
|
children.push({
|
||||||
type: "text",
|
type: "text",
|
||||||
value: nodeText
|
value: nodeText,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
parent.children[index] = {
|
parent.children[index] = {
|
||||||
type: "text",
|
type: "text",
|
||||||
children
|
children,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ export const createRemark2RehypeCodeRendererAdapter = (remarkRenderer: any) => {
|
|||||||
children = children || [];
|
children = children || [];
|
||||||
const renderProps = {
|
const renderProps = {
|
||||||
value: children[0],
|
value: children[0],
|
||||||
language: Array.isArray(node.properties.className) ? node.properties.className[0].split("language-")[1] : ""
|
language: Array.isArray(node.properties.className) ? node.properties.className[0].split("language-")[1] : "",
|
||||||
};
|
};
|
||||||
return React.createElement(remarkRenderer, renderProps, ...children);
|
return React.createElement(remarkRenderer, renderProps, ...children);
|
||||||
};
|
};
|
||||||
@@ -54,13 +54,14 @@ export const createRemark2RehypeLinkRendererAdapter = (remarkRenderer: any) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const createRemark2RehypeHeadingRendererAdapterFactory = (remarkRenderer: any, permalink?: string) => {
|
export const createRemark2RehypeHeadingRendererAdapterFactory = (remarkRenderer: any, permalink?: string) => {
|
||||||
return (level: number) => ({ node, children }: any) => {
|
return (level: number) =>
|
||||||
const renderProps = {
|
({ node, children }: any) => {
|
||||||
id: node.properties.id,
|
const renderProps = {
|
||||||
level,
|
id: node.properties.id,
|
||||||
permalink
|
level,
|
||||||
|
permalink,
|
||||||
|
};
|
||||||
|
children = children || [];
|
||||||
|
return React.createElement(remarkRenderer, renderProps, ...children);
|
||||||
};
|
};
|
||||||
children = children || [];
|
|
||||||
return React.createElement(remarkRenderer, renderProps, ...children);
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -37,15 +37,15 @@ const buttons = [
|
|||||||
{
|
{
|
||||||
className: "is-outlined",
|
className: "is-outlined",
|
||||||
label: "Cancel",
|
label: "Cancel",
|
||||||
onClick: () => null
|
onClick: () => null,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Submit"
|
label: "Submit",
|
||||||
}
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
storiesOf("Modal/ConfirmAlert", module)
|
storiesOf("Modal/ConfirmAlert", module)
|
||||||
.addDecorator(story => <MemoryRouter initialEntries={["/"]}>{story()}</MemoryRouter>)
|
.addDecorator((story) => <MemoryRouter initialEntries={["/"]}>{story()}</MemoryRouter>)
|
||||||
.add("Default", () => <ConfirmAlert message={body} title={"Are you sure about that?"} buttons={buttons} />)
|
.add("Default", () => <ConfirmAlert message={body} title={"Are you sure about that?"} buttons={buttons} />)
|
||||||
.add("WithButton", () => {
|
.add("WithButton", () => {
|
||||||
const buttonClick = () => {
|
const buttonClick = () => {
|
||||||
|
|||||||
@@ -65,13 +65,13 @@ export const ConfirmAlert: FC<Props> = ({ title, message, buttons, close }) => {
|
|||||||
<div className="field is-grouped">
|
<div className="field is-grouped">
|
||||||
{buttons.map((button, index) => (
|
{buttons.map((button, index) => (
|
||||||
<p className="control" key={index}>
|
<p className="control" key={index}>
|
||||||
<a
|
<button
|
||||||
className={classNames("button", "is-info", button.className, button.isLoading ? "is-loading" : "")}
|
className={classNames("button", "is-info", button.className, button.isLoading ? "is-loading" : "")}
|
||||||
key={index}
|
key={index}
|
||||||
onClick={() => handleClickButton(button)}
|
onClick={() => handleClickButton(button)}
|
||||||
>
|
>
|
||||||
{button.label}
|
{button.label}
|
||||||
</a>
|
</button>
|
||||||
</p>
|
</p>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -48,8 +48,8 @@ const CreateTagModal: FC<Props> = ({ t, onClose, tagCreationLink, existingTagsLi
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
apiClient
|
apiClient
|
||||||
.get(existingTagsLink)
|
.get(existingTagsLink)
|
||||||
.then(response => response.json())
|
.then((response) => response.json())
|
||||||
.then(json => setTagNames(json._embedded.tags.map((tag: Tag) => tag.name)));
|
.then((json) => setTagNames(json._embedded.tags.map((tag: Tag) => tag.name)));
|
||||||
}, [existingTagsLink]);
|
}, [existingTagsLink]);
|
||||||
|
|
||||||
const createTag = () => {
|
const createTag = () => {
|
||||||
@@ -57,7 +57,7 @@ const CreateTagModal: FC<Props> = ({ t, onClose, tagCreationLink, existingTagsLi
|
|||||||
apiClient
|
apiClient
|
||||||
.post(tagCreationLink, {
|
.post(tagCreationLink, {
|
||||||
revision,
|
revision,
|
||||||
name: newTagName
|
name: newTagName,
|
||||||
})
|
})
|
||||||
.then(onCreated)
|
.then(onCreated)
|
||||||
.catch(onError)
|
.catch(onError)
|
||||||
@@ -83,7 +83,7 @@ const CreateTagModal: FC<Props> = ({ t, onClose, tagCreationLink, existingTagsLi
|
|||||||
<InputField
|
<InputField
|
||||||
name="name"
|
name="name"
|
||||||
label={t("tags.create.form.field.name.label")}
|
label={t("tags.create.form.field.name.label")}
|
||||||
onChange={val => setNewTagName(val)}
|
onChange={(val) => setNewTagName(val)}
|
||||||
value={newTagName}
|
value={newTagName}
|
||||||
validationError={!!validationError}
|
validationError={!!validationError}
|
||||||
errorMessage={t(validationError)}
|
errorMessage={t(validationError)}
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ export const MenuContext = React.createContext<MenuContext>({
|
|||||||
isCollapsed() {
|
isCollapsed() {
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
setCollapsed() {}
|
setCollapsed() {},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const StateMenuContextProvider: FC = ({ children }) => {
|
export const StateMenuContextProvider: FC = ({ children }) => {
|
||||||
@@ -43,7 +43,7 @@ export const StateMenuContextProvider: FC = ({ children }) => {
|
|||||||
isCollapsed() {
|
isCollapsed() {
|
||||||
return collapsed;
|
return collapsed;
|
||||||
},
|
},
|
||||||
setCollapsed
|
setCollapsed,
|
||||||
};
|
};
|
||||||
|
|
||||||
return <MenuContext.Provider value={context}>{children}</MenuContext.Provider>;
|
return <MenuContext.Provider value={context}>{children}</MenuContext.Provider>;
|
||||||
|
|||||||
@@ -39,17 +39,17 @@ class NavAction extends React.Component<Props> {
|
|||||||
if (icon) {
|
if (icon) {
|
||||||
showIcon = (
|
showIcon = (
|
||||||
<>
|
<>
|
||||||
<i className={icon}></i>{" "}
|
<i className={icon} />{" "}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<li>
|
<li>
|
||||||
<a onClick={action} href="javascript:void(0);">
|
<button onClick={action}>
|
||||||
{showIcon}
|
{showIcon}
|
||||||
{label}
|
{label}
|
||||||
</a>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,8 +53,8 @@ const withRoute = (route: string) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
storiesOf("Secondary Navigation", module)
|
storiesOf("Secondary Navigation", module)
|
||||||
.addDecorator(story => <StateMenuContextProvider>{story()}</StateMenuContextProvider>)
|
.addDecorator((story) => <StateMenuContextProvider>{story()}</StateMenuContextProvider>)
|
||||||
.addDecorator(story => (
|
.addDecorator((story) => (
|
||||||
<Columns className="columns">
|
<Columns className="columns">
|
||||||
<div className="column is-3">{story()}</div>
|
<div className="column is-3">{story()}</div>
|
||||||
</Columns>
|
</Columns>
|
||||||
@@ -92,7 +92,7 @@ storiesOf("Secondary Navigation", module)
|
|||||||
<SecondaryNavigation label="Hitchhiker">
|
<SecondaryNavigation label="Hitchhiker">
|
||||||
<SecondaryNavigationItem to="/42" icon="fas fa-puzzle-piece" label="Puzzle 42" title="Puzzle 42" />
|
<SecondaryNavigationItem to="/42" icon="fas fa-puzzle-piece" label="Puzzle 42" title="Puzzle 42" />
|
||||||
<SecondaryNavigationItem
|
<SecondaryNavigationItem
|
||||||
activeWhenMatch={route => route.location.pathname === "/hog"}
|
activeWhenMatch={(route) => route.location.pathname === "/hog"}
|
||||||
to="/heart-of-gold"
|
to="/heart-of-gold"
|
||||||
icon="fas fa-star"
|
icon="fas fa-star"
|
||||||
label="Heart Of Gold"
|
label="Heart Of Gold"
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ const SubNavigation: FC<Props> = ({
|
|||||||
title,
|
title,
|
||||||
label,
|
label,
|
||||||
children,
|
children,
|
||||||
testId
|
testId,
|
||||||
}) => {
|
}) => {
|
||||||
const context = useMenuContext();
|
const context = useMenuContext();
|
||||||
const collapsed = context.isCollapsed();
|
const collapsed = context.isCollapsed();
|
||||||
@@ -56,7 +56,7 @@ const SubNavigation: FC<Props> = ({
|
|||||||
const active = useActiveMatch({
|
const active = useActiveMatch({
|
||||||
to: parent,
|
to: parent,
|
||||||
activeOnlyWhenExact,
|
activeOnlyWhenExact,
|
||||||
activeWhenMatch
|
activeWhenMatch,
|
||||||
});
|
});
|
||||||
|
|
||||||
let defaultIcon = "fas fa-cog";
|
let defaultIcon = "fas fa-cog";
|
||||||
|
|||||||
@@ -34,40 +34,42 @@ const Wrapper = styled.div`
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
storiesOf("Popover", module)
|
storiesOf("Popover", module)
|
||||||
.addDecorator(storyFn => <Wrapper>{storyFn()}</Wrapper>)
|
.addDecorator((storyFn) => <Wrapper>{storyFn()}</Wrapper>)
|
||||||
.add("Default", () => React.createElement(() => {
|
.add("Default", () =>
|
||||||
const { triggerProps, popoverProps } = usePopover();
|
React.createElement(() => {
|
||||||
|
const { triggerProps, popoverProps } = usePopover();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Popover title={<strong>Spaceship Heart of Gold</strong>} width={512} {...popoverProps}>
|
<Popover title={<strong>Spaceship Heart of Gold</strong>} width={512} {...popoverProps}>
|
||||||
<p>
|
<p>
|
||||||
The Heart of Gold is the sleekest, most advanced, coolest spaceship in the galaxy. Its stunning good looks
|
The Heart of Gold is the sleekest, most advanced, coolest spaceship in the galaxy. Its stunning good looks
|
||||||
mirror its awesome speed and power. It is powered by the revolutionary new Infinite Improbability Drive,
|
mirror its awesome speed and power. It is powered by the revolutionary new Infinite Improbability Drive,
|
||||||
which lets the ship pass through every point in every universe simultaneously.
|
which lets the ship pass through every point in every universe simultaneously.
|
||||||
</p>
|
</p>
|
||||||
</Popover>
|
</Popover>
|
||||||
<button className="button" {...triggerProps}>
|
<button className="button" {...triggerProps}>
|
||||||
Trigger
|
Trigger
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}))
|
})
|
||||||
.add("Link", () => React.createElement(() => {
|
)
|
||||||
const { triggerProps, popoverProps } = usePopover();
|
.add("Link", () =>
|
||||||
|
React.createElement(() => {
|
||||||
|
const { triggerProps, popoverProps } = usePopover();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Popover title={<strong>Spaceship Heart of Gold</strong>} width={512} {...popoverProps}>
|
<Popover title={<strong>Spaceship Heart of Gold</strong>} width={512} {...popoverProps}>
|
||||||
<p>
|
<p>
|
||||||
The Heart of Gold is the sleekest, most advanced, coolest spaceship in the galaxy. Its stunning good looks
|
The Heart of Gold is the sleekest, most advanced, coolest spaceship in the galaxy. Its stunning good looks
|
||||||
mirror its awesome speed and power. It is powered by the revolutionary new Infinite Improbability Drive,
|
mirror its awesome speed and power. It is powered by the revolutionary new Infinite Improbability Drive,
|
||||||
which lets the ship pass through every point in every universe simultaneously.
|
which lets the ship pass through every point in every universe simultaneously.
|
||||||
</p>
|
</p>
|
||||||
</Popover>
|
</Popover>
|
||||||
<a href="#" {...triggerProps}>
|
<button {...triggerProps}>Trigger</button>
|
||||||
Trigger
|
</div>
|
||||||
</a>
|
);
|
||||||
</div>
|
})
|
||||||
);
|
);
|
||||||
}));
|
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ type State = {
|
|||||||
|
|
||||||
const initialState = {
|
const initialState = {
|
||||||
onPopover: false,
|
onPopover: false,
|
||||||
onTrigger: false
|
onTrigger: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
const reducer = (state: State, action: Action): State => {
|
const reducer = (state: State, action: Action): State => {
|
||||||
@@ -66,14 +66,14 @@ const reducer = (state: State, action: Action): State => {
|
|||||||
offsetTop: action.offsetTop,
|
offsetTop: action.offsetTop,
|
||||||
offsetLeft: action.offsetLeft,
|
offsetLeft: action.offsetLeft,
|
||||||
onTrigger: true,
|
onTrigger: true,
|
||||||
onPopover: false
|
onPopover: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
case "leave-trigger": {
|
case "leave-trigger": {
|
||||||
if (state.onPopover) {
|
if (state.onPopover) {
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
onTrigger: false
|
onTrigger: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return initialState;
|
return initialState;
|
||||||
@@ -81,14 +81,14 @@ const reducer = (state: State, action: Action): State => {
|
|||||||
case "enter-popover": {
|
case "enter-popover": {
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
onPopover: true
|
onPopover: true,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
case "leave-popover": {
|
case "leave-popover": {
|
||||||
if (state.onTrigger) {
|
if (state.onTrigger) {
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
onPopover: false
|
onPopover: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return initialState;
|
return initialState;
|
||||||
@@ -109,13 +109,13 @@ const usePopover = () => {
|
|||||||
dispatchDeferred(dispatch, {
|
dispatchDeferred(dispatch, {
|
||||||
type: "enter-trigger",
|
type: "enter-trigger",
|
||||||
offsetTop: current.offsetTop,
|
offsetTop: current.offsetTop,
|
||||||
offsetLeft: current.offsetLeft + current.offsetWidth / 2
|
offsetLeft: current.offsetLeft + current.offsetWidth / 2,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const onMouseLeave = () => {
|
const onMouseLeave = () => {
|
||||||
dispatchDeferred(dispatch, {
|
dispatchDeferred(dispatch, {
|
||||||
type: "leave-trigger"
|
type: "leave-trigger",
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -123,14 +123,14 @@ const usePopover = () => {
|
|||||||
triggerProps: {
|
triggerProps: {
|
||||||
onMouseOver,
|
onMouseOver,
|
||||||
onMouseLeave,
|
onMouseLeave,
|
||||||
ref: (node: HTMLElement | null) => (triggerRef.current = node)
|
ref: (node: HTMLElement | null) => (triggerRef.current = node),
|
||||||
},
|
},
|
||||||
popoverProps: {
|
popoverProps: {
|
||||||
dispatch,
|
dispatch,
|
||||||
show: state.onPopover || state.onTrigger,
|
show: state.onPopover || state.onTrigger,
|
||||||
offsetTop: state.offsetTop,
|
offsetTop: state.offsetTop,
|
||||||
offsetLeft: state.offsetLeft
|
offsetLeft: state.offsetLeft,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -42,8 +42,8 @@ const HUNK_0: Hunk = {
|
|||||||
{ content: "line", type: "insert", lineNumber: 5, isInsert: true },
|
{ content: "line", type: "insert", lineNumber: 5, isInsert: true },
|
||||||
{ content: "line", type: "normal", oldLineNumber: 6, newLineNumber: 6, isNormal: true },
|
{ content: "line", type: "normal", oldLineNumber: 6, newLineNumber: 6, isNormal: true },
|
||||||
{ content: "line", type: "normal", oldLineNumber: 7, newLineNumber: 7, isNormal: true },
|
{ content: "line", type: "normal", oldLineNumber: 7, newLineNumber: 7, isNormal: true },
|
||||||
{ content: "line", type: "normal", oldLineNumber: 8, newLineNumber: 8, isNormal: true }
|
{ content: "line", type: "normal", oldLineNumber: 8, newLineNumber: 8, isNormal: true },
|
||||||
]
|
],
|
||||||
};
|
};
|
||||||
const HUNK_1: Hunk = {
|
const HUNK_1: Hunk = {
|
||||||
content: "@@ -14,6 +14,7 @@",
|
content: "@@ -14,6 +14,7 @@",
|
||||||
@@ -58,8 +58,8 @@ const HUNK_1: Hunk = {
|
|||||||
{ content: "line", type: "insert", lineNumber: 17, isInsert: true },
|
{ content: "line", type: "insert", lineNumber: 17, isInsert: true },
|
||||||
{ content: "line", type: "normal", oldLineNumber: 17, newLineNumber: 18, isNormal: true },
|
{ content: "line", type: "normal", oldLineNumber: 17, newLineNumber: 18, isNormal: true },
|
||||||
{ content: "line", type: "normal", oldLineNumber: 18, newLineNumber: 19, isNormal: true },
|
{ content: "line", type: "normal", oldLineNumber: 18, newLineNumber: 19, isNormal: true },
|
||||||
{ content: "line", type: "normal", oldLineNumber: 19, newLineNumber: 20, isNormal: true }
|
{ content: "line", type: "normal", oldLineNumber: 19, newLineNumber: 20, isNormal: true },
|
||||||
]
|
],
|
||||||
};
|
};
|
||||||
const HUNK_2: Hunk = {
|
const HUNK_2: Hunk = {
|
||||||
content: "@@ -21,7 +22,7 @@",
|
content: "@@ -21,7 +22,7 @@",
|
||||||
@@ -75,8 +75,8 @@ const HUNK_2: Hunk = {
|
|||||||
{ content: "line", type: "insert", lineNumber: 25, isInsert: true },
|
{ content: "line", type: "insert", lineNumber: 25, isInsert: true },
|
||||||
{ content: "line", type: "normal", oldLineNumber: 25, newLineNumber: 26, isNormal: true },
|
{ content: "line", type: "normal", oldLineNumber: 25, newLineNumber: 26, isNormal: true },
|
||||||
{ content: "line", type: "normal", oldLineNumber: 26, newLineNumber: 27, isNormal: true },
|
{ content: "line", type: "normal", oldLineNumber: 26, newLineNumber: 27, isNormal: true },
|
||||||
{ content: "line", type: "normal", oldLineNumber: 27, newLineNumber: 28, isNormal: true }
|
{ content: "line", type: "normal", oldLineNumber: 27, newLineNumber: 28, isNormal: true },
|
||||||
]
|
],
|
||||||
};
|
};
|
||||||
const HUNK_3: Hunk = {
|
const HUNK_3: Hunk = {
|
||||||
content: "@@ -33,6 +34,7 @@",
|
content: "@@ -33,6 +34,7 @@",
|
||||||
@@ -91,8 +91,8 @@ const HUNK_3: Hunk = {
|
|||||||
{ content: "line", type: "insert", lineNumber: 37, isInsert: true },
|
{ content: "line", type: "insert", lineNumber: 37, isInsert: true },
|
||||||
{ content: "line", type: "normal", oldLineNumber: 36, newLineNumber: 38, isNormal: true },
|
{ content: "line", type: "normal", oldLineNumber: 36, newLineNumber: 38, isNormal: true },
|
||||||
{ content: "line", type: "normal", oldLineNumber: 37, newLineNumber: 39, isNormal: true },
|
{ content: "line", type: "normal", oldLineNumber: 37, newLineNumber: 39, isNormal: true },
|
||||||
{ content: "line", type: "normal", oldLineNumber: 38, newLineNumber: 40, isNormal: true }
|
{ content: "line", type: "normal", oldLineNumber: 38, newLineNumber: 40, isNormal: true },
|
||||||
]
|
],
|
||||||
};
|
};
|
||||||
const TEST_CONTENT_WITH_HUNKS: FileDiff = {
|
const TEST_CONTENT_WITH_HUNKS: FileDiff = {
|
||||||
hunks: [HUNK_0, HUNK_1, HUNK_2, HUNK_3],
|
hunks: [HUNK_0, HUNK_1, HUNK_2, HUNK_3],
|
||||||
@@ -107,9 +107,9 @@ const TEST_CONTENT_WITH_HUNKS: FileDiff = {
|
|||||||
_links: {
|
_links: {
|
||||||
lines: {
|
lines: {
|
||||||
href: "http://localhost:8081/scm/api/v2/content/abc/CommitMessage.js?start={start}&end={end}",
|
href: "http://localhost:8081/scm/api/v2/content/abc/CommitMessage.js?start={start}&end={end}",
|
||||||
templated: true
|
templated: true,
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const TEST_CONTENT_WITH_NEW_BINARY_FILE: FileDiff = {
|
const TEST_CONTENT_WITH_NEW_BINARY_FILE: FileDiff = {
|
||||||
@@ -119,7 +119,7 @@ const TEST_CONTENT_WITH_NEW_BINARY_FILE: FileDiff = {
|
|||||||
newEndingNewLine: true,
|
newEndingNewLine: true,
|
||||||
oldRevision: "0000000000000000000000000000000000000000",
|
oldRevision: "0000000000000000000000000000000000000000",
|
||||||
newRevision: "86c370aae0727d628a5438f79a5cdd45752b9d99",
|
newRevision: "86c370aae0727d628a5438f79a5cdd45752b9d99",
|
||||||
type: "add"
|
type: "add",
|
||||||
};
|
};
|
||||||
|
|
||||||
const TEST_CONTENT_WITH_NEW_TEXT_FILE: FileDiff = {
|
const TEST_CONTENT_WITH_NEW_TEXT_FILE: FileDiff = {
|
||||||
@@ -138,17 +138,16 @@ const TEST_CONTENT_WITH_NEW_TEXT_FILE: FileDiff = {
|
|||||||
newLines: 2,
|
newLines: 2,
|
||||||
changes: [
|
changes: [
|
||||||
{ content: "line 1", type: "insert", lineNumber: 1, isInsert: true },
|
{ content: "line 1", type: "insert", lineNumber: 1, isInsert: true },
|
||||||
{ content: "line 2", type: "insert", lineNumber: 2, isInsert: true }
|
{ content: "line 2", type: "insert", lineNumber: 2, isInsert: true },
|
||||||
]
|
],
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
_links: {
|
_links: {
|
||||||
lines: {
|
lines: {
|
||||||
href:
|
href: "http://localhost:8081/scm/api/v2/repositories/scm-manager/scm-editor-plugin/content/c63898d35520ee47bcc3a8291660979918715762/src/main/markdown/README.md?start={start}&end={end}",
|
||||||
"http://localhost:8081/scm/api/v2/repositories/scm-manager/scm-editor-plugin/content/c63898d35520ee47bcc3a8291660979918715762/src/main/markdown/README.md?start={start}&end={end}",
|
templated: true,
|
||||||
templated: true
|
},
|
||||||
}
|
},
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const TEST_CONTENT_WITH_DELETED_TEXT_FILE: FileDiff = {
|
const TEST_CONTENT_WITH_DELETED_TEXT_FILE: FileDiff = {
|
||||||
@@ -165,10 +164,10 @@ const TEST_CONTENT_WITH_DELETED_TEXT_FILE: FileDiff = {
|
|||||||
content: "@@ -1 +0,0 @@",
|
content: "@@ -1 +0,0 @@",
|
||||||
oldStart: 1,
|
oldStart: 1,
|
||||||
oldLines: 1,
|
oldLines: 1,
|
||||||
changes: [{ content: "# scm-editor-plugin", type: "delete", lineNumber: 1, isDelete: true }]
|
changes: [{ content: "# scm-editor-plugin", type: "delete", lineNumber: 1, isDelete: true }],
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
_links: { lines: { href: "http://localhost:8081/dev/null?start={start}&end={end}", templated: true } }
|
_links: { lines: { href: "http://localhost:8081/dev/null?start={start}&end={end}", templated: true } },
|
||||||
};
|
};
|
||||||
|
|
||||||
const TEST_CONTENT_WITH_DELETED_LINES_AT_END: FileDiff = {
|
const TEST_CONTENT_WITH_DELETED_LINES_AT_END: FileDiff = {
|
||||||
@@ -202,16 +201,16 @@ const TEST_CONTENT_WITH_DELETED_LINES_AT_END: FileDiff = {
|
|||||||
{ content: "line", type: "delete", lineNumber: 119, isDelete: true },
|
{ content: "line", type: "delete", lineNumber: 119, isDelete: true },
|
||||||
{ content: "line", type: "delete", lineNumber: 120, isDelete: true },
|
{ content: "line", type: "delete", lineNumber: 120, isDelete: true },
|
||||||
{ content: "line", type: "delete", lineNumber: 121, isDelete: true },
|
{ content: "line", type: "delete", lineNumber: 121, isDelete: true },
|
||||||
{ content: "line", type: "delete", lineNumber: 122, isDelete: true }
|
{ content: "line", type: "delete", lineNumber: 122, isDelete: true },
|
||||||
]
|
],
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
_links: {
|
_links: {
|
||||||
lines: {
|
lines: {
|
||||||
href: "http://localhost:8081/scm/api/v2/content/abc/CommitMessage.js?start={start}&end={end}",
|
href: "http://localhost:8081/scm/api/v2/content/abc/CommitMessage.js?start={start}&end={end}",
|
||||||
templated: true
|
templated: true,
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const TEST_CONTENT_WITH_ALL_LINES_REMOVED_FROM_FILE: FileDiff = {
|
const TEST_CONTENT_WITH_ALL_LINES_REMOVED_FROM_FILE: FileDiff = {
|
||||||
@@ -231,17 +230,16 @@ const TEST_CONTENT_WITH_ALL_LINES_REMOVED_FROM_FILE: FileDiff = {
|
|||||||
changes: [
|
changes: [
|
||||||
{ content: "line", type: "delete", lineNumber: 1, isDelete: true },
|
{ content: "line", type: "delete", lineNumber: 1, isDelete: true },
|
||||||
{ content: "line", type: "delete", lineNumber: 2, isDelete: true },
|
{ content: "line", type: "delete", lineNumber: 2, isDelete: true },
|
||||||
{ content: "line", type: "delete", lineNumber: 3, isDelete: true }
|
{ content: "line", type: "delete", lineNumber: 3, isDelete: true },
|
||||||
]
|
],
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
_links: {
|
_links: {
|
||||||
lines: {
|
lines: {
|
||||||
href:
|
href: "http://localhost:8081/scm/api/v2/repositories/scm-manager/scm-editor-plugin/content/b313a7690f028c77df98417c1ed6cba67e5692ec/pom.xml?start={start}&end={end}",
|
||||||
"http://localhost:8081/scm/api/v2/repositories/scm-manager/scm-editor-plugin/content/b313a7690f028c77df98417c1ed6cba67e5692ec/pom.xml?start={start}&end={end}",
|
templated: true,
|
||||||
templated: true
|
},
|
||||||
}
|
},
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
describe("with hunks the diff expander", () => {
|
describe("with hunks the diff expander", () => {
|
||||||
@@ -285,7 +283,7 @@ describe("with hunks the diff expander", () => {
|
|||||||
await diffExpander
|
await diffExpander
|
||||||
.getHunk(1)
|
.getHunk(1)
|
||||||
.expandBottom(1)
|
.expandBottom(1)
|
||||||
.then(file => (newFile = file));
|
.then((file) => (newFile = file));
|
||||||
expect(fetchMock.done()).toBe(true);
|
expect(fetchMock.done()).toBe(true);
|
||||||
expect(newFile!.hunks!.length).toBe(oldHunkCount + 1);
|
expect(newFile!.hunks!.length).toBe(oldHunkCount + 1);
|
||||||
expect(newFile!.hunks![1]).toBe(expandedHunk);
|
expect(newFile!.hunks![1]).toBe(expandedHunk);
|
||||||
@@ -310,7 +308,7 @@ describe("with hunks the diff expander", () => {
|
|||||||
await diffExpander
|
await diffExpander
|
||||||
.getHunk(1)
|
.getHunk(1)
|
||||||
.expandHead(5)
|
.expandHead(5)
|
||||||
.then(file => (newFile = file));
|
.then((file) => (newFile = file));
|
||||||
expect(fetchMock.done()).toBe(true);
|
expect(fetchMock.done()).toBe(true);
|
||||||
expect(newFile!.hunks!.length).toBe(oldHunkCount + 1);
|
expect(newFile!.hunks!.length).toBe(oldHunkCount + 1);
|
||||||
expect(newFile!.hunks![0]).toBe(preceedingHunk);
|
expect(newFile!.hunks![0]).toBe(preceedingHunk);
|
||||||
@@ -339,7 +337,7 @@ describe("with hunks the diff expander", () => {
|
|||||||
await diffExpander
|
await diffExpander
|
||||||
.getHunk(3)
|
.getHunk(3)
|
||||||
.expandBottom(10)
|
.expandBottom(10)
|
||||||
.then(file => (newFile = file));
|
.then((file) => (newFile = file));
|
||||||
expect(newFile!.hunks!.length).toBe(oldHunkCount + 1);
|
expect(newFile!.hunks!.length).toBe(oldHunkCount + 1);
|
||||||
expect(newFile!.hunks![4].fullyExpanded).toBe(true);
|
expect(newFile!.hunks![4].fullyExpanded).toBe(true);
|
||||||
});
|
});
|
||||||
@@ -352,7 +350,7 @@ describe("with hunks the diff expander", () => {
|
|||||||
await diffExpander
|
await diffExpander
|
||||||
.getHunk(3)
|
.getHunk(3)
|
||||||
.expandBottom(-1)
|
.expandBottom(-1)
|
||||||
.then(file => (newFile = file));
|
.then((file) => (newFile = file));
|
||||||
await fetchMock.flush(true);
|
await fetchMock.flush(true);
|
||||||
expect(newFile!.hunks![4].fullyExpanded).toBe(true);
|
expect(newFile!.hunks![4].fullyExpanded).toBe(true);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ class DiffExpander {
|
|||||||
expandHead: (n: number, count: number) => Promise<FileDiff> = (n, count) => {
|
expandHead: (n: number, count: number) => Promise<FileDiff> = (n, count) => {
|
||||||
const start = this.minLineNumber(n) - Math.min(count, this.computeMaxExpandHeadRange(n)) - 1;
|
const start = this.minLineNumber(n) - Math.min(count, this.computeMaxExpandHeadRange(n)) - 1;
|
||||||
const end = this.minLineNumber(n) - 1;
|
const end = this.minLineNumber(n) - 1;
|
||||||
return this.loadLines(start, end).then(lines => {
|
return this.loadLines(start, end).then((lines) => {
|
||||||
const hunk = this.file.hunks![n];
|
const hunk = this.file.hunks![n];
|
||||||
|
|
||||||
const newHunk = this.createNewHunk(
|
const newHunk = this.createNewHunk(
|
||||||
@@ -96,7 +96,7 @@ class DiffExpander {
|
|||||||
count > 0
|
count > 0
|
||||||
? start + Math.min(count, maxExpandBottomRange > 0 ? maxExpandBottomRange : Number.MAX_SAFE_INTEGER)
|
? start + Math.min(count, maxExpandBottomRange > 0 ? maxExpandBottomRange : Number.MAX_SAFE_INTEGER)
|
||||||
: -1;
|
: -1;
|
||||||
return this.loadLines(start, end).then(lines => {
|
return this.loadLines(start, end).then((lines) => {
|
||||||
const hunk = this.file.hunks![n];
|
const hunk = this.file.hunks![n];
|
||||||
|
|
||||||
const newHunk: Hunk = this.createNewHunk(
|
const newHunk: Hunk = this.createNewHunk(
|
||||||
@@ -116,9 +116,9 @@ class DiffExpander {
|
|||||||
.replace("{end}", end.toString());
|
.replace("{end}", end.toString());
|
||||||
return apiClient
|
return apiClient
|
||||||
.get(lineRequestUrl)
|
.get(lineRequestUrl)
|
||||||
.then(response => response.text())
|
.then((response) => response.text())
|
||||||
.then(text => text.split("\n"))
|
.then((text) => text.split("\n"))
|
||||||
.then(lines => (lines[lines.length - 1] === "" ? lines.slice(0, lines.length - 1) : lines));
|
.then((lines) => (lines[lines.length - 1] === "" ? lines.slice(0, lines.length - 1) : lines));
|
||||||
};
|
};
|
||||||
|
|
||||||
addHunkToFile = (newHunk: Hunk, position: number) => {
|
addHunkToFile = (newHunk: Hunk, position: number) => {
|
||||||
@@ -141,13 +141,13 @@ class DiffExpander {
|
|||||||
let oldLineNumber: number = oldFirstLineNumber;
|
let oldLineNumber: number = oldFirstLineNumber;
|
||||||
let newLineNumber: number = newFirstLineNumber;
|
let newLineNumber: number = newFirstLineNumber;
|
||||||
|
|
||||||
lines.forEach(line => {
|
lines.forEach((line) => {
|
||||||
newChanges.push({
|
newChanges.push({
|
||||||
content: line,
|
content: line,
|
||||||
type: "normal",
|
type: "normal",
|
||||||
oldLineNumber,
|
oldLineNumber,
|
||||||
newLineNumber,
|
newLineNumber,
|
||||||
isNormal: true
|
isNormal: true,
|
||||||
});
|
});
|
||||||
oldLineNumber += 1;
|
oldLineNumber += 1;
|
||||||
newLineNumber += 1;
|
newLineNumber += 1;
|
||||||
@@ -161,7 +161,7 @@ class DiffExpander {
|
|||||||
oldLines: lines.length,
|
oldLines: lines.length,
|
||||||
newLines: lines.length,
|
newLines: lines.length,
|
||||||
expansion: true,
|
expansion: true,
|
||||||
fullyExpanded: requestedLines < 0 || lines.length < requestedLines
|
fullyExpanded: requestedLines < 0 || lines.length < requestedLines,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -175,13 +175,13 @@ class DiffExpander {
|
|||||||
return lastChange.newLineNumber || lastChange.lineNumber!;
|
return lastChange.newLineNumber || lastChange.lineNumber!;
|
||||||
};
|
};
|
||||||
|
|
||||||
getHunk: (n: number) => ExpandableHunk = n => {
|
getHunk: (n: number) => ExpandableHunk = (n) => {
|
||||||
return {
|
return {
|
||||||
maxExpandHeadRange: this.computeMaxExpandHeadRange(n),
|
maxExpandHeadRange: this.computeMaxExpandHeadRange(n),
|
||||||
maxExpandBottomRange: this.computeMaxExpandBottomRange(n),
|
maxExpandBottomRange: this.computeMaxExpandBottomRange(n),
|
||||||
expandHead: (count: number) => this.expandHead(n, count),
|
expandHead: (count: number) => this.expandHead(n, count),
|
||||||
expandBottom: (count: number) => this.expandBottom(n, count),
|
expandBottom: (count: number) => this.expandBottom(n, count),
|
||||||
hunk: this.file?.hunks![n]
|
hunk: this.file?.hunks![n],
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
import React, { FC } from "react";
|
import React, { FC } from "react";
|
||||||
import { Color, Size } from "../styleConstants";
|
import { Color, Size } from "../styleConstants";
|
||||||
import Tooltip, {TooltipLocation} from "../Tooltip";
|
import Tooltip, { TooltipLocation } from "../Tooltip";
|
||||||
import Tag from "../Tag";
|
import Tag from "../Tag";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ function runTokenize({ id, payload }: TokenizeMessage) {
|
|||||||
const options = {
|
const options = {
|
||||||
highlight: language !== "text",
|
highlight: language !== "text",
|
||||||
language: language,
|
language: language,
|
||||||
refractor
|
refractor,
|
||||||
};
|
};
|
||||||
|
|
||||||
const doTokenization = (worker: Worker) => {
|
const doTokenization = (worker: Worker) => {
|
||||||
@@ -57,13 +57,13 @@ function runTokenize({ id, payload }: TokenizeMessage) {
|
|||||||
const tokens = tokenize(hunks, options);
|
const tokens = tokenize(hunks, options);
|
||||||
const payload = {
|
const payload = {
|
||||||
success: true,
|
success: true,
|
||||||
tokens: tokens
|
tokens: tokens,
|
||||||
};
|
};
|
||||||
worker.postMessage({ id, payload });
|
worker.postMessage({ id, payload });
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
const payload = {
|
const payload = {
|
||||||
success: false,
|
success: false,
|
||||||
reason: ex.message
|
reason: ex.message,
|
||||||
};
|
};
|
||||||
worker.postMessage({ id, payload });
|
worker.postMessage({ id, payload });
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ type Props = {
|
|||||||
const TokenizedDiffView: FC<Props> = ({ file, viewType, className, children }) => {
|
const TokenizedDiffView: FC<Props> = ({ file, viewType, className, children }) => {
|
||||||
const { tokens } = useTokenizeWorker(tokenize, {
|
const { tokens } = useTokenizeWorker(tokenize, {
|
||||||
hunks: file.hunks,
|
hunks: file.hunks,
|
||||||
language: determineLanguage(file.language)
|
language: determineLanguage(file.language),
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -40,30 +40,30 @@ const commitCreateNewApp = {
|
|||||||
revision: "0d8c1d328f4599b363755671afe667c7ace52bae",
|
revision: "0d8c1d328f4599b363755671afe667c7ace52bae",
|
||||||
author: {
|
author: {
|
||||||
name: "Arthur Dent",
|
name: "Arthur Dent",
|
||||||
mail: "arthur.dent@hitchhiker.com"
|
mail: "arthur.dent@hitchhiker.com",
|
||||||
},
|
},
|
||||||
description: "create new app",
|
description: "create new app",
|
||||||
when: new Date("2020-04-09T13:07:42Z")
|
when: new Date("2020-04-09T13:07:42Z"),
|
||||||
};
|
};
|
||||||
|
|
||||||
const commitFixedMissingImport = {
|
const commitFixedMissingImport = {
|
||||||
revision: "fab38559ce3ab8c388e067712b4bd7ab94b9fa9b",
|
revision: "fab38559ce3ab8c388e067712b4bd7ab94b9fa9b",
|
||||||
author: {
|
author: {
|
||||||
name: "Tricia Marie McMillan",
|
name: "Tricia Marie McMillan",
|
||||||
mail: "trillian@hitchhiker.com"
|
mail: "trillian@hitchhiker.com",
|
||||||
},
|
},
|
||||||
description: "fixed missing import",
|
description: "fixed missing import",
|
||||||
when: new Date("2020-05-10T09:18:42Z")
|
when: new Date("2020-05-10T09:18:42Z"),
|
||||||
};
|
};
|
||||||
|
|
||||||
const commitImplementMain = {
|
const commitImplementMain = {
|
||||||
revision: "5203292ab2bc0c020dd22adc4d3897da4930e43f",
|
revision: "5203292ab2bc0c020dd22adc4d3897da4930e43f",
|
||||||
author: {
|
author: {
|
||||||
name: "Ford Prefect",
|
name: "Ford Prefect",
|
||||||
mail: "ford.prefect@hitchhiker.com"
|
mail: "ford.prefect@hitchhiker.com",
|
||||||
},
|
},
|
||||||
description: "implemented main function",
|
description: "implemented main function",
|
||||||
when: new Date("2020-04-12T16:29:42Z")
|
when: new Date("2020-04-12T16:29:42Z"),
|
||||||
};
|
};
|
||||||
|
|
||||||
const source: AnnotatedSource = {
|
const source: AnnotatedSource = {
|
||||||
@@ -72,44 +72,44 @@ const source: AnnotatedSource = {
|
|||||||
{
|
{
|
||||||
lineNumber: 1,
|
lineNumber: 1,
|
||||||
code: "package main",
|
code: "package main",
|
||||||
...commitCreateNewApp
|
...commitCreateNewApp,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
lineNumber: 2,
|
lineNumber: 2,
|
||||||
code: "",
|
code: "",
|
||||||
...commitCreateNewApp
|
...commitCreateNewApp,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
lineNumber: 3,
|
lineNumber: 3,
|
||||||
code: 'import "fmt"',
|
code: 'import "fmt"',
|
||||||
...commitFixedMissingImport
|
...commitFixedMissingImport,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
lineNumber: 4,
|
lineNumber: 4,
|
||||||
code: "",
|
code: "",
|
||||||
...commitFixedMissingImport
|
...commitFixedMissingImport,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
lineNumber: 5,
|
lineNumber: 5,
|
||||||
code: "func main() {",
|
code: "func main() {",
|
||||||
...commitCreateNewApp
|
...commitCreateNewApp,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
lineNumber: 6,
|
lineNumber: 6,
|
||||||
code: ' fmt.Println("Hello World")',
|
code: ' fmt.Println("Hello World")',
|
||||||
...commitImplementMain
|
...commitImplementMain,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
lineNumber: 7,
|
lineNumber: 7,
|
||||||
code: "}",
|
code: "}",
|
||||||
...commitCreateNewApp
|
...commitCreateNewApp,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
lineNumber: 8,
|
lineNumber: 8,
|
||||||
code: "",
|
code: "",
|
||||||
...commitCreateNewApp
|
...commitCreateNewApp,
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
const markdownSource: AnnotatedSource = {
|
const markdownSource: AnnotatedSource = {
|
||||||
@@ -118,44 +118,44 @@ const markdownSource: AnnotatedSource = {
|
|||||||
{
|
{
|
||||||
lineNumber: 1,
|
lineNumber: 1,
|
||||||
code: "# Title",
|
code: "# Title",
|
||||||
...commitCreateNewApp
|
...commitCreateNewApp,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
lineNumber: 2,
|
lineNumber: 2,
|
||||||
code: "",
|
code: "",
|
||||||
...commitCreateNewApp
|
...commitCreateNewApp,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
lineNumber: 3,
|
lineNumber: 3,
|
||||||
code: "This is a short Markdown text.",
|
code: "This is a short Markdown text.",
|
||||||
...commitFixedMissingImport
|
...commitFixedMissingImport,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
lineNumber: 4,
|
lineNumber: 4,
|
||||||
code: "",
|
code: "",
|
||||||
...commitFixedMissingImport
|
...commitFixedMissingImport,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
lineNumber: 5,
|
lineNumber: 5,
|
||||||
code: "With **bold** and __italic__ words.",
|
code: "With **bold** and __italic__ words.",
|
||||||
...commitCreateNewApp
|
...commitCreateNewApp,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
lineNumber: 6,
|
lineNumber: 6,
|
||||||
code: "",
|
code: "",
|
||||||
...commitImplementMain
|
...commitImplementMain,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
lineNumber: 7,
|
lineNumber: 7,
|
||||||
code: "> This should be a quote",
|
code: "> This should be a quote",
|
||||||
...commitCreateNewApp
|
...commitCreateNewApp,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
lineNumber: 8,
|
lineNumber: 8,
|
||||||
code: "",
|
code: "",
|
||||||
...commitCreateNewApp
|
...commitCreateNewApp,
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
const Robohash: FC = ({ children }) => {
|
const Robohash: FC = ({ children }) => {
|
||||||
@@ -165,8 +165,8 @@ const Robohash: FC = ({ children }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
storiesOf("Repositories/Annotate", module)
|
storiesOf("Repositories/Annotate", module)
|
||||||
.addDecorator(storyFn => <MemoryRouter initialEntries={["/"]}>{storyFn()}</MemoryRouter>)
|
.addDecorator((storyFn) => <MemoryRouter initialEntries={["/"]}>{storyFn()}</MemoryRouter>)
|
||||||
.addDecorator(storyFn => <Wrapper className="box">{storyFn()}</Wrapper>)
|
.addDecorator((storyFn) => <Wrapper className="box">{storyFn()}</Wrapper>)
|
||||||
.add("Default", () => (
|
.add("Default", () => (
|
||||||
<Annotate source={source} repository={repository} baseDate={new Date("2020-04-16T09:22:42Z")} />
|
<Annotate source={source} repository={repository} baseDate={new Date("2020-04-16T09:22:42Z")} />
|
||||||
))
|
))
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ const Contributors: FC<PersonsProps> = ({ persons, label, displayTextOnly }) =>
|
|||||||
<>
|
<>
|
||||||
{t(label)}{" "}
|
{t(label)}{" "}
|
||||||
<AvatarList>
|
<AvatarList>
|
||||||
{persons.map(p => (
|
{persons.map((p) => (
|
||||||
<ContributorWithAvatar key={p.name} person={p} avatar={avatarFactory(p)} />
|
<ContributorWithAvatar key={p.name} person={p} avatar={avatarFactory(p)} />
|
||||||
))}
|
))}
|
||||||
</AvatarList>
|
</AvatarList>
|
||||||
@@ -125,9 +125,9 @@ const Contributors: FC<PersonsProps> = ({ persons, label, displayTextOnly }) =>
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{t(label)}{" "}
|
{t(label)}{" "}
|
||||||
<a title={persons.map(person => "- " + person.name).join("\n")}>
|
<span title={persons.map((person) => "- " + person.name).join("\n")}>
|
||||||
{t("changeset.contributors.more", { count: persons.length })}
|
{t("changeset.contributors.more", { count: persons.length })}
|
||||||
</a>
|
</span>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -148,7 +148,7 @@ const ChangesetAuthor: FC<Props> = ({ changeset }) => {
|
|||||||
|
|
||||||
const filterContributorsByType = (type: string) => {
|
const filterContributorsByType = (type: string) => {
|
||||||
if (changeset.contributors) {
|
if (changeset.contributors) {
|
||||||
return changeset.contributors.filter(p => p.type === type).map(contributor => contributor.person);
|
return changeset.contributors.filter((p) => p.type === type).map((contributor) => contributor.person);
|
||||||
}
|
}
|
||||||
return emptyListOfContributors;
|
return emptyListOfContributors;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -39,11 +39,11 @@ const ChangesetDescription: FC<Props> = ({ changeset, value }) => {
|
|||||||
"changeset.description.tokens",
|
"changeset.description.tokens",
|
||||||
{
|
{
|
||||||
changeset,
|
changeset,
|
||||||
value
|
value,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
return <SplitAndReplace text={value} replacements={replacements.flatMap(r => r(changeset, value))} />;
|
return <SplitAndReplace text={value} replacements={replacements.flatMap((r) => r(changeset, value))} />;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ChangesetDescription;
|
export default ChangesetDescription;
|
||||||
|
|||||||
@@ -29,9 +29,9 @@ describe("isDiffSupported tests", () => {
|
|||||||
const supported = isDiffSupported({
|
const supported = isDiffSupported({
|
||||||
_links: {
|
_links: {
|
||||||
diff: {
|
diff: {
|
||||||
href: "http://diff"
|
href: "http://diff",
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(supported).toBe(true);
|
expect(supported).toBe(true);
|
||||||
@@ -41,9 +41,9 @@ describe("isDiffSupported tests", () => {
|
|||||||
const supported = isDiffSupported({
|
const supported = isDiffSupported({
|
||||||
_links: {
|
_links: {
|
||||||
diffParsed: {
|
diffParsed: {
|
||||||
href: "http://diff"
|
href: "http://diff",
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(supported).toBe(true);
|
expect(supported).toBe(true);
|
||||||
@@ -51,7 +51,7 @@ describe("isDiffSupported tests", () => {
|
|||||||
|
|
||||||
it("should return false if not diff link was provided", () => {
|
it("should return false if not diff link was provided", () => {
|
||||||
const supported = isDiffSupported({
|
const supported = isDiffSupported({
|
||||||
_links: {}
|
_links: {},
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(supported).toBe(false);
|
expect(supported).toBe(false);
|
||||||
@@ -63,9 +63,9 @@ describe("createUrl tests", () => {
|
|||||||
const url = createUrl({
|
const url = createUrl({
|
||||||
_links: {
|
_links: {
|
||||||
diff: {
|
diff: {
|
||||||
href: "http://diff"
|
href: "http://diff",
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(url).toBe("http://diff?format=GIT");
|
expect(url).toBe("http://diff?format=GIT");
|
||||||
@@ -75,9 +75,9 @@ describe("createUrl tests", () => {
|
|||||||
const url = createUrl({
|
const url = createUrl({
|
||||||
_links: {
|
_links: {
|
||||||
diffParsed: {
|
diffParsed: {
|
||||||
href: "http://diff-parsed"
|
href: "http://diff-parsed",
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(url).toBe("http://diff-parsed");
|
expect(url).toBe("http://diff-parsed");
|
||||||
@@ -87,12 +87,12 @@ describe("createUrl tests", () => {
|
|||||||
const url = createUrl({
|
const url = createUrl({
|
||||||
_links: {
|
_links: {
|
||||||
diff: {
|
diff: {
|
||||||
href: "http://diff"
|
href: "http://diff",
|
||||||
},
|
},
|
||||||
diffParsed: {
|
diffParsed: {
|
||||||
href: "http://diff-parsed"
|
href: "http://diff-parsed",
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(url).toBe("http://diff-parsed");
|
expect(url).toBe("http://diff-parsed");
|
||||||
@@ -101,7 +101,7 @@ describe("createUrl tests", () => {
|
|||||||
it("should throw an error if no diff link is defined", () => {
|
it("should throw an error if no diff link is defined", () => {
|
||||||
expect(() =>
|
expect(() =>
|
||||||
createUrl({
|
createUrl({
|
||||||
_links: {}
|
_links: {},
|
||||||
})
|
})
|
||||||
).toThrow();
|
).toThrow();
|
||||||
});
|
});
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user