lodash#sortBy TypeScript Examples

The following examples show how to use lodash#sortBy. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: utils.ts    From yforms with MIT License 7 votes vote down vote up
export function submitFormatValues(
  values: KeyValue,
  formatFieldsValue?: FormatFieldsValue[],
): KeyValue {
  const _values = mergeWithDom({}, values);
  const list: FormatFieldsValue[] = sortBy(formatFieldsValue, (item) => {
    if (!item) return;
    if (isArray(item.name)) {
      return -item.name.length;
    }
    return -`${item.name}`.length;
  }).filter((x) => x);
  forEach(list, (item) => {
    const { name, format } = item;
    if (name && format) {
      const parentValue = getParentNameData(values, name);
      // 如果上一级是 undefined,则不处理该字段。(List add 会生成空对象)
      if (parentValue === undefined) return;
      try {
        set(_values, name, format(get(values, name), parentValue, values));
      } catch (error) {
        // 如果 format 代码报错这里抛出异常
        // eslint-disable-next-line no-console
        console.error(error);
        warning(false, error);
      }
    }
  });
  return _values;
}
Example #2
Source File: snapshots-utils.ts    From ui5-language-assistant with Apache License 2.0 7 votes vote down vote up
export function computeXMLWithMarkedRanges(
  testDir: string,
  ranges: Range[]
): string {
  const xmlTextSnippet = readInputXMLSnippet(testDir);
  const xmlTextDoc = TextDocument.create(
    `file://${getInputXMLSnippetPath(testDir)}`,
    "xml",
    0,
    xmlTextSnippet
  );

  // this assumes no overlapping ranges
  const issueRangesByOffsetAscending = sortBy(
    ranges,
    // sort by line first and column second
    (_) => xmlTextDoc.offsetAt(_.start)
  );

  // Changes are made from the "end" of the text to the start to ensure correctness
  let xmlSnippetWithRangeMarkers = xmlTextSnippet;
  forEachRight(issueRangesByOffsetAscending, (_) => {
    const startOffset = xmlTextDoc.offsetAt(_.start);
    const endOffset = xmlTextDoc.offsetAt(_.end);
    const prefix = xmlSnippetWithRangeMarkers.substring(0, startOffset);
    const toBeMarked = xmlSnippetWithRangeMarkers.substring(
      startOffset,
      endOffset
    );
    const suffix = xmlSnippetWithRangeMarkers.substring(endOffset);
    xmlSnippetWithRangeMarkers = prefix + "?" + toBeMarked + "?" + suffix;
  });

  return xmlSnippetWithRangeMarkers;
}
Example #3
Source File: utils.tsx    From erda-ui with GNU Affero General Public License v3.0 7 votes vote down vote up
getTableList = (data: IPerm, scope: string, filterKey: string) => {
  let list = [] as any[];
  const countData = (curData: any, key = scope, depth = 0, prevData = {}) => {
    if (!curData) return;
    if (curData.role) {
      list.push({ ...prevData, action: { ...curData, key } });
    } else {
      const { name, ...rest } = curData;
      map(rest, (item, cKey) => {
        const curPrevData = { ...prevData, [`depth${depth}`]: { key, name } };
        countData(item, cKey, depth + 1, curPrevData);
      });
    }
  };
  countData(data);

  if (filterKey) {
    list = filter(list, (l) => some(l, (item) => item.key.includes(filterKey) || item.name.includes(filterKey)));
  }

  const maxDeepthObj = maxBy(list, (item) => Object.keys(item).length);
  const tableList = [] as any[];
  map(list, (item) => {
    const itemData = { ...item };
    map(maxDeepthObj, (val, key) => {
      if (!itemData[key]) {
        itemData[key] = {};
      }
    });
    const sortKeys = sortBy(Object.keys(itemData), (k) => (k.startsWith('depth') ? Number(k.slice(5)) : 1000));
    itemData.actionKey = map(sortKeys, (k) => itemData[k].key || '__').join('');
    tableList.push(itemData);
  });
  return map(
    sortBy(tableList, (item) => item.actionKey),
    ({ actionKey, ...rest }) => rest,
  );
}
Example #4
Source File: boxFetcher.ts    From nautilus-wallet with MIT License 6 votes vote down vote up
export async function fetchBoxes(
  walletId: number,
  options: { tokenId?: string; useAllAddressesAsFallback: boolean; includeUnconfirmed: boolean } = {
    tokenId: ERG_TOKEN_ID,
    useAllAddressesAsFallback: true,
    includeUnconfirmed: true
  }
): Promise<ErgoBox[]> {
  const addresses = await assestsDbService.getAddressesByTokenId(
    walletId,
    options.tokenId ?? ERG_TOKEN_ID
  );
  const pendingBoxes = options.includeUnconfirmed
    ? await utxosDbService.getByWalletId(walletId)
    : [];

  let boxes = await fetchBoxesFromExplorer(addresses);

  if (
    options.useAllAddressesAsFallback &&
    isEmpty(boxes) &&
    !find(pendingBoxes, (b) => !b.locked && b.content)
  ) {
    boxes = await fetchBoxesFromExplorer(difference(await getAllAddresses(walletId), addresses));
  }
  if (!isEmpty(pendingBoxes)) {
    const lockedIds = pendingBoxes.filter((x) => x.locked).map((x) => x.id);
    const unconfirmed = pendingBoxes.filter((b) => !b.locked && b.content).map((b) => b.content!);

    if (!isEmpty(lockedIds)) {
      boxes = boxes.filter((b) => !lockedIds.includes(b.boxId));
    }
    if (!isEmpty(unconfirmed)) {
      boxes = unionBy(boxes, unconfirmed, (b) => b.boxId);
    }
  }

  return sortBy(boxes, (x) => x.creationHeight).reverse();
}
Example #5
Source File: generate.ts    From earl with MIT License 6 votes vote down vote up
function sortBySignatures(xs: MethodDocumentation[]) {
  const sorted = sortBy(xs, (d) => d.signature)

  // functions are lifted to the top
  const functions = sorted.filter((d) => d.signature.startsWith('function '))
  const others = sorted.filter((d) => !d.signature.startsWith('function '))

  return [...functions, ...others]
}
Example #6
Source File: reorderMountPoints.ts    From next-basics with GNU General Public License v3.0 6 votes vote down vote up
export function reorderMountPoints({
  draggingMountPoint,
  droppingMountPoint,
  siblingGroups,
}: ReorderMountPointsParams): Pick<
  EventDetailOfNodeReorder,
  "nodeUids" | "nodeIds"
