superset urlUtils 源码

  • 2022-10-20
  • 浏览 (245)

superset urlUtils 代码

文件路径:/superset-frontend/src/utils/urlUtils.ts

/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * 'License'); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * 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 {
  isDefined,
  JsonObject,
  QueryFormData,
  SupersetClient,
} from '@superset-ui/core';
import rison from 'rison';
import { isEmpty } from 'lodash';
import {
  RESERVED_CHART_URL_PARAMS,
  RESERVED_DASHBOARD_URL_PARAMS,
  URL_PARAMS,
} from '../constants';
import { getActiveFilters } from '../dashboard/util/activeDashboardFilters';
import serializeActiveFilterValues from '../dashboard/util/serializeActiveFilterValues';

export type UrlParamType = 'string' | 'number' | 'boolean' | 'object' | 'rison';
export type UrlParam = typeof URL_PARAMS[keyof typeof URL_PARAMS];
export function getUrlParam(
  param: UrlParam & { type: 'string' },
): string | null;
export function getUrlParam(
  param: UrlParam & { type: 'number' },
): number | null;
export function getUrlParam(
  param: UrlParam & { type: 'boolean' },
): boolean | null;
export function getUrlParam(
  param: UrlParam & { type: 'object' },
): object | null;
export function getUrlParam(param: UrlParam & { type: 'rison' }): object | null;
export function getUrlParam(
  param: UrlParam & { type: 'rison | string' },
): string | object | null;
export function getUrlParam({ name, type }: UrlParam): unknown {
  const urlParam = new URLSearchParams(window.location.search).get(name);
  switch (type) {
    case 'number':
      if (!urlParam) {
        return null;
      }
      if (urlParam.toLowerCase() === 'true') {
        return 1;
      }
      if (urlParam.toLowerCase() === 'false') {
        return 0;
      }
      if (!Number.isNaN(Number(urlParam))) {
        return Number(urlParam);
      }
      return null;
    case 'object':
      if (!urlParam) {
        return null;
      }
      return JSON.parse(urlParam);
    case 'boolean':
      if (!urlParam) {
        return null;
      }
      return urlParam.toLowerCase() !== 'false' && urlParam !== '0';
    case 'rison':
      if (!urlParam) {
        return null;
      }
      try {
        return rison.decode(urlParam);
      } catch {
        return urlParam;
      }
    default:
      return urlParam;
  }
}

function getUrlParams(excludedParams: string[]): URLSearchParams {
  const urlParams = new URLSearchParams();
  const currentParams = new URLSearchParams(window.location.search);
  currentParams.forEach((value, key) => {
    if (!excludedParams.includes(key)) urlParams.append(key, value);
  });
  return urlParams;
}

export type UrlParamEntries = [string, string][];

function getUrlParamEntries(urlParams: URLSearchParams): UrlParamEntries {
  const urlEntries: [string, string][] = [];
  urlParams.forEach((value, key) => urlEntries.push([key, value]));
  return urlEntries;
}

function getChartUrlParams(excludedUrlParams?: string[]): UrlParamEntries {
  const excludedParams = excludedUrlParams || RESERVED_CHART_URL_PARAMS;
  const urlParams = getUrlParams(excludedParams);
  const filterBoxFilters = getActiveFilters();
  if (
    !isEmpty(filterBoxFilters) &&
    !excludedParams.includes(URL_PARAMS.preselectFilters.name)
  )
    urlParams.append(
      URL_PARAMS.preselectFilters.name,
      JSON.stringify(serializeActiveFilterValues(getActiveFilters())),
    );
  return getUrlParamEntries(urlParams);
}

function getDashboardUrlParams(): UrlParamEntries {
  const urlParams = getUrlParams(RESERVED_DASHBOARD_URL_PARAMS);
  const filterBoxFilters = getActiveFilters();
  if (!isEmpty(filterBoxFilters))
    urlParams.append(
      URL_PARAMS.preselectFilters.name,
      JSON.stringify(serializeActiveFilterValues(getActiveFilters())),
    );
  return getUrlParamEntries(urlParams);
}

function getPermalink(endpoint: string, jsonPayload: JsonObject) {
  return SupersetClient.post({
    endpoint,
    jsonPayload,
  }).then(result => result.json.url as string);
}

export function getChartPermalink(
  formData: Pick<QueryFormData, 'datasource'>,
  excludedUrlParams?: string[],
) {
  return getPermalink('/api/v1/explore/permalink', {
    formData,
    urlParams: getChartUrlParams(excludedUrlParams),
  });
}

export function getDashboardPermalink({
  dashboardId,
  dataMask,
  activeTabs,
  anchor, // the anchor part of the link which corresponds to the tab/chart id
}: {
  dashboardId: string | number;
  /**
   * Current applied data masks (for native filters).
   */
  dataMask: JsonObject;
  /**
   * Current active tabs in the dashboard.
   */
  activeTabs: string[];
  /**
   * The "anchor" component for the permalink. It will be scrolled into view
   * and highlighted upon page load.
   */
  anchor?: string;
}) {
  // only encode filter box state if non-empty
  return getPermalink(`/api/v1/dashboard/${dashboardId}/permalink`, {
    urlParams: getDashboardUrlParams(),
    dataMask,
    activeTabs,
    anchor,
  });
}

const externalUrlRegex =
  /^([^:/?#]+:)?(?:(\/\/)?([^/?#]*))?([^?#]+)?(\?[^#]*)?(#.*)?/;

// group 1 matches protocol
// group 2 matches '//'
// group 3 matches hostname
export function isUrlExternal(url: string) {
  const match = url.match(externalUrlRegex) || [];
  return (
    (typeof match[1] === 'string' && match[1].length > 0) ||
    match[2] === '//' ||
    (typeof match[3] === 'string' && match[3].length > 0)
  );
}

export function parseUrl(url: string) {
  const match = url.match(externalUrlRegex) || [];
  // if url is external but start with protocol or '//',
  // it can't be used correctly with <a> element
  // in such case, add '//' prefix
  if (isUrlExternal(url) && !isDefined(match[1]) && !url.startsWith('//')) {
    return `//${url}`;
  }
  return url;
}

相关信息

superset 源码目录

相关文章

superset DebouncedMessageQueue 源码

superset cacheWrapper 源码

superset colorUtils 源码

superset common 源码

superset copy 源码

superset datasourceUtils 源码

superset dates 源码

superset downloadAsImage 源码

superset errorMessages 源码

superset export 源码

0  赞