Blame core/sagas/inputs.js

Packit Service eebd6f
import { call, put, takeEvery, takeLatest, select } from "redux-saga/effects";
Packit Service eebd6f
import * as composer from "../composer";
Packit Service eebd6f
import {
Packit Service eebd6f
  FETCHING_INPUTS,
Packit Service eebd6f
  fetchingInputsSucceeded,
Packit Service eebd6f
  fetchingFilterNoResults,
Packit Service eebd6f
  FETCHING_INPUT_DETAILS,
Packit Service eebd6f
  FETCHING_INPUT_DEPS,
Packit Service eebd6f
  FETCHING_DEP_DETAILS,
Packit Service eebd6f
  setSelectedInput,
Packit Service eebd6f
  setSelectedInputDeps,
Packit Service eebd6f
  setDepDetails,
Packit Service eebd6f
} from "../actions/inputs";
Packit Service eebd6f
import { makeGetBlueprintById, makeGetSelectedDeps } from "../selectors";
Packit Service eebd6f
Packit Service eebd6f
function flattenInputs(response) {
Packit Service eebd6f
  // duplicate inputs exist when more than one build is available
Packit Service eebd6f
  // flatten duplicate inputs to a single item
Packit Service eebd6f
  const previousInputs = {};
Packit Service eebd6f
  const flattened = response.filter((item) => {
Packit Service eebd6f
    const build = {
Packit Service eebd6f
      version: item.builds[0].source.version,
Packit Service eebd6f
      release: item.builds[0].release,
Packit Service eebd6f
    };
Packit Service eebd6f
    if (previousInputs.hasOwnProperty(item.name)) {
Packit Service eebd6f
      // update the previousInput object with this item"s version/release
Packit Service eebd6f
      // to make the default version/release the latest
Packit Service eebd6f
      previousInputs[item.name] = Object.assign(previousInputs[item.name], build);
Packit Service eebd6f
      // and remove this item from the list
Packit Service eebd6f
      return false;
Packit Service eebd6f
    }
Packit Service eebd6f
    delete item.builds;
Packit Service eebd6f
    item = Object.assign(item, build);
Packit Service eebd6f
Packit Service eebd6f
    previousInputs[item.name] = item;
Packit Service eebd6f
    return true;
Packit Service eebd6f
  });
Packit Service eebd6f
  return flattened;
Packit Service eebd6f
}
Packit Service eebd6f
Packit Service eebd6f
function* fetchInputs(action) {
Packit Service eebd6f
  try {
Packit Service eebd6f
    const { filter, selectedInputPage, pageSize } = action.payload;
Packit Service 0c2606
    const wildcardsUsed = filter.value.includes("*");
Packit Service 0c2606
    const regex = / +|, +/g;
Packit Service 0c2606
    let filterValue = filter.value.replace(regex, ",");
Packit Service 0c2606
    const regexStrip = /(^,+)|(,+$)/g;
Packit Service 0c2606
    filterValue = filterValue.replace(regexStrip, "");
Packit Service 0c2606
    filterValue = wildcardsUsed ? filterValue : `*${filterValue}*`.replace(/,/g, "*,*");
Packit Service 0c2606
    // page is displayed in UI starting from 1 but api starts from 0
Packit Service 0c2606
    const pageIndex = selectedInputPage - 1;
Packit Service 0c2606
    const response = yield call(composer.listModules, filterValue, pageIndex, pageSize);
Packit Service eebd6f
    const { total } = response;
Packit Service eebd6f
    const inputNames = response.modules.map((input) => input.name).join(",");
Packit Service eebd6f
    const inputs = yield call(composer.getComponentInfo, inputNames);
Packit Service eebd6f
    const updatedInputs = flattenInputs(inputs).map((input) => {
Packit Service eebd6f
      const inputData = {
Packit Service eebd6f
        ui_type: "RPM",
Packit Service eebd6f
        ...input,
Packit Service eebd6f
      };
Packit Service eebd6f
      return inputData;
Packit Service eebd6f
    });
Packit Service eebd6f
    yield put(fetchingInputsSucceeded(filter, selectedInputPage, pageSize, updatedInputs, total));
Packit Service eebd6f
  } catch (error) {
Packit Service eebd6f
    const { filter, pageSize } = action.payload;
Packit Service eebd6f
    if (filter.value !== "") {
Packit Service eebd6f
      yield put(fetchingFilterNoResults(filter, pageSize));
Packit Service eebd6f
    } else {
Packit Service eebd6f
      console.log("Error in fetchInputsSaga", error);
Packit Service eebd6f
    }
Packit Service eebd6f
  }
Packit Service eebd6f
}
Packit Service eebd6f
Packit Service eebd6f
function flattenInput(response) {
Packit Service eebd6f
  // each response item is a different build (version, release, arch)
Packit Service eebd6f
  // flatten the response to a single item with an array of builds
Packit Service eebd6f
  // only keep the latest release per version
Packit Service eebd6f
  // for each version, include wildcard options
Packit Service eebd6f
  const previousBuilds = {};
Packit Service eebd6f
  const flattened = { ...response[0], builds: [] };
Packit Service eebd6f
  response.forEach((item) => {
Packit Service eebd6f
    let previousBuild;
Packit Service eebd6f
    const build = {
Packit Service eebd6f
      version: item.builds[0].source.version,
Packit Service eebd6f
      release: item.builds[0].release,
Packit Service eebd6f
      arch: [item.builds[0].arch],
Packit Service eebd6f
    };
Packit Service eebd6f
    if (previousBuilds.hasOwnProperty(build.version)) {
Packit Service eebd6f
      // if this item has the same version value as a
Packit Service eebd6f
      // previousBuild replace the release value (this is assumed to be the latest)
Packit Service eebd6f
      // then push arch to the array of arch's and filter this item out
Packit Service eebd6f
      previousBuild = previousBuilds[build.version];
Packit Service eebd6f
      previousBuild.arch = previousBuild.arch.concat(build.arch);
Packit Service eebd6f
      previousBuild.release = build.release;
Packit Service eebd6f
      return false;
Packit Service eebd6f
    }
Packit Service eebd6f
    // else push the build to the array of builds
Packit Service eebd6f
    flattened.builds = [build].concat(flattened.builds);
Packit Service eebd6f
Packit Service eebd6f
    previousBuilds[build.version] = build;
Packit Service eebd6f
    return true;
Packit Service eebd6f
  });
Packit Service eebd6f
  flattened.builds = addWildcardVersions(flattened.builds);
Packit Service eebd6f
  return flattened;
Packit Service eebd6f
}
Packit Service eebd6f
Packit Service eebd6f
function addWildcardVersions(builds) {
Packit Service eebd6f
  const wildcardBuilds = {};
Packit Service eebd6f
  builds.forEach((item) => {
Packit Service eebd6f
    item.depsolveVersion = item.version;
Packit Service eebd6f
Packit Service eebd6f
    const parts = item.version.split(".");
Packit Service eebd6f
    for (let i = 0; i < parts.length; i += 1) {
Packit Service eebd6f
      const wildcard = parts.slice(0, i).concat("*").join(".");
Packit Service eebd6f
Packit Service eebd6f
      if (!(wildcard in wildcardBuilds)) {
Packit Service eebd6f
        wildcardBuilds[wildcard] = { ...item, version: wildcard };
Packit Service eebd6f
      }
Packit Service eebd6f
    }
Packit Service eebd6f
    wildcardBuilds[item.version] = { ...item };
Packit Service eebd6f
  });
Packit Service eebd6f
Packit Service eebd6f
  return Object.values(wildcardBuilds);
Packit Service eebd6f
}
Packit Service eebd6f
Packit Service eebd6f
// when ComponentDetailsView loads, get component details
Packit Service eebd6f
function* fetchInputDetails(action) {
Packit Service eebd6f
  try {
Packit Service eebd6f
    const { component } = action.payload;
Packit Service eebd6f
    const response = yield call(composer.getComponentInfo, component.name);
Packit Service eebd6f
    const updatedResponse = flattenInput(response);
Packit Service eebd6f
    const componentData = {
Packit Service eebd6f
      ...component,
Packit Service eebd6f
      builds: updatedResponse.builds,
Packit Service eebd6f
      description: updatedResponse.description,
Packit Service eebd6f
      homepage: updatedResponse.homepage,
Packit Service eebd6f
      summary: updatedResponse.summary,
Packit Service eebd6f
    };
Packit Service eebd6f
    yield put(setSelectedInput(componentData));
Packit Service eebd6f
  } catch (error) {
Packit Service eebd6f
    console.log("Error in fetchInputDetails", error);
Packit Service eebd6f
  }
Packit Service eebd6f
}
Packit Service eebd6f
Packit Service eebd6f
// when ComponentDetailsView loads, get component dependencies
Packit Service eebd6f
function* fetchInputDeps(action) {
Packit Service eebd6f
  try {
Packit Service eebd6f
    const { component } = action.payload;
Packit Service eebd6f
    const response = yield call(composer.getComponentDependencies, component.name);
Packit Service eebd6f
    let responseIndex;
Packit Service eebd6f
    if (response[0].builds) {
Packit Service eebd6f
      responseIndex = response.findIndex((item) => {
Packit Service eebd6f
        return item.builds[0].release === component.release && item.builds[0].source.version === component.version;
Packit Service eebd6f
      });
Packit Service eebd6f
    } else {
Packit Service eebd6f
      responseIndex = 0;
Packit Service eebd6f
    }
Packit Service eebd6f
    const deps = response[responseIndex].dependencies.filter((item) => item.name !== component.name);
Packit Service eebd6f
    const updatedDeps = deps.map((dep) => {
Packit Service eebd6f
      const depData = {
Packit Service eebd6f
        ui_type: "RPM",
Packit Service eebd6f
        ...dep,
Packit Service eebd6f
      };
Packit Service eebd6f
      delete depData.epoch;
Packit Service eebd6f
      delete depData.arch;
Packit Service eebd6f
      return depData;
Packit Service eebd6f
    });
Packit Service eebd6f
    yield put(setSelectedInputDeps(updatedDeps));
Packit Service eebd6f
  } catch (error) {
Packit Service eebd6f
    console.log("Error in fetchInputDeps", error);
Packit Service eebd6f
  }
Packit Service eebd6f
}
Packit Service eebd6f
Packit Service eebd6f
// when expanding a dependency list item in ComponentDetailsView
Packit Service eebd6f
// get additional details to display in expanded section
Packit Service eebd6f
function* fetchDepDetails(action) {
Packit Service eebd6f
  try {
Packit Service eebd6f
    const { component, blueprintId } = action.payload;
Packit Service eebd6f
    const response = yield call(composer.getComponentDependencies, component.name);
Packit Service eebd6f
    const deps = response[0].dependencies.filter((item) => item.name !== component.name);
Packit Service eebd6f
    const updatedDeps = deps.map((dep) => {
Packit Service eebd6f
      const depData = { ui_type: "RPM", ...dep };
Packit Service eebd6f
      delete depData.epoch;
Packit Service eebd6f
      delete depData.arch;
Packit Service eebd6f
      return depData;
Packit Service eebd6f
    });
Packit Service eebd6f
    const getBlueprintById = makeGetBlueprintById();
Packit Service eebd6f
    const blueprint = yield select(getBlueprintById, blueprintId);
Packit Service eebd6f
    const { components } = blueprint.present;
Packit Service eebd6f
Packit Service eebd6f
    const getSelectedDeps = makeGetSelectedDeps();
Packit Service eebd6f
    const selectedDeps = yield select(getSelectedDeps, updatedDeps, components);
Packit Service eebd6f
Packit Service eebd6f
    const depDetails = {
Packit Service eebd6f
      ...component,
Packit Service eebd6f
      description: response[0].description,
Packit Service eebd6f
      homepage: response[0].homepage,
Packit Service eebd6f
      summary: response[0].summary,
Packit Service eebd6f
      dependencies: selectedDeps,
Packit Service eebd6f
    };
Packit Service eebd6f
    yield put(setDepDetails(depDetails));
Packit Service eebd6f
  } catch (error) {
Packit Service eebd6f
    console.log("Error in fetchDepDetails", error);
Packit Service eebd6f
  }
Packit Service eebd6f
}
Packit Service eebd6f
Packit Service eebd6f
export default function* () {
Packit Service 0c2606
  yield takeLatest(FETCHING_INPUTS, fetchInputs);
Packit Service eebd6f
  yield takeLatest(FETCHING_INPUT_DETAILS, fetchInputDetails);
Packit Service eebd6f
  yield takeLatest(FETCHING_INPUT_DEPS, fetchInputDeps);
Packit Service eebd6f
  yield takeEvery(FETCHING_DEP_DETAILS, fetchDepDetails);
Packit Service eebd6f
}