> {
  const mountPointList = siblingGroups.map((group) => group.mountPoint);
  const draggingIndex = mountPointList.indexOf(draggingMountPoint);
  const droppingIndex = mountPointList.indexOf(droppingMountPoint);
  mountPointList.splice(draggingIndex, 1);
  mountPointList.splice(droppingIndex, 0, draggingMountPoint);
  const nodeUids: number[] = [];
  const nodeIds: string[] = [];
  sortBy(siblingGroups, (group) => mountPointList.indexOf(group.mountPoint))
    .flatMap((group) => group.childNodes)
    .forEach((node) => {
      nodeUids.push(node.$$uid);
      nodeIds.push(node.id);
    });
  return {
    nodeUids,
    nodeIds,
  };
}
Example #7
Source File: Kernel.ts    From next-core with GNU General Public License v3.0 6 votes vote down vote up
async getRelatedAppsAsync(appId: string): Promise<RelatedApp[]> {
    if (!appId) {
      return [];
    }
    const allRelatedApps = await this.allRelatedAppsPromise;
    const thisApp = allRelatedApps.find((item) => item.microAppId === appId);
    if (!thisApp) {
      return [];
    }
    return sortBy(
      allRelatedApps.filter((item) => item.objectId === thisApp.objectId),
      ["order"]
    );
  }
Example #8
Source File: yml-flow-util.ts    From erda-ui with GNU Affero General Public License v3.0 6 votes vote down vote up
sortByLineType = (list: any[]) => {
  return sortBy(list, (item: any) => item.type !== 'polyline');
}
Example #9
Source File: BuilderDataManager.ts    From next-core with GNU General Public License v3.0 6 votes vote down vote up
/**
   * Move mount-point up or down.
   */
  moveMountPoint(
    { $$uid: parentUid }: BuilderRuntimeNode,
    mountPoint: string,
    direction: "up" | "down"
  ): void {
    const { relatedEdges, mountPoints } = getRelatedEdgesAndMountPoint(
      this.data.edges,
      parentUid
    );
    const index = mountPoints.indexOf(mountPoint);
    const orderedMountPoints = moveItemInList(mountPoints, index, direction);
    if (!orderedMountPoints) {
      return;
    }
    const orderedEdges = sortBy(
      relatedEdges,
      (edge) => orderedMountPoints.indexOf(edge.mountPoint),
      "sort"
    );
    this.reorder(parentUid, orderedEdges);
  }
Example #10
Source File: index.tsx    From admin with MIT License 6 votes vote down vote up
/*
 * Render a summary of groups to which the customer belongs
 */
function CustomersGroupsSummary(props: P) {
  const groups = sortBy(props.groups, "name")
  if (!groups.length) {
    return null
  }

  const left = groups.length - 1
  const leadName = groups[0].name
  const allGroups = groups.map((g) => g.name).join(", ")

  return (
    <div title={allGroups} className="text-small">
      <span>{leadName}</span>
      {!!left && <span className="text-grey-40"> + {left} more</span>}
    </div>
  )
}
Example #11
Source File: classifierSearch.ts    From condo with MIT License 6 votes vote down vote up
public async init (): Promise<void> {
        if (this.rules && this.rules.length) {
            return
        }
        let skip = 0
        let maxCount = 500
        let newchunk = []
        let allRules = []
        do {
            newchunk = await loadClassifierRules(this.client, { first: 200, skip: skip, sortBy: 'id_ASC' })
            allRules = allRules.concat(newchunk)
            skip += newchunk.length
        } while (--maxCount > 0 && newchunk.length)
        this.rules = allRules
        this.place = this.rulesToOptions(allRules, 'place')
        this.category = this.rulesToOptions(allRules, 'category')
        this.problem = this.rulesToOptions(allRules, 'problem')
    }
