Repository: apache/superset
File: superset-frontend/src/dashboard/util/activeAllDashboardFilters.ts (TypeScript)

Code before:
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
import {
  DataMaskStateWithId,
  DataMaskWithId,
  JsonObject,
  PartialFilters,
} from '@superset-ui/core';
import { ActiveFilters, ChartConfiguration } from '../types';

export const getRelevantDataMask = (
  dataMask: DataMaskStateWithId,
  prop: keyof DataMaskWithId,
): JsonObject =>
  Object.fromEntries(
    Object.values(dataMask)
      .filter(item => item[prop])
      .map(item => [item.id, item[prop]]),
  );

interface LayerInfo {
  layerMap: { [chartId: number]: number[] };
  chartIds: Set<number>;
}

const extractLayerIndicesFromKeys = (selectedLayers: string[]): LayerInfo => {
  const layerMap: { [chartId: number]: number[] } = {};
  const chartIds = new Set<number>();
  selectedLayers.forEach(layerKey => {
    const match = layerKey.match(/^chart-(\d+)-layer-(\d+)$/);
    if (match) {
      const chartId = parseInt(match[1], 10);
      const layerIndex = parseInt(match[2], 10);
      if (!Number.isNaN(chartId)) {
        if (!layerMap[chartId]) {
          layerMap[chartId] = [];
        }
        layerMap[chartId].push(layerIndex);
        chartIds.add(chartId);
      }
    }
  });
  return { layerMap, chartIds };
};


Review comment (suggestion):
Shouldn't this be handled by the chart component instead of `getRelevantDataMask`? I'm wondering if `clientView` might be useful for another caller of `getRelevantDataMask` and should just be discarded by the chart when re-rendering. 

Code after:
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
import {
  DataMaskStateWithId,
  DataMaskWithId,
  JsonObject,
  PartialFilters,
} from '@superset-ui/core';
import { omit } from 'lodash';
import { ActiveFilters, ChartConfiguration } from '../types';

export const getRelevantDataMask = (
  dataMask: DataMaskStateWithId,
  prop: keyof DataMaskWithId,
): JsonObject =>
  Object.fromEntries(
    Object.values(dataMask)
      .filter(item => item[prop])
      .map(item => {
        const value = item[prop];
        // TableChart writes clientView to ownState on every filtered-row change for export
        // but clientView changes should NOT trigger chart re-queries
        // Only clone when clientView exists to avoid unnecessary allocations
        if (
          prop === 'ownState' &&
          value &&
          typeof value === 'object' &&
          'clientView' in value
        ) {
          return [item.id, omit(value, ['clientView'])];
        }
        return [item.id, value];
      }),
  );

interface LayerInfo {
  layerMap: { [chartId: number]: number[] };
  chartIds: Set<number>;
}

const extractLayerIndicesFromKeys = (selectedLayers: string[]): LayerInfo => {
  const layerMap: { [chartId: number]: number[] } = {};
  const chartIds = new Set<number>();
  selectedLayers.forEach(layerKey => {
    const match = layerKey.match(/^chart-(\d+)-layer-(\d+)$/);