Files
SCM-Manager/scm-ui/ui-webapp/src/repos/sources/modules/sources.ts

146 lines
4.6 KiB
TypeScript
Raw Normal View History

import * as types from "../../../modules/types";
import { Repository, File, Action, Link } from "@scm-manager/ui-types";
import { apiClient } from "@scm-manager/ui-components";
import { isPending } from "../../../modules/pending";
import { getFailure } from "../../../modules/failure";
2018-09-27 16:32:37 +02:00
export const FETCH_SOURCES = "scm/repos/FETCH_SOURCES";
2018-09-27 16:32:37 +02:00
export const FETCH_SOURCES_PENDING = `${FETCH_SOURCES}_${types.PENDING_SUFFIX}`;
export const FETCH_SOURCES_SUCCESS = `${FETCH_SOURCES}_${types.SUCCESS_SUFFIX}`;
export const FETCH_SOURCES_FAILURE = `${FETCH_SOURCES}_${types.FAILURE_SUFFIX}`;
export function fetchSources(
2019-12-11 15:49:33 +01:00
repository: Repository,
revision: string,
path: string,
initialLoad = true
2019-12-11 15:49:33 +01:00
) {
return function(dispatch: any, getState: () => any) {
const state = getState();
if (isFetchSourcesPending(state, repository, revision, path)
|| isUpdateSourcePending(state, repository, revision, path)) {
return;
}
if (initialLoad) {
2019-12-11 15:49:33 +01:00
dispatch(fetchSourcesPending(repository, revision, path));
} else {
dispatch(updateSourcesPending(repository, revision, path, getSources(state, repository, revision, path)));
2019-12-11 15:49:33 +01:00
}
2018-09-27 16:32:37 +02:00
return apiClient
.get(createUrl(repository, revision, path))
2018-09-27 16:32:37 +02:00
.then(response => response.json())
2019-12-11 15:49:33 +01:00
.then((sources: File) => {
dispatch(fetchSourcesSuccess(repository, revision, path, sources));
2018-09-27 16:32:37 +02:00
})
.catch(err => {
dispatch(fetchSourcesFailure(repository, revision, path, err));
2018-09-27 16:32:37 +02:00
});
};
}
function createUrl(repository: Repository, revision: string, path: string) {
const base = (repository._links.sources as Link).href;
if (!revision && !path) {
return base;
}
// TODO handle trailing slash
const pathDefined = path ? path : "";
2018-10-23 13:03:15 +02:00
return `${base}${encodeURIComponent(revision)}/${pathDefined}`;
}
2019-10-21 10:57:56 +02:00
export function fetchSourcesPending(repository: Repository, revision: string, path: string): Action {
2018-09-27 16:32:37 +02:00
return {
type: FETCH_SOURCES_PENDING,
itemId: createItemId(repository, revision, path)
2018-09-27 16:32:37 +02:00
};
}
export function updateSourcesPending(repository: Repository, revision: string, path: string, currentSources: any): Action {
return {
type: "UPDATE_PENDING",
payload: { updatePending: true, sources: currentSources},
itemId: createItemId(repository, revision, path)
};
}
2019-10-21 10:57:56 +02:00
export function fetchSourcesSuccess(repository: Repository, revision: string, path: string, sources: File) {
2018-09-27 16:32:37 +02:00
return {
type: FETCH_SOURCES_SUCCESS,
payload: { updatePending: false, sources },
itemId: createItemId(repository, revision, path)
2018-09-27 16:32:37 +02:00
};
}
2019-10-21 10:57:56 +02:00
export function fetchSourcesFailure(repository: Repository, revision: string, path: string, error: Error): Action {
2018-09-27 16:32:37 +02:00
return {
type: FETCH_SOURCES_FAILURE,
payload: error,
itemId: createItemId(repository, revision, path)
2018-09-27 16:32:37 +02:00
};
}
function createItemId(repository: Repository, revision: string, path: string) {
const revPart = revision ? revision : "_";
const pathPart = path ? path : "";
return `${repository.namespace}/${repository.name}/${decodeURIComponent(revPart)}/${pathPart}`;
2018-09-27 16:32:37 +02:00
}
// reducer
export default function reducer(
state: any = {},
action: Action = {
type: "UNKNOWN"
}
2018-09-27 16:32:37 +02:00
): any {
if (action.itemId && (action.type === FETCH_SOURCES_SUCCESS || action.type === "UPDATE_PENDING")) {
2018-09-27 16:32:37 +02:00
return {
...state,
[action.itemId]: action.payload
2018-09-27 16:32:37 +02:00
};
}
return state;
}
// selectors
2019-10-21 10:57:56 +02:00
export function isDirectory(state: any, repository: Repository, revision: string, path: string): boolean {
const currentFile = getSources(state, repository, revision, path);
if (currentFile && !currentFile.directory) {
return false;
} else {
return true; //also return true if no currentFile is found since it is the "default" path
}
}
2018-09-27 16:32:37 +02:00
export function getSources(
state: any,
repository: Repository,
revision: string,
path: string
): File | null | undefined {
2018-09-27 16:32:37 +02:00
if (state.sources) {
return state.sources[createItemId(repository, revision, path)]?.sources;
2018-09-27 16:32:37 +02:00
}
return null;
}
2019-10-21 10:57:56 +02:00
export function isFetchSourcesPending(state: any, repository: Repository, revision: string, path: string): boolean {
return state && isPending(state, FETCH_SOURCES, createItemId(repository, revision, path));
}
function isUpdateSourcePending(state: any, repository: Repository, revision: string, path: string): boolean {
return state?.sources[createItemId(repository, revision, path)]?.updatePending;
2018-09-27 16:32:37 +02:00
}
export function getFetchSourcesFailure(
state: any,
repository: Repository,
revision: string,
path: string
): Error | null | undefined {
2019-10-21 10:57:56 +02:00
return getFailure(state, FETCH_SOURCES, createItemId(repository, revision, path));
2018-09-27 16:32:37 +02:00
}