Example #12
Source File: Linear.ts    From HeartBeat with MIT License 6 votes vote down vote up
private static async putStatusChangeEventsIntoAnArray(
    cardHistory: IssueHistory[]
  ): Promise<StatusChangedArrayItem[]> {
    const sortedActivities = sortBy(cardHistory, "createdAt");

    const sortedAndStateRelatedHistory = sortedActivities.filter(
      (item) => item.fromState || item.toState
    );

    const firstActivity = sortedActivities[0];

    if (sortedAndStateRelatedHistory.length === 0) {
      return [
        {
          timestamp: firstActivity.createdAt.getTime(),
          status: (await (await firstActivity.issue)?.state)?.name || "",
        },
      ];
    }

    const stateChanged = await Promise.all(
      sortedAndStateRelatedHistory.map(async (activity) => ({
        timestamp: activity.createdAt.getTime(),
        status: (await activity.toState)?.name || "",
      }))
    );

    return [
      {
        timestamp: firstActivity.createdAt.getTime(),
        status: (await sortedAndStateRelatedHistory[0].fromState)?.name || "",
      },
      ...stateChanged,
    ];
  }
Example #13
Source File: strategyParams.ts    From yearn-watch-legacy with GNU Affero General Public License v3.0 6 votes vote down vote up
getStrategyAllocation = (vault: Vault): BarChartData[] => {
    const strategiesAllocations = vault.strategies.map(({ name, params }) => {
        return {
            name,
            y: Number(
                (parseInt(params.debtRatio.toString(), 10) / 100).toFixed(2)
            ),
        };
    });

    const debtUsage = parseInt(vault.debtUsage) / 100;
    if (debtUsage < 100) {
        strategiesAllocations.push({
            name: 'Not Allocated',
            y: Number((100 - debtUsage).toFixed(2)),
        });
    }

    return sortBy(strategiesAllocations, ['y']) as BarChartData[];
}
Example #14
Source File: index.ts    From free-swagger with MIT License 6 votes vote down vote up
createTagsByPaths = (
  paths: OpenAPIV2.PathsObject
): OpenAPIV2.TagObject[] =>
  // @ts-ignore
  sortBy(
    uniq(
      flattenDeep(
        Object.values(paths).map((item: OpenAPIV2.PathItemObject) =>
          Object.values(item).map(
            (item: OpenAPIV2.OperationObject) => item.tags
          )
        )
      ).filter(Boolean)
    )
  ).map((item) => ({ name: item }))
Example #15
Source File: sitesListSlice.ts    From aqualink-app with MIT License 6 votes vote down vote up
sitesRequest = createAsyncThunk<
  SitesRequestData,
  undefined,
  CreateAsyncThunkTypes
