<commit_before>import { createAction, createThunkAction } from 'redux/actions';
import flatten from 'lodash/flatten';
import sortBy from 'lodash/sortBy';
import chroma from 'chroma-js';

import { getDatasets } from 'services/datasets';
import thresholdOptions from 'data/thresholds.json';

import { reduceParams, reduceSqlParams } from './utils';
import decodeLayersConfig from './config';

export const setDatasetsLoading = createAction('setDatasetsLoading');
export const setDatasets = createAction('setDatasets');

const byVocabulary = (dataset) =>
  dataset.vocabulary &&
  dataset.vocabulary.some(
    (o) => o.name === 'layer_manager_ver' && o.tags.includes('3.0')
  );

export const fetchDatasets = createThunkAction(
  'fetchDatasets',
  () => (dispatch) => {
    dispatch(setDatasetsLoading({ loading: true, error: false }));
    getDatasets()
      .then((datasets) => {
        const parsedDatasets = datasets
          .filter(
            (d) =>
              d.published &&
              d.layer.length &&
              (d.env === 'production' ||
                d.env === process.env.NEXT_PUBLIC_FEATURE_ENV)
          )
          .filter(byVocabulary)
          .map((d) => {
            const { layer, metadata } = d;
            const appMeta =
              (metadata && metadata.find((m) => m.application === 'gfw')) || {};
            const { info } = appMeta || {};
            const defaultLayer =
              (layer &&
                layer.find(
                  (l) =>
                    (l.env === 'production' ||
                      l.env === process.env.NEXT_PUBLIC_FEATURE_ENV) &&
                    l.applicationConfig &&
                    l.applicationConfig.default
                )) ||
              layer[0];
            // we need a default layer so we can set it when toggled onto the map
            if (!defaultLayer) return null;

            const {
              isSelectorLayer,
              isMultiSelectorLayer,
              isLossLayer,
              isLossDriverLayer,
            } = info || {};
            const { iso, applicationConfig } = defaultLayer || {};
            const { global, selectorConfig } = applicationConfig || {};

            // build statement config
            let statementConfig =
              defaultLayer.legendConfig && defaultLayer.legendConfig.statement
                ? { statement: defaultLayer.legendConfig.statement }
                : null;
            if (isLossLayer) {
              statementConfig = {
                type: 'lossLayer',
              };
            } else if (isLossDriverLayer) {
              statementConfig = {
                type: 'lossDriverLayer',
              };
            } else if (global && !!iso.length && iso[0]) {
              statementConfig = {
                type: 'isoLayer',
                isos: iso,
              };
            }

            return {
              id: applicationConfig?.dataset_slug || applicationConfig.slug,
              dataset:
                applicationConfig?.dataset_slug || applicationConfig.slug,
              name: d.name,
              layer: applicationConfig.slug,
              ...applicationConfig,
              ...info,
              iso,
              slug: applicationConfig?.dataset_slug || applicationConfig.slug,
              tags: flatten(d.vocabulary.map((v) => v.tags)),
              // dropdown selector config
              ...((isSelectorLayer || isMultiSelectorLayer) && {
                selectorLayerConfig: {
                  options: layer.map((l) => ({
                    ...l.applicationConfig.selectorConfig,
                    value: l?.applicationConfig?.slug,
                  })),
                  ...selectorConfig,
                },
              }),
              // disclaimer statement config
              statementConfig,
              // layers config
              layers:
                layer &&
                sortBy(
                  layer
                    .filter(
                      (l) =>
                        (l.env === 'production' ||
                          l.env === process.env.NEXT_PUBLIC_FEATURE_ENV) &&
                        l.published
                    )
                    .map((l, i) => {
                      const { layerConfig, legendConfig } = l;
                      const { position, confirmedOnly, multiConfig } =
                        l.applicationConfig || {};
                      const {
                        params_config,
                        decode_config,
                        sql_config,
                        timeline_config,
                        source, // v3<commit_msg>add support for mixed env<commit_after>import { createAction, createThunkAction } from 'redux/actions';
import flatten from 'lodash/flatten';
import sortBy from 'lodash/sortBy';
import chroma from 'chroma-js';

import { getDatasets } from 'services/datasets';
import thresholdOptions from 'data/thresholds.json';

import { reduceParams, reduceSqlParams } from './utils';
import decodeLayersConfig from './config';

export const setDatasetsLoading = createAction('setDatasetsLoading');
export const setDatasets = createAction('setDatasets');

const byVocabulary = (dataset) =>
  dataset.vocabulary &&
  dataset.vocabulary.some(
    (o) => o.name === 'layer_manager_ver' && o.tags.includes('3.0')
  );

const handleFeatureEnvLock = (env) => {
  const currEnv = process.env.NEXT_PUBLIC_FEATURE_ENV;
  const MIXED_ENV = 'preproduction-staging';
  if (env === MIXED_ENV && currEnv !== 'production') {
    return true;
  }
  return env === currEnv;
};

export const fetchDatasets = createThunkAction(
  'fetchDatasets',
  () => (dispatch) => {
    dispatch(setDatasetsLoading({ loading: true, error: false }));
    getDatasets()
      .then((datasets) => {
        const parsedDatasets = datasets
          .filter(
            (d) =>
              d.published &&
              d.layer.length &&
              (d.env === 'production' || handleFeatureEnvLock(d.env))
          )
          .filter(byVocabulary)
          .map((d) => {
            const { layer, metadata } = d;
            const appMeta =
              (metadata && metadata.find((m) => m.application === 'gfw')) || {};
            const { info } = appMeta || {};
            const defaultLayer =
              (layer &&
                layer.find(
                  (l) =>
                    (l.env === 'production' || handleFeatureEnvLock(l.env)) &&
                    l.applicationConfig &&
                    l.applicationConfig.default
                )) ||
              layer[0];
            // we need a default layer so we can set it when toggled onto the map
            if (!defaultLayer) return null;

            const {
              isSelectorLayer,
              isMultiSelectorLayer,
              isLossLayer,
              isLossDriverLayer,
            } = info || {};
            const { iso, applicationConfig } = defaultLayer || {};
            const { global, selectorConfig } = applicationConfig || {};

            // build statement config
            let statementConfig =
              defaultLayer.legendConfig && defaultLayer.legendConfig.statement
                ? { statement: defaultLayer.legendConfig.statement }
                : null;
            if (isLossLayer) {
              statementConfig = {
                type: 'lossLayer',
              };
            } else if (isLossDriverLayer) {
              statementConfig = {
                type: 'lossDriverLayer',
              };
            } else if (global && !!iso.length && iso[0]) {
              statementConfig = {
                type: 'isoLayer',
                isos: iso,
              };
            }

            return {
              id: applicationConfig?.dataset_slug || applicationConfig.slug,
              dataset:
                applicationConfig?.dataset_slug || applicationConfig.slug,
              name: d.name,
              layer: applicationConfig.slug,
              ...applicationConfig,
              ...info,
              iso,
              slug: applicationConfig?.dataset_slug || applicationConfig.slug,
              tags: flatten(d.vocabulary.map((v) => v.tags)),
              // dropdown selector config
              ...((isSelectorLayer || isMultiSelectorLayer) && {
                selectorLayerConfig: {
                  options: layer.map((l) => ({
                    ...l.applicationConfig.selectorConfig,
                    value: l?.applicationConfig?.slug,
                  })),
                  ...selectorConfig,
                },
              }),
              // disclaimer statement config
              statementConfig,
              // layers config
              layers:
                layer &&
                sortBy(
                  layer
                    .filter(
                      (l) =>
                        (l.env === 'production' ||
                          handleFeatureEnvLock(l.env)) &&
                        l.published
                    )
                    .map((l, i) => {
                      const { layerConfig, legendConfig } = l;
                      const { position, confirmedOnly, multiConfig } =
                        l.applicationConfig || {};
                      const {
                        params_config,
                        decode_config,
                        sql_config,
                        timeline_config,
                        source, // v3
{'fraction_non_alphanumeric': 0.10904311251314405, 'fraction_numerical': 0.0010515247108307045, 'mean_word_length': 1.3460779477059694, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 30, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7574263', 'n_tokens_mistral': 2330, 'n_tokens_neox': 2254, 'n_words': 485}