import * as types from '../../../modules/types'; import { Repository, File, Action } from '@scm-manager/ui-types'; import { apiClient } from '@scm-manager/ui-components'; import { isPending } from '../../../modules/pending'; import { getFailure } from '../../../modules/failure'; export const FETCH_SOURCES = 'scm/repos/FETCH_SOURCES'; 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( repository: Repository, revision: string, path: string, ) { return function(dispatch: any) { dispatch(fetchSourcesPending(repository, revision, path)); return apiClient .get(createUrl(repository, revision, path)) .then(response => response.json()) .then(sources => { dispatch(fetchSourcesSuccess(repository, revision, path, sources)); }) .catch(err => { dispatch(fetchSourcesFailure(repository, revision, path, err)); }); }; } function createUrl(repository: Repository, revision: string, path: string) { const base = repository._links.sources.href; if (!revision && !path) { return base; } // TODO handle trailing slash const pathDefined = path ? path : ''; return `${base}${encodeURIComponent(revision)}/${pathDefined}`; } export function fetchSourcesPending( repository: Repository, revision: string, path: string, ): Action { return { type: FETCH_SOURCES_PENDING, itemId: createItemId(repository, revision, path), }; } export function fetchSourcesSuccess( repository: Repository, revision: string, path: string, sources: File, ) { return { type: FETCH_SOURCES_SUCCESS, payload: sources, itemId: createItemId(repository, revision, path), }; } export function fetchSourcesFailure( repository: Repository, revision: string, path: string, error: Error, ): Action { return { type: FETCH_SOURCES_FAILURE, payload: error, itemId: createItemId(repository, revision, path), }; } function createItemId(repository: Repository, revision: string, path: string) { const revPart = revision ? revision : '_'; const pathPart = path ? path : ''; return `${repository.namespace}/${repository.name}/${revPart}/${pathPart}`; } // reducer export default function reducer( state: any = {}, action: Action = { type: 'UNKNOWN', }, ): any { if (action.itemId && action.type === FETCH_SOURCES_SUCCESS) { return { ...state, [action.itemId]: action.payload, }; } return state; } // selectors 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 } } export function getSources( state: any, repository: Repository, revision: string, path: string, ): File | null | undefined { if (state.sources) { return state.sources[createItemId(repository, revision, path)]; } return null; } export function isFetchSourcesPending( state: any, repository: Repository, revision: string, path: string, ): boolean { return isPending( state, FETCH_SOURCES, createItemId(repository, revision, path), ); } export function getFetchSourcesFailure( state: any, repository: Repository, revision: string, path: string, ): Error | null | undefined { return getFailure( state, FETCH_SOURCES, createItemId(repository, revision, path), ); }