>(
  "sitesList/request",
  async (arg, { rejectWithValue, getState }) => {
    try {
      const { data } = await siteServices.getSites();
      const {
        homepage: { withSpotterOnly },
      } = getState();
      const sortedData = sortBy(data, "name");
      const transformedData = sortedData.map((item) => ({
        ...item,
        collectionData: mapCollectionData(item.collectionData || {}),
      }));
      return {
        list: transformedData,
        sitesToDisplay: withSpotterOnly
          ? transformedData.filter(hasDeployedSpotter)
          : transformedData,
      };
    } catch (err) {
      return rejectWithValue(getAxiosErrorMessage(err));
    }
  },
  {
    condition(arg: undefined, { getState }) {
      const {
        sitesList: { list },
      } = getState();
      return !list;
    },
  }
)
Example #16
Source File: turn.ts    From fishbowl with MIT License 6 votes vote down vote up
export function nextPlayerForNextTeam(
  activePlayer: CurrentGameSubscription["games"][0]["players"][0] | null,
  turns: CurrentGameSubscription["games"][0]["turns"],
  players: CurrentGameSubscription["games"][0]["players"]
) {
  if (!activePlayer) {
    return sortBy(players, ["team_sequence"])[0]
  }
  const lastTeamToPlay = activePlayer.team
  const nextTeamToPlay = lastTeamToPlay === Team.Blue ? Team.Red : Team.Blue
  const nextTeamToPlayPlayers = filter(
    players,
    (player) => player.team === nextTeamToPlay
  )
  const lastTurnFromNextTeamToPlay = findLast(turns, (turn) =>
    nextTeamToPlayPlayers.map((player) => player.id).includes(turn.player_id)
  )
  const lastPlayerFromNextTeamToPlay = lastTurnFromNextTeamToPlay
    ? players.find(
        (player) => player.id === lastTurnFromNextTeamToPlay.player_id
      )
    : null

  const nextTeamPlayersSortedBySequence = sortBy(nextTeamToPlayPlayers, [
    "team_sequence",
  ])
  const nextPlayerFromNextTeamToPlay = lastPlayerFromNextTeamToPlay
    ? nextTeamPlayersSortedBySequence[
        ((lastPlayerFromNextTeamToPlay.team_sequence || 0) + 1) %
          nextTeamToPlayPlayers.length
      ]
    : nextTeamPlayersSortedBySequence[0]

  return nextPlayerFromNextTeamToPlay
}
Example #17
Source File: cardinality-of-aggregation.ts    From ui5-language-assistant with Apache License 2.0 6 votes vote down vote up
function getFirstSubElementAtSameDepth(
  allSubElementsAtSameDepth: XMLElement[]
): XMLElement {
  const sortedSubElementsAtSameDepth = sortBy(allSubElementsAtSameDepth, (_) =>
    getSubElementPosition(_)
  );

  return sortedSubElementsAtSameDepth[0];
}
Example #18
Source File: localStoragePreferences.ts    From hub with Apache License 2.0 6 votes vote down vote up
applyMigrations = (lsActual: PreferencesList): PreferencesList => {
  let lsUpdated: PreferencesList = { ...lsActual };
  if (isEmpty(lsUpdated)) {
    return { guest: DEFAULT_PREFS };
  }
  const sortedMigrations: Migration[] = sortBy(migrations, 'key');
  let migrationsToApply = [...sortedMigrations];
  const migrationApplied = window.localStorage.getItem(APPLIED_MIGRATION);
  const lastMigration = getLastMigrationNumber();

  if (migrationApplied) {
    // If latest migration has been applied, we don't do anything
    if (lastMigration === parseInt(migrationApplied)) {
      migrationsToApply = [];
    } else {
      // Migrations newest than current one are applied to prefs
      migrationsToApply = sortedMigrations.filter((migration: Migration) => migration.key > parseInt(migrationApplied));
    }
  }

  migrationsToApply.forEach((migration: Migration, index: number) => {
    lsUpdated = migration.method(lsUpdated);
  });

  // Saved last migration
  try {
    window.localStorage.setItem(APPLIED_MIGRATION, lastMigration.toString());
  } catch {
    // Incognite mode
  }
  return lsUpdated;
}
Example #19
Source File: liveData.ts    From aqualink-app with MIT License 6 votes vote down vote up
getSstAnomaly = (
  historicalMonthlyMean: HistoricalMonthlyMean[],
  satelliteTemperature?: ValueWithTimestamp,
) => {
  if (historicalMonthlyMean.length < 12 || !satelliteTemperature?.value) {
    return undefined;
  }

  const orderedMontlyMax = sortBy(historicalMonthlyMean, 'month');
  const now = moment().startOf('day');

  // The date of the previous value. Subtract 15 days from the current date
  // and see in which month the result falls. The date we are looking for is
  // the 15th day of this month.
  const previousDate = now
    .clone()
    .subtract(15, 'days')
    .set('date', 15)
    .startOf('day');

  // The date of the next value. It must fall on the next month of the previous
  // value.
  const nextDate = previousDate.clone().add(1, 'month');

  // We can index `orderedMontlyMax` with `moment.get('month')` since it returns
  // a value between 0 and 11, with 0 corresponding to January and 11 corresponding to December
  const previousValue = orderedMontlyMax[previousDate.get('month')].temperature;
  const previousDistance = now.diff(previousDate, 'days');
  const nextValue = orderedMontlyMax[nextDate.get('month')].temperature;
  const nextDistance = nextDate.diff(now, 'days');
  const deltaDays = previousDistance + nextDistance;

  const interpolated =
    previousValue * (1 - previousDistance / deltaDays) +
    nextValue * (1 - nextDistance / deltaDays);

  return satelliteTemperature.value - interpolated;
}
Example #20
Source File: stackArea.ts    From fe-v5 with Apache License 2.0 5 votes vote down vote up
draw(xScales: XScales, yScales: YScales) {
    const {
      series,
      chart: { colors },
      xkey,
      ykey,
      timestamp,
      fillNull,
      notDisplayedSeries,
    } = this.options;
    const { ctx } = this;
    const line = d3
      .area()
      .x((d: SerieDataItem) => {
        const xVal = timestamp === 'X' ? d[xkey] * 1000 : d[xkey];
        const x = xScales(new Date(xVal));
        return x;
      })
      .y0((d: SerieDataItem) => {
        const val = d[2];
        if (typeof val === 'number') {
          return yScales(val);
        } else if (typeof fillNull === 'number') {
          return yScales(fillNull);
        }
        return undefined;
      })
      .y1((d: SerieDataItem) => {
        const val = d[1];
        if (typeof val === 'number') {
          return yScales(val);
        } else if (typeof fillNull === 'number') {
          return yScales(fillNull);
        }
        return undefined;
      })
      .defined((d: SerieDataItem) => {
        const val = d[ykey];
        return typeof val === 'number' || typeof fillNull === 'number';
      })
      .context(ctx);
    sortBy(series, 'zIndex')
      .reverse()
      .forEach((serie: Serie, i: number) => {
        if (serie.visible === false) return;
        if (notDisplayedSeries.indexOf(serie.name) > -1) return;

        const color = serie.color || getColor(colors, i);

        serie.color = color;
        ctx.beginPath();

        ctx.lineTo(0, 0); // TODO: fix don't draw the first single point

        line(serie.data || []);
        ctx.lineJoin = 'round';
        ctx.lineWidth = this.options.line.width;
        ctx.strokeStyle = color;
        ctx.fillStyle = color + '50';
        ctx.lineCap = 'round';
        ctx.stroke();
        ctx.fill();
        ctx.closePath();
      });
  }
Example #21
Source File: utils.tsx    From erda-ui with GNU Affero General Public License v3.0 5 votes vote down vote up
getRender = (val: Obj, record: Obj, extra?: Extra) => {
  const { type, data, key } = val || {};
  let Comp: React.ReactNode = null;
  const { userMap = {} } = extra || {};

  if (!data) {
    return '-';
  }

  switch (type) {
    case 'multiple':
      {
        const { props } = extra || ({} as Extra);
        const render = get(props, `columnsRender.${key}`) || defaultMultiple;

        const CompMap = {};
        map(data, (v, k) => {
          CompMap[k] = getRender(v, record, extra);
        });
        Comp = <div>{render(val, record, CompMap)}</div>;
      }
      break;
    case 'icon':
      {
        const { type: iconType, url } = data;
        if (url) {
          Comp = <img src={url} />;
        } else if (iconType) {
          Comp = <ErdaIcon isConfigPageIcon size={16} type={iconType} />;
        } else {
          Comp = '';
        }
      }
      break;
    case 'duration':
      {
        const { value, tip } = data;
        if (!value) {
          Comp = '0s';
        } else if (value === -1) {
          Comp = '-';
        } else {
          const _duration = moment.duration(value, 'seconds');
          const duration = [
            { value: _duration.years(), unit: 'y' },
            { value: _duration.months(), unit: 'm' },
            { value: _duration.days(), unit: 'd' },
            { value: _duration.hours(), unit: 'h' },
            { value: _duration.minutes(), unit: 'min' },
            { value: _duration.seconds(), unit: 's' },
          ];
          const durationArr = duration.filter((item) => item.value) || [];
          const durationStr = durationArr.map((item) => `${item.value}${item.unit}`).join('');
          Comp = tip ? <Tooltip title={tip}>{durationStr}</Tooltip> : durationStr;
        }
      }
      break;
    case 'progressBar':
      {
        const { barCompletedNum, barTotalNum, barPercent, text, status, tip } = data;
        const value = barPercent || (barCompletedNum / barTotalNum) * 100 || 0;

        const content = (
          <>
            <Progress
              percent={value}
              type="circle"
              width={20}
              strokeWidth={18}
              format={() => null}
              strokeColor={statusColorMap[status]}
            />
            <span className="text-black-8  ml-2">{text}</span>
          </>
        );
        Comp = tip ? <Tooltip title={tip}>{content}</Tooltip> : content;
      }
      break;
    case 'user':
      const curUsers = [];
      if (isArray(data.id)) {
        data.id.forEach((vItem: any) => {
          curUsers.push(userMap[vItem] || {});
        });
      } else {
        curUsers.push(userMap[data.id] || {});
      }
      if (data.showIcon === false) {
        Comp = map(curUsers, (item) => item.nick || item.name || item.id || i18n.t('common:None')).join(', ');
      } else {
        Comp = (
          <div>
            {map(curUsers, (cU, idx) => {
              return (
                <span key={idx}>
                  {data.showIcon === false ? null : (
                    <Avatar src={cU.avatar} size="small">
                      {cU.nick ? getAvatarChars(cU.nick) : i18n.t('None')}
                    </Avatar>
                  )}
                  <span className="ml-0.5 mr-1" title={cU.name}>
                    {cU.nick || cU.name || data.value || i18n.t('common:None')}
                  </span>
                </span>
              );
            })}
          </div>
        );
      }
      break;
    case 'dropDownMenu':
      // {
      // const {menus, operations} = data || {};
      // Comp = <DropdownSelectNew options={} />
      // }
      break;
    case 'text':
      if (typeof data === 'string') {
        Comp = data;
      } else if (typeof data === 'object') {
        const { text, enableCopy, status, showDot = false, tip, onlyText = false } = data;
        let value = status ? <Badge text={text} status={status} showDot={showDot} onlyText={onlyText} /> : text;

        if (tip) {
          value = (
            <Tooltip overlayClassName="whitespace-pre" title={tip} className="truncate w-full inline-block">
              {value}
            </Tooltip>
          );
        } else {
          value = <Ellipsis title={value} />;
        }

        Comp = enableCopy ? (
          <span className="flex group">
            <span className="ant-table-cell-ellipsis group-hover:text-purple-deep" title={text}>
              {text}
            </span>
            <Copy>
              <ErdaIcon
                type="fz1"
                size={12}
                data-clipboard-text={text}
                onClick={(e) => e.stopPropagation()}
                className="ml-1 cursor-copy text-desc opacity-0 group-hover:text-purple-deep group-hover:opacity-100"
              />
            </Copy>
          </span>
        ) : (
          value
        );
      }
      break;
    case 'labels':
      {
        const { labels, showCount } = data;
        // TODO showCount should be calculated based on the container width
        Comp = (
          <TagsRow
            labels={labels.map((item: { id: string; title?: string; color?: string; group?: string }) => ({
              ...item,
              label: item.title || item.id,
            }))}
            showCount={showCount ?? 2}
          />
        );
      }
      break;
    case 'moreOperations':
      {
        const { ops } = data;

        const getIcon = (icon: { type?: string; url?: string }) => {
          if (icon.type) {
            return <ErdaIcon type={icon.type} color="currentColor" className="mr-1 text-white-6" />;
          }
          if (icon.url) {
            return <img src={icon.url} />;
          }
          return null;
        };

        const getTableOperationItem = (op: CP_COMMON.Operation, key: string, record: Obj) => {
          const { confirm, disabled, disabledTip, text, icon, operations } = op;
          const { click } = operations || {};
          const { serverData } = click || {};
          if (disabled === true) {
            // 无权限操作
            return (
              <Menu.Item key={key} className="p-0">
                <WithAuth noAuthTip={disabledTip} key={key} pass={false}>
                  <span className="table-operations-btn px-4 py-1 block flex-h-center">
                    {icon ? getIcon(icon) : null}
                    {text}
                  </span>
                </WithAuth>
              </Menu.Item>
            );
          } else if (confirm) {
            // 需要确认的操作
            return (
              <Menu.Item key={key} className="p-0 bg-transparent">
                <Popconfirm
                  title={confirm}
                  onConfirm={(e) => {
                    e && e.stopPropagation();
                    extra?.execOperation({
                      key: 'click',
                      ...click,
                      clientData: {
                        dataRef: op,
                        parentDataRef: record,
                      },
                      serverData,
                    });
                    const customFunc = get(extra, `customOp.operations.${key}`);
                    if (customFunc) {
                      customFunc(op, record);
                    }
                  }}
                  key={key}
                  onCancel={(e: any) => e && e.stopPropagation()}
                  zIndex={1100}
                >
                  <span
                    className="table-operations-btn px-4 py-1 block flex-h-center text-white-9"
                    onClick={(e: any) => e.stopPropagation()}
                  >
                    {icon ? getIcon(icon) : null}
                    {text}
                  </span>
                </Popconfirm>
              </Menu.Item>
            );
          } else {
            // 普通的操作
            return (
              <Menu.Item key={key} className="p-0">
                <span
                  className="table-operations-btn px-4 py-1 block flex-h-center text-white-9"
                  key={key}
                  onClick={(e: any) => {
                    e.stopPropagation();
                    extra?.execOperation({
                      key: 'click',
                      ...click,
                      clientData: {
                        dataRef: op,
                        parentDataRef: record,
                      },
                      serverData,
                    });
                    const customFunc = get(extra, `customOp.operations.${key}`);
                    if (customFunc) {
                      customFunc(op, record);
                    }
                  }}
                >
                  {icon ? getIcon(icon) : null}
                  {text}
                </span>
              </Menu.Item>
            );
          }
        };

        const operationList = [] as any[];
        if (ops) {
          // 根据配置的operations展示
          const operations = sortBy(
            filter(map(ops) || [], (item: CP_COMMON.Operation) => item.show !== false),
            'showIndex',
          );

          map(operations, (item: CP_COMMON.Operation) => {
            if (item) {
              operationList.push(getTableOperationItem(item, item.id, record));
            }
          });
        }

        if (!operationList.length) {
          Comp = null;
        } else {
          Comp = (
            <div className="table-operations">
              <Dropdown
                overlay={
                  <Menu theme="dark" style={{ minWidth: 160, padding: '8px 0' }}>
                    {operationList}
                  </Menu>
                }
                align={{ offset: [0, 5] }}
                trigger={['click']}
                overlayStyle={{ zIndex: 1040 }}
              >
                <ErdaIcon
                  type="more"
                  className="cursor-pointer p-1 bg-hover rounded-sm"
                  onClick={(e) => e.stopPropagation()}
                />
              </Dropdown>
            </div>
          );
        }
      }
      break;
    default:
      Comp = (typeof data === 'string' ? data : data?.text) || '-';
      break;
  }
  return Comp;
}
Example #22
Source File: selectedSiteSlice.ts    From aqualink-app with MIT License 5 votes vote down vote up
siteRequest = createAsyncThunk<
  SelectedSiteState["details"],
  string,
  CreateAsyncThunkTypes
>(
  "selectedSite/request",
  async (id: string, { rejectWithValue }) => {
    try {
      const { data } = await siteServices.getSite(id);
      const { data: dailyData } = await siteServices.getSiteDailyData(id);
      const { data: surveyPoints } = await siteServices.getSiteSurveyPoints(id);

      return {
        ...data,
        dailyData,
        historicalMonthlyMean: sortBy(
          data.historicalMonthlyMean,
          (item) => item.month
        ).map((item) => ({
          id: item.id,
          month: item.month,
          temperature: item.temperature,
        })),
        surveyPoints: surveyPoints.map((point) => ({
          id: point.id,
          name: point.name,
          polygon: point.polygon,
        })),
      };
    } catch (err) {
      return rejectWithValue(getAxiosErrorMessage(err));
    }
  },
  {
    condition(id: string, { getState }) {
      const {
        selectedSite: { details },
      } = getState();
      return `${details?.id}` !== id;
    },
  }
)
Example #23
Source File: label-selector.tsx    From erda-ui with GNU Affero General Public License v3.0 5 votes vote down vote up
LabelSelector = React.forwardRef(({ labelOptions, value = [], onChange }: IProps, ref) => {
  const nodeLabels = clusterDashboardStore.useStore((s) => s.nodeLabels);
  const { getNodeLabels } = clusterDashboardStore.effects;
  const [labelList, setLabelList] = React.useState([] as any[]);

  React.useEffect(() => {
    labelOptions === undefined && getNodeLabels(); // 无options,则请求
  }, [getNodeLabels, labelOptions]);

  React.useEffect(() => {
    if (labelOptions === undefined) {
      setLabelList(nodeLabels.filter((l) => !l.isPrefix).map((l) => ({ ...l, value: l.label, name: l.label })));
    } else {
      setLabelList(labelOptions);
    }
  }, [labelOptions, nodeLabels]);

  // label 以group分组显示
  const gorupLabelObj = groupBy(labelList, 'group');
  let groupList = [] as any[];
  map(gorupLabelObj, (item, key) => {
    groupList.push({
      name: get(item, '[0].groupName', key),
      groupLevel: get(item, '[0].groupLevel', 100),
      children: [...item],
    });
  });
  groupList = sortBy(groupList, 'groupLevel');

  const handleChange = (item: string, isActive: boolean) => {
    const newList = isActive ? value.filter((label) => label !== item) : value.concat(item);
    onChange && onChange(newList);
  };

  return (
    <div ref={ref} className="label-selector-container">
      {map(groupList, (item: any) => {
        const { name, children } = item;
        return (
          <div className="label-group" key={name}>
            <span className="label-group-name">{firstCharToUpper(name)}: </span>
            {map(children, (cItem: any) => {
              const isActive = value.includes(cItem.value);
              return (
                <span
                  key={cItem.value}
                  className={`cursor-pointer ${isActive ? 'tag-primary' : 'tag-default'}`}
                  onClick={() => handleChange(cItem.value, isActive)}
                >
                  {cItem.desc ? <Tooltip title={cItem.desc}>{cItem.name}</Tooltip> : cItem.name}
                </span>
              );
            })}
          </div>
        );
      })}
    </div>
  );
})
Example #24
Source File: download-many-auto-extractors.spec.ts    From js-client with MIT License 5 votes vote down vote up
describe('downloadManyAutoExtractors()', () => {
	const createOneAutoExtractor = makeCreateOneAutoExtractor(TEST_BASE_API_CONTEXT);
	const deleteOneAutoExtractor = makeDeleteOneAutoExtractor(TEST_BASE_API_CONTEXT);
	const getAllAutoExtractors = makeGetAllAutoExtractors(TEST_BASE_API_CONTEXT);
	const downloadManyAutoExtractors = makeDownloadManyAutoExtractors(TEST_BASE_API_CONTEXT);

	let createdAutoExtractors: Array<AutoExtractor>;

	beforeEach(async () => {
		jasmine.addMatchers(myCustomMatchers);

		// Delete all auto extractors
		const currentAutoExtractors = await getAllAutoExtractors();
		const currentAutoExtractorIDs = currentAutoExtractors.map(m => m.id);
		const deletePromises = currentAutoExtractorIDs.map(autoExtractorID => deleteOneAutoExtractor(autoExtractorID));
		await Promise.all(deletePromises);

		// Create three auto extractors
		const creatableAutoExtractors: Array<CreatableAutoExtractor> = [
			{
				name: 'AE1 name',
				description: 'AE1 description',

				tag: 'netflow',
				module: 'csv',
				parameters: 'a b c',
			},
			{
				name: 'AE2 name',
				description: 'AE2 description',

				tag: 'gravwell',
				module: 'fields',
				parameters: '1 2 3',
			},
			{
				name: 'AE3 name',
				description: 'AE3 description',

				tag: 'test',
				module: 'regex',
				parameters: 'abc',
			},
		];
		const createPromises = creatableAutoExtractors.map(creatable => createOneAutoExtractor(creatable));
		createdAutoExtractors = await Promise.all(createPromises);
	});

	it(
		'Should download the specified auto extractors',
		integrationTest(async () => {
			const sortByName = <T extends { name: string }>(arr: Array<T>) => sortBy(arr, ae => ae.name);
			const expectedAutoExtractors = sortByName(createdAutoExtractors.slice(0, 2));
			const ids = expectedAutoExtractors.map(ae => ae.id);

			const autoExtractorContents = await downloadManyAutoExtractors({ ids });
			const parsedAutoExtractorContents = sortByName(parseAutoExtractorFile(autoExtractorContents));
			expect(expectedAutoExtractors).toPartiallyEqual(parsedAutoExtractorContents);
		}),
	);
});
Example #25
Source File: line.ts    From fe-v5 with Apache License 2.0 5 votes vote down vote up
draw(xScales: XScales, yScales: YScales) {
    const {
      series,
      chart: { colors },
      xkey,
      ykey,
      timestamp,
      fillNull,
      notDisplayedSeries,
    } = this.options;
    const { ctx } = this;
    const line = d3
      .line()
      .x((d: SerieDataItem) => {
        const xVal = timestamp === 'X' ? d[xkey] * 1000 : d[xkey];
        const x = xScales(new Date(xVal));
        return x;
      })
      .y((d: SerieDataItem) => {
        const val = d[ykey];
        if (typeof val === 'number') {
          return yScales(val);
        } else if (typeof fillNull === 'number') {
          return yScales(fillNull);
        }
        return undefined;
      })
      .defined((d: SerieDataItem) => {
        const val = d[ykey];
        return typeof val === 'number' || typeof fillNull === 'number';
      })
      .context(ctx);
    sortBy(series, 'zIndex').forEach((serie: Serie, i: number) => {
      if (serie.visible === false) return;
      if (notDisplayedSeries.indexOf(serie.name) > -1) return;

      const color = serie.color || getColor(colors, i);

      serie.color = color;
      ctx.beginPath();

      ctx.lineTo(0, 0); // TODO: fix don't draw the first single point

      line(serie.data || []);
      ctx.lineJoin = 'round';
      ctx.lineWidth = this.options.line.width;
      ctx.strokeStyle = color;
      ctx.lineCap = 'round';
      ctx.setLineDash(serie.lineDash || []);
      ctx.stroke();
      ctx.closePath();
    });
  }
Example #26
Source File: CalendarEventPopoverContent.tsx    From backstage with Apache License 2.0 5 votes vote down vote up
CalendarEventPopoverContent = ({
  event,
}: CalendarEventPopoverProps) => {
  const classes = useStyles({ event });
  const analytics = useAnalytics();
  const zoomLink = getZoomLink(event);

  return (
    <Box display="flex" flexDirection="column" width={400} p={2}>
      <Box display="flex" alignItems="center">
        <Box flex={1}>
          <Typography variant="h6">{event.summary}</Typography>
          <Typography variant="subtitle2">{getTimePeriod(event)}</Typography>
        </Box>
        {event.htmlLink && (
          <Tooltip title="Open in Calendar">
            <Link
              data-testid="open-calendar-link"
              href={event.htmlLink}
              target="_blank"
              onClick={_e =>
                analytics.captureEvent('click', 'open in calendar')
              }
            >
              <IconButton>
                <ArrowForwardIcon />
              </IconButton>
            </Link>
          </Tooltip>
        )}
      </Box>
      {zoomLink && (
        <Link
          href={zoomLink}
          target="_blank"
          onClick={_e => analytics.captureEvent('click', 'zoom link')}
        >
          Join Zoom Meeting
        </Link>
      )}

      {event.description && (
        <>
          <Divider className={classes.divider} variant="fullWidth" />
          <Box
            className={classes.description}
            dangerouslySetInnerHTML={{
              __html: DOMPurify.sanitize(event.description, {
                USE_PROFILES: { html: true },
              }),
            }}
          />
        </>
      )}

      {event.attendees && (
        <>
          <Divider className={classes.divider} variant="fullWidth" />
          <Box>
            <Typography variant="subtitle2">Attendees</Typography>
            <Box mb={1} />
            {sortBy(event.attendees || [], 'email').map(user => (
              <AttendeeChip key={user.email} user={user} />
            ))}
          </Box>
        </>
      )}
    </Box>
  );
}
Example #27
Source File: BoundaryDropdown.tsx    From prism-frontend with MIT License 5 votes vote down vote up
/**
 * Converts the boundary layer data into a list of options for the dropdown
 * grouped by admin level 2, with individual sections under admin level 3.
 */
function getCategories(
  data: LayerData<BoundaryLayerProps>['data'],
  search: string,
  i18nLocale: typeof i18n,
) {
  const locationLevelNames = isEnglishLanguageSelected(i18nLocale)
    ? boundaryLayer.adminLevelNames
    : boundaryLayer.adminLevelLocalNames;
  if (!boundaryLayer.adminLevelNames.length) {
    console.error(
      'Boundary layer has no admin level names. Cannot generate categories.',
    );
    return [];
  }

  // Make categories based off the level of all boundaries
  return sortBy(
    data.features
      .reduce<
        Array<{
          title: string;
          children: { value: string; label: string }[];
        }>
      >((ret, feature) => {
        const parentCategory = feature.properties?.[locationLevelNames[0]];
        const label = feature.properties?.[last(locationLevelNames)!];
        const code = feature.properties?.[boundaryLayer.adminCode];
        if (!label || !code || !parentCategory) {
          return ret;
        }
        // filter via search
        const searchIncludes = (field: string) =>
          field.toLowerCase().includes(search.toLowerCase());
        if (
          search &&
          !searchIncludes(label) &&
          !searchIncludes(code) &&
          !searchIncludes(parentCategory)
        ) {
          return ret;
        }
        // add to categories if exists
        const category = ret.find(c => c.title === parentCategory);
        if (category) {
          // eslint-disable-next-line fp/no-mutating-methods
          category.children.push({ value: code, label });
        } else {
          return [
            ...ret,
            {
              title: parentCategory,
              children: [{ value: code, label }],
            },
          ];
        }
        return ret;
      }, [])
      .map(category => ({
        ...category,
        // sort children by label
        children: sortBy(category.children, 'label'),
      })),
    // then finally sort categories.
    'title',
  );
}
Example #28
Source File: datadoc-permission.ts    From querybook with Apache License 2.0 5 votes vote down vote up
export function sortViewersInfo(viewersInfo: IViewerInfo[]) {
    return sortBy(viewersInfo, [
        (info) => (info.online ? 0 : 1),
        (info) => (info.permission === DataDocPermission.OWNER ? 0 : 1),
        (info) => -(info.editorId ?? Infinity),
        'uid',
    ]);
}
Example #29
Source File: PopularTimes.tsx    From office-hours with GNU General Public License v3.0 5 votes vote down vote up
function generateBusyText(day: number, dailySumWaitTimes: number[]): string {
  const dayWaitTime = dailySumWaitTimes[day];
  const uniqSumWaitTimes = uniq(
    sortBy(dailySumWaitTimes.filter((v) => v >= 0))
  );
  const rank = uniqSumWaitTimes.indexOf(dayWaitTime);
  return BUSY_TEXTS[uniqSumWaitTimes.length][rank];
}