lodash#compact TypeScript Examples

The following examples show how to use lodash#compact. 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: util.ts    From erda-ui with GNU Affero General Public License v3.0 7 votes vote down vote up
filterMenu = (menu: IMenuItem[], type: MENU_SCOPE) => {
  return compact(
    map(menu, (item) => {
      const func = get(menuFilterMap, `${type}.${item.key}`) || defaultFunc;
      const reItem = func(item);
      if (reItem && reItem.subMenu) {
        reItem.subMenu = compact(
          map(reItem.subMenu, (subItem) => {
            const subFunc = get(menuFilterMap, `${type}.${subItem.key}`) || defaultFunc;
            return subFunc(subItem);
          }),
        );
      }
      return reItem;
    }),
  );
}
Example #2
Source File: subWikiPlugin.ts    From TidGi-Desktop with Mozilla Public License 2.0 6 votes vote down vote up
/**
 * Get "Sub-Wiki Plugin"'s content
 * @param mainWikiPath subwiki's main wiki's absolute path.
 * @returns ISubWikiPluginContent
 */
export async function getSubWikiPluginContent(mainWikiPath: string): Promise<ISubWikiPluginContent[]> {
  if (mainWikiPath.length === 0) return [];
  const FileSystemPathsTiddlerPath = getFileSystemPathsTiddlerPath(mainWikiPath);
  try {
    const FileSystemPathsFile = await fs.readFile(FileSystemPathsTiddlerPath, 'utf-8');
    const FileSystemPaths = compact(drop(FileSystemPathsFile.split('\n'), 3));
    return FileSystemPaths.map((line) => ({
      tagName: getTagNameFromMatchPart(line),
      folderName: getFolderNamePathPart(line),
    })).filter((item) => item.folderName.length > 0 && item.tagName.length > 0);
  } catch (error) {
    logger.error((error as Error)?.message, { function: 'getSubWikiPluginContent' });
    return [];
  }
}
Example #3
Source File: index.tsx    From next-basics with GNU General Public License v3.0 6 votes vote down vote up
assignResolveToFieldComponent(field: Record<string, any>) {
    const dataSource = field.dataSource;
    const { resolveName, path } = dataSource;

    const resolveData = this[resolveName as keyof BrickFormElement];
    if (resolveData === undefined) return;

    const options =
      path !== undefined ? get(resolveData, `${path}`) : resolveData;

    const { useIdField, useTextField } = dataSource;
    if (useIdField && useTextField) {
      return options.map((item: Record<string, any>) => {
        return {
          id: get(item, useIdField) || "",
          text: get(item, useTextField) || "",
        };
      });
    } else {
      return compact(options) as FieldDefinition["optionList"];
    }
  }
Example #4
Source File: index.ts    From TidGi-Desktop with Mozilla Public License 2.0 6 votes vote down vote up
/**
   *
   * @param {string} githubRepoName similar to "linonetwo/wiki", string after "https://com/"
   */
  public async updateGitInfoTiddler(workspace: IWorkspace, githubRepoName: string): Promise<void> {
    const browserViews = await this.viewService.getActiveBrowserViews();
    if (compact(browserViews).length === 0) {
      logger.error('no browserView in updateGitInfoTiddler');
      return;
    }
    await Promise.all(
      browserViews.map(async (browserView) => {
        if (browserView !== undefined) {
          const tiddlerText = await this.wikiService.getTiddlerText(workspace, '$:/GitHub/Repo');
          if (tiddlerText !== githubRepoName) {
            await new Promise<void>((resolve) => {
              browserView.webContents.send(WikiChannel.addTiddler, '$:/GitHub/Repo', githubRepoName, {
                type: 'text/vnd.tiddlywiki',
              });
              ipcMain.once(WikiChannel.addTiddlerDone, () => resolve());
            });
          }
        }
      }),
    );
  }
Example #5
Source File: regist-router.tsx    From erda-ui with GNU Affero General Public License v3.0 6 votes vote down vote up
registRouters = (key: string, routers: IGetRouter, { Root, NotFound }: CompMap = {}) => {
  const rs = typeof routers === 'function' ? routers() : routers || [];
  NewestRoot = Root || (NewestRoot as any);
  NewestNotFound = NotFound || (NewestNotFound as any);
  if (rs.length) {
    moduleRouteMap = produce(moduleRouteMap, (draft) => {
      draft[key] = rs;
    });
    const reRoutes = resetRouter(moduleRouteMap);
    const [parsed, routeMap] = parseRoutes({
      path: '/',
      component: NewestRoot,
      NotFound: NewestNotFound,
      routes: compact(Object.values(reRoutes).flat()),
    });
    const routePatterns = sortRoutes(routeMap);
    return { routeMap, routePatterns, parsed };
  }
  return {};
}
Example #6
Source File: index.ts    From TidGi-Desktop with Mozilla Public License 2.0 6 votes vote down vote up
/**
   * We have some value in template that need to get latest value, they are functions, we execute every functions in the template
   * @param submenu menu options to get latest value
   * @returns MenuTemplate that `Menu.buildFromTemplate` wants
   */
  private async getCurrentMenuItemConstructorOptions(
    submenu?: Array<DeferredMenuItemConstructorOptions | MenuItemConstructorOptions>,
  ): Promise<MenuItemConstructorOptions[] | undefined> {
    if (submenu === undefined) return;
    return await Promise.all(
      submenu
        .filter((item) => Object.keys(item).length > 0)
        .map(async (item) => ({
          ...item,
          /** label sometimes is null, causing  */
          label: typeof item.label === 'function' ? item.label() ?? undefined : item.label,
          checked: typeof item.checked === 'function' ? await item.checked() : item.checked,
          enabled: typeof item.enabled === 'function' ? await item.enabled() : item.enabled,
          submenu: !Array.isArray(item.submenu) ? item.submenu : await this.getCurrentMenuItemConstructorOptions(compact(item.submenu)),
        })),
    );
  }
Example #7
Source File: TrackerInstance.ts    From condo with MIT License 6 votes vote down vote up
private _getLogEventPermissionFromConfig ( eventProperties: Pick<ITrackerLogEventType, 'eventProperties'>): boolean  {
        let hasDomainLevelPermission = false
        if (this.allowedDomains) {
            const route = compact<string>(get(eventProperties, ['page', 'path'], '').split('/'))

            if (route.length === 1) {
                hasDomainLevelPermission = Object.keys(this.allowedDomains).some(pageRoute => route[0].includes(pageRoute))
            } else if (route.length === 2) {
                const currentDomainConfig = get(this.allowedDomains, route[0], []) as Array<string>
                const pageConfigName = uuidValidate(route[1]) ? 'id' : route[1]

                hasDomainLevelPermission = currentDomainConfig.indexOf(pageConfigName) !== -1
            } else if (route.length === 3) {
                const currentDomainConfig = get(this.allowedDomains, route[0], []) as Array<string>

                hasDomainLevelPermission = currentDomainConfig.some(pageRoute => route[2].includes(pageRoute))
            }
        }

        return Boolean(this.instance) && Boolean(this.token) && hasDomainLevelPermission
    }
Example #8
Source File: index.tsx    From erda-ui with GNU Affero General Public License v3.0 6 votes vote down vote up
FilterBarHandle = {
  splitKey: '||',
  filterDataKey: '_Q_',
  queryToData: (str = '') => {
    const strArr = str.split(FilterBarHandle.splitKey);
    const _data = {};
    if (!isEmpty(compact(strArr))) {
      map(strArr, (item) => {
        const [key, val] = item.split('[');
        _data[key] = val.slice(0, -1);
      });
    }
    return _data;
  },
  dataToQuery: (_data: object = {}) => {
    const strArr = [] as string[];
    map(_data, (val, key) => {
      val && strArr.push(`${key}[${val}]`);
    });
    return strArr.join(FilterBarHandle.splitKey);
  },
}
Example #9
Source File: index.tsx    From hub with Apache License 2.0 6 votes vote down vote up
getResourceKinds = (data: string): string[] => {
  const kinds = data.match(KIND);
  if (kinds) {
    const cleanKinds = kinds.map((kind: string) => {
      const parts = kind.split(':');
      return parts[1].replaceAll('"', '').trim();
    });
    return uniq(compact(cleanKinds));
  }
  return [];
}
Example #10
Source File: playwright.config.ts    From excalideck with MIT License 6 votes vote down vote up
config: PlaywrightTestConfig = {
    testDir: "test/scenario",
    forbidOnly: IS_CI,
    retries: IS_CI ? 4 : 0,
    webServer: {
        command: "yarn start",
        port: 1234,
        env: {
            EXCALIDRAW_ELEMENTS_INPUT_ONCHANGE_CHECK_INTERVAL: "1",
            SLIDE_MINIATURES_DROP_TRANSITION_DURATION: "0",
            SORTABLE_SLIDE_MINIATURE_MOVE_TRANSITION_DURATION: "0",
            SLIDE_MINIATURE_IMAGE_RENDER_DEBOUNCE: "1",
        },
    },
    use: {
        trace: "retain-on-failure",
    },
    reporter: IS_CI ? [["github"], ["list"]] : "list",
    projects: compact([
        {
            name: "chromium",
            use: { browserName: "chromium" },
        },
        {
            name: "firefox",
            use: { browserName: "firefox" },
        },
        // Re-enable when @playwright/test v1.17.0 is released. See
        // microsoft/playwright issue #9811
        platform() !== "darwin"
            ? {
                  name: "webkit",
                  use: { browserName: "webkit" },
              }
            : null,
    ]),
}
Example #11
Source File: tooltip.ts    From S2 with MIT License 6 votes vote down vote up
getTooltipVisibleOperator = (
  operation: TooltipOperation,
  options: { defaultMenus?: TooltipOperatorMenu[]; cell: S2CellType },
): TooltipOperatorOptions => {
  const { defaultMenus = [], cell } = options;

  const getDisplayMenus = (menus: TooltipOperatorMenu[] = []) => {
    return menus
      .filter((menu) => {
        return isFunction(menu.visible)
          ? menu.visible(cell)
          : menu.visible ?? true;
      })
      .map((menu) => {
        if (menu.children) {
          menu.children = getDisplayMenus(menu.children);
        }
        return menu;
      });
  };
  const displayMenus = getDisplayMenus(operation.menus);

  return {
    onClick: operation.onClick,
    menus: compact([...defaultMenus, ...displayMenus]),
  };
}
Example #12
Source File: in-params-drawer.tsx    From erda-ui with GNU Affero General Public License v3.0 6 votes vote down vote up
formDataToYmlData = (data: IFormData[]): PIPELINE.IPipelineInParams[] => {
  return compact(
    map(data, (item) => {
      const { key, required, defaultValue, component, labelTip } = item;
      const type = get(find(typeMapping, { component }), 'type') || component;
      let _default = defaultValue as any;
      if (type === 'int') _default = isNaN(+_default) ? undefined : +_default;
      if (type === 'boolean') _default = isBoolean(_default) ? _default : _default === 'true';
      if (!key) return null;
      const dataItem = {
        name: key,
        required,
        default: _default || undefined,
        type,
        desc: labelTip,
      };
      const res = {};
      map(dataItem, (val, k) => {
        if (val !== undefined) {
          res[k] = val;
        }
      });
      return res as PIPELINE.IPipelineInParams;
    }),
  );
}
Example #13
Source File: hide-columns.ts    From S2 with MIT License 6 votes vote down vote up
getHiddenColumnNodes = (
  spreadsheet: SpreadSheet,
  hiddenColumnFields: string[] = [],
): Node[] => {
  const columnNodes = spreadsheet.getInitColumnLeafNodes();
  return compact(
    hiddenColumnFields.map((field) => {
      const targetFieldKey = getHiddenColumnFieldKey(field);
      return columnNodes.find((node) => node[targetFieldKey] === field);
    }),
  );
}
Example #14
Source File: config.tsx    From erda-ui with GNU Affero General Public License v3.0 6 votes vote down vote up
getBranchPath = (node?: TREE.NODE, appId?: string) => {
  if (!node || isEmpty(node)) return { branch: '', pagingYmlNames: [], env: '' };
  const gittarYmlPath = get(node, 'meta.snippetAction.snippet_config.labels.gittarYmlPath');
  const snippetConfigName = get(node, 'meta.snippetAction.snippet_config.name') || '';
  const ymlPathStrArr: string[] = compact((gittarYmlPath.replace(snippetConfigName, '') || '').split('/'));
  let pagingYmlNames = [] as string[];
  let branch = '';
  let env = '';
  if (ymlPathStrArr.length) {
    pagingYmlNames = [`${appId}/${gittarYmlPath.split('/').slice(1).join('/')}`, snippetConfigName];
    branch = ymlPathStrArr.slice(2).join('/');
    env = ymlPathStrArr[1];
  }
  const path = snippetConfigName.startsWith('/') ? snippetConfigName.replace('/', '') : snippetConfigName;
  return { branch, path, pagingYmlNames, env };
}
Example #15
Source File: namespace.ts    From ui5-language-assistant with Apache License 2.0 5 votes vote down vote up
/**
 * Suggests Namespaces inside Element
 * For example xmlns:m should provide list of namespaces ending with .m.. (like "sap.m", "sap.ui.core.mvc")
 * attribute is namespace attribute if it's equal to "xmlns" or starts with "xmlns:"
 * in first case all possible namespaces of semantic module will be provided excluding pre-existing ones
 */
export function namespaceKeysSuggestions(
  opts: UI5AttributeNameCompletionOptions
): UI5NamespacesInXMLAttributeKeyCompletion[] {
  const ui5Model = opts.context;
  const xmlElement = opts.element;

  if (opts.prefix === undefined) {
    return [];
  }

  const xmlnsPrefix = getXMLNamespaceKeyPrefix(opts.prefix);
  if (xmlnsPrefix === undefined) {
    return [];
  }

  const existingNamespacesAttributes: XMLAttribute[] = filter(
    xmlElement.attributes,
    isExistingNamespaceAttribute
  );

  const existingNamespacesNames = compact(
    map(existingNamespacesAttributes, (_) => _.value)
  );

  const applicableNamespaces = filter(ui5Model.namespaces, (_) =>
    isNamespaceApplicable(_, xmlnsPrefix)
  );

  const suggestedNamespaces = reject(applicableNamespaces, (_) =>
    includes(existingNamespacesNames, ui5NodeToFQN(_))
  );

  return map(suggestedNamespaces, (_) => ({
    type: "UI5NamespacesInXMLAttributeKey",
    ui5Node: _,
    astNode: opts.attribute as XMLAttribute,
  }));
}
Example #16
Source File: pure-edit-list.tsx    From erda-ui with GNU Affero General Public License v3.0 5 votes vote down vote up
validateValue = (dataTemp: ITemp[], value: IData[]) => {
  const requiredKeys = [] as ITemp[];
  const uniqValueKeys = [] as ITemp[];
  dataTemp.forEach((item) => {
    item.render?.required && requiredKeys.push(item);
    item.render?.uniqueValue && uniqValueKeys.push(item);
  });

  let validTip = '';
  if (!isEmpty(uniqValueKeys)) {
    // 唯一值的key
    uniqValueKeys.forEach((uk) => {
      if (!validTip) {
        const duplicateValues = getDuplicateValue(compact(map(value, uk.key)));
        const sameKey = i18n.t('the same {key} exists', { key: duplicateValues.join(',') });
        duplicateValues.length && (validTip = `${uk.title || uk.key} ${sameKey}`);
      }
    });
  }
  if (!validTip) {
    requiredKeys.forEach((rk) => {
      value.forEach((v) => {
        if (!validTip) {
          const unValid = notEmptyValue(get(v, rk.key));
          !unValid && (validTip = i18n.t('{name} can not empty', { name: rk.title || rk.key }));
        }
      });
    });
  }

  if (!validTip) {
    dataTemp.forEach((item) => {
      const rules = item.render?.rules;
      if (!validTip && rules) {
        value.forEach((v) => {
          if (!validTip) validTip = validRulesValue(rules, get(v, item.key));
        });
      }
    });
  }
  return validTip;
}
Example #17
Source File: deploy.ts    From arbitrum-dai-bridge with GNU Affero General Public License v3.0 5 votes vote down vote up
export async function performSanityChecks(
  deps: NetworkConfig,
  bridgeDeployment: BridgeDeployment,
  l1BlockOfBeginningOfDeployment: number,
  l2BlockOfBeginningOfDeployment: number,
  includeDeployer: boolean,
) {
  console.log('Performing sanity checks...')

  async function checkPermissions(contract: AuthableLike, startBlock: number, _expectedPermissions: string[]) {
    const actualPermissions = await getActiveWards(contract, startBlock)
    const expectedPermissions = compact([..._expectedPermissions, includeDeployer && deps.l1.deployer.address])

    expect(normalizeAddresses(actualPermissions)).to.deep.eq(normalizeAddresses(expectedPermissions))
  }

  await checkPermissions(bridgeDeployment.l1Escrow, l1BlockOfBeginningOfDeployment, [
    deps.l1.makerPauseProxy,
    deps.l1.makerESM,
  ])
  await checkPermissions(bridgeDeployment.l1DaiGateway, l1BlockOfBeginningOfDeployment, [
    deps.l1.makerPauseProxy,
    deps.l1.makerESM,
  ])
  await checkPermissions(bridgeDeployment.l1GovRelay, l1BlockOfBeginningOfDeployment, [
    deps.l1.makerPauseProxy,
    deps.l1.makerESM,
  ])
  await checkPermissions(bridgeDeployment.l2DaiGateway, l2BlockOfBeginningOfDeployment, [
    bridgeDeployment.l2GovRelay.address,
  ])
  await checkPermissions(bridgeDeployment.l2Dai, l2BlockOfBeginningOfDeployment, [
    bridgeDeployment.l2DaiGateway.address,
    bridgeDeployment.l2GovRelay.address,
  ])

  expect(await bridgeDeployment.l1DaiGateway.l1Escrow()).to.be.eq(bridgeDeployment.l1Escrow.address)
  expect(await bridgeDeployment.l1GovRelay.l2GovernanceRelay()).to.be.eq(bridgeDeployment.l2GovRelay.address)
  expect(await bridgeDeployment.l1GovRelay.inbox()).to.be.eq(await bridgeDeployment.l1DaiGateway.inbox())
}
Example #18
Source File: _perm-state.ts    From erda-ui with GNU Affero General Public License v3.0 5 votes vote down vote up
changePerm2Yml = (permData: any, scope: string, ROLES: Obj) => {
  // const postData = [] as any[];
  const setPostData = (obj: any, postData = [] as any[], extra = {} as any) => {
    if (!obj) return postData;
    const { name, role, ...rest } = obj;
    if (!role) {
      map(rest, (item, key) => {
        const reExtra = { ...extra, nameArr: [...(extra.nameArr || []), name] } as any;
        if (scopeNames.includes(key)) {
          reExtra.scope = key;
        } else {
          reExtra.resource = `${reExtra.resource || permPrefix}.${key}`;
        }
        return setPostData(item, postData, reExtra);
      });
    } else {
      const customRole = [] as string[];
      const regularRole = [] as string[];
      map(role, (rItem) => {
        if (ROLES[rItem] && !ROLES[rItem].isCustomRole) {
          regularRole.push(rItem);
        } else {
          customRole.push(rItem);
        }
      });
      const dataItem = {
        scope: extra.scope,
        name: (extra.nameArr || []).concat(name).join(' > '),
        resource: '',
        action: '',
        role: regularRole.join(','),
      } as any;
      const reResource = extra.resource;
      const resourceArr = reResource.split('.');
      dataItem.action = resourceArr.pop();
      dataItem.resource = resourceArr.join('.');
      if (customRole.length) {
        // 含自定义角色resource_role
        dataItem.resource_role = customRole.join(',');
        postData.push(dataItem);
      } else {
        postData.push(dataItem);
      }
    }
    return postData;
  };

  const ymlStr = yaml.dump(setPostData(permData, [], { scope }));
  const ymlStrArr = compact(ymlStr.split('\n'));
  // 去除yml缩进多余
  return map(ymlStrArr, (yItem: string) => {
    return yItem.startsWith('  ') ? yItem.replace('  ', '') : yItem;
  }).join('\n');
}
Example #19
Source File: GeneralCarousel.tsx    From next-basics with GNU General Public License v3.0 5 votes vote down vote up
export function GeneralCarousel({
  speed,
  slidesToShow,
  slidesToScroll,
  autoplay,
  dots,
  components,
  carouselStyle,
  pauseOnDotsHover,
  adaptiveHeight,
  infinite,
  responsive,
  onHandleClick,
  noDataDesc,
  arrows,
  dotsTheme,
  useBrick,
  dataSource,
  autoplaySpeed,
}: GeneralCarouselProps): React.ReactElement {
  const comps = Array.isArray(components) ? components : compact([components]);
  const data = Array.isArray(dataSource) ? dataSource : compact([dataSource]);

  const carousel = (
    <Carousel
      className={classNames({
        "carousel-dots-dark": dotsTheme === "dark",
      })}
      style={carouselStyle}
      autoplay={autoplay}
      dots={dots}
      speed={speed}
      autoplaySpeed={autoplaySpeed}
      slidesToShow={slidesToShow}
      slidesToScroll={slidesToScroll}
      pauseOnDotsHover={pauseOnDotsHover}
      arrows={arrows}
      infinite={infinite}
      adaptiveHeight={adaptiveHeight}
      responsive={responsive}
      prevArrow={<LeftOutlined />}
      nextArrow={<RightOutlined />}
    >
      {useBrick
        ? renderCustomBrick(useBrick, data, onHandleClick)
        : renderCustomComp(comps, onHandleClick)}
    </Carousel>
  );

  return (
    <div className={style.generalCarousel}>
      {useBrick ? (
        data.length !== 0 ? (
          carousel
        ) : (
          <Empty description={noDataDesc} />
        )
      ) : comps.length !== 0 ? (
        carousel
      ) : (
        <Empty description={noDataDesc} />
      )}
    </div>
  );
}
Example #20
Source File: result-view.tsx    From erda-ui with GNU Affero General Public License v3.0 5 votes vote down vote up
ResultView = (props: IProps) => {
  const { data } = props;
  const metadata = get(data, 'result.metadata') || [];
  const api_request = find(metadata, { name: 'api_request' });
  const api_response = find(metadata, { name: 'api_response' });
  const api_assert_detail = find(metadata, { name: 'api_assert_detail' });
  const api_assert_success = find(metadata, { name: 'api_assert_success' });

  const status = find(metadata, { name: 'status' });
  const result = find(metadata, { name: 'result' });
  const resArr = compact([api_request, api_response, api_assert_detail, api_assert_success, status, result]) as any[];

  return (
    <div className="test-case-execute-result">
      {map(resArr, (item: any) => {
        let jsonObj = {} as any;
        let jsonStr = item.value;
        try {
          jsonObj = JSON.parse(item.value);
          if (item.name === 'api_response' && jsonObj.body) {
            try {
              jsonObj = {
                ...jsonObj,
                body: JSON.parse(jsonObj.body),
              };
            } catch (e) {
              jsonObj = { ...jsonObj };
            }
          }
        } catch (e) {
          jsonStr = item.value;
        }
        if (!isEmpty(jsonObj)) {
          jsonStr = JSON.stringify(jsonObj, null, 2);
        }
        // const jsonObj = JSON.parse(item.value);
        // const jsonStr = JSON.stringify(item.value, null, 2);
        return (
          <div className="test-case-execute-result-item mb-3" key={item.name}>
            <div className="label">{labelMap[item.name] || item.name}</div>
            <pre className="value">{jsonStr}</pre>
          </div>
        );
      })}
    </div>
  );
}
Example #21
Source File: CmdbInstanceSelect.tsx    From next-basics with GNU General Public License v3.0 5 votes vote down vote up
export function formatUserQuery(instanceQuery: any) {
  const arr = Array.isArray(instanceQuery) ? instanceQuery : [instanceQuery];

  return compact(arr);
}
Example #22
Source File: AuthorizedSearchEngine.ts    From backstage with Apache License 2.0 5 votes vote down vote up
private async filterResults(
    results: IndexableResult[],
    typeDecisions: Record<string, EvaluatePermissionResponse>,
    authorizer: DataLoader<
      EvaluatePermissionRequest,
      EvaluatePermissionResponse
    >,
  ) {
    return compact(
      await Promise.all(
        results.map(result => {
          if (typeDecisions[result.type]?.result === AuthorizeResult.ALLOW) {
            return result;
          }

          const permission = this.types[result.type]?.visibilityPermission;
          const resourceRef = result.document.authorization?.resourceRef;

          if (!permission || !resourceRef) {
            return result;
          }

          // We only reach this point in the code for types where the initial
          // authorization returned CONDITIONAL -- ALLOWs return early
          // immediately above, and types where the decision was DENY get
          // filtered out entirely when querying.
          //
          // This means the call to isResourcePermission here is mostly about
          // narrowing the type of permission - the only way to get here with a
          // non-resource permission is if the PermissionPolicy returns a
          // CONDITIONAL decision for a non-resource permission, which can't
          // happen - it would throw an error during validation in the
          // permission-backend.
          if (!isResourcePermission(permission)) {
            throw new Error(
              `Unexpected conditional decision returned for non-resource permission "${permission.name}"`,
            );
          }

          return authorizer
            .load({ permission, resourceRef })
            .then(decision =>
              decision.result === AuthorizeResult.ALLOW ? result : undefined,
            );
        }),
      ),
    );
  }
Example #23
Source File: prop-event-assoc.ts    From ui5-language-assistant with Apache License 2.0 5 votes vote down vote up
/**
 * Suggests Properties and Events inside Element
 * For example: 'backgroundDesign' and 'icon' in `sap.m.Page` element
 */
export function propEventAssocSuggestions(
  opts: UI5AttributeNameCompletionOptions
): PropEventsAssocInXMLAttributeKeyCompletion[] {
  const ui5Model = opts.context;
  const xmlElement = opts.element;

  const elementClass = getUI5ClassByXMLElement(xmlElement, ui5Model);
  if (!isElementSubClass(elementClass)) {
    return [];
  }
  const allProps: (UI5Prop | UI5Event | UI5Association)[] = flattenProperties(
    elementClass
  );
  const allEvents = flattenEvents(elementClass);
  const allAssociations = flattenAssociations(elementClass);
  const allPropertiesEventsAssociations = allProps
    .concat(allEvents)
    .concat(allAssociations);

  const prefix = opts.prefix ?? "";
  const existingAttributeNames = compact(
    uniq(map(xmlElement.attributes, (_) => _.key))
  );
  const currentAttributeKey = opts.attribute?.key;
  const existingAttributeNamesWithoutCurrent =
    currentAttributeKey === undefined
      ? existingAttributeNames
      : reject(existingAttributeNames, (name) => name === currentAttributeKey);

  const uniquePrefixMatchingAttributes = filterMembersForSuggestion(
    allPropertiesEventsAssociations,
    prefix,
    existingAttributeNamesWithoutCurrent
  );

  const suggestions = map(uniquePrefixMatchingAttributes, (_) => ({
    type: NodeKindToSuggestionType[_.kind],
    ui5Node: _,
    astNode:
      (opts.attribute as XMLAttribute) ?? createDummyAttribute(xmlElement),
  }));

  // Using casing due to dynamic assignment to the `type` property of each suggestion
  return suggestions as PropEventsAssocInXMLAttributeKeyCompletion[];
}
Example #24
Source File: index.ts    From TidGi-Desktop with Mozilla Public License 2.0 5 votes vote down vote up
/**
   * Insert provided sub menu items into menubar, so user and services can register custom menu items
   * @param menuID Top level menu name to insert menu items
   * @param newSubMenuItems An array of menu item to insert or update, if some of item is already existed, it will be updated instead of inserted
   * @param afterSubMenu The `id` or `role` of a submenu you want your submenu insert after. `null` means inserted as first submenu item; `undefined` means inserted as last submenu item;
   * @param withSeparator Need to insert a separator first, before insert menu items
   * @param menuPartKey When you update a part of menu, you can overwrite old menu part with same key
   */
  public async insertMenu(
    menuID: string,
    newSubMenuItems: Array<DeferredMenuItemConstructorOptions | MenuItemConstructorOptions>,
    afterSubMenu?: string | null,
    withSeparator = false,
    menuPartKey?: string,
  ): Promise<void> {
    let foundMenuName = false;
    const copyOfNewSubMenuItems = [...newSubMenuItems];
    // try insert menu into an existed menu's submenu
    for (const menu of this.menuTemplate) {
      // match top level menu
      if (menu.id === menuID) {
        foundMenuName = true;
        // heck some menu item existed, we update them and pop them out
        const currentSubMenu = compact(menu.submenu);
        // we push old and new content into this array, and assign back to menu.submenu later
        let filteredSubMenu: Array<DeferredMenuItemConstructorOptions | MenuItemConstructorOptions> = currentSubMenu;
        // refresh menu part by delete previous menuItems that belongs to the same partKey
        if (menuPartKey !== undefined) {
          filteredSubMenu = filteredSubMenu.filter((currentSubMenuItem) => !this.belongsToPart(menuPartKey, menuID, currentSubMenuItem.id));
        }
        for (const newSubMenuItem of newSubMenuItems) {
          const existedItemIndex = currentSubMenu.findIndex((existedItem) => MenuService.isMenuItemEqual(existedItem, newSubMenuItem));
          // replace existed item, and remove it from needed-to-add-items
          if (existedItemIndex !== -1) {
            filteredSubMenu[existedItemIndex] = newSubMenuItem;
            remove(newSubMenuItems, (item) => item.id === newSubMenuItem.id);
          }
        }

        if (afterSubMenu === undefined) {
          // inserted as last submenu item
          if (withSeparator) {
            filteredSubMenu.push({ type: 'separator' });
          }
          filteredSubMenu = [...filteredSubMenu, ...newSubMenuItems];
        } else if (afterSubMenu === null) {
          // inserted as first submenu item
          if (withSeparator) {
            newSubMenuItems.push({ type: 'separator' });
          }
          filteredSubMenu = [...newSubMenuItems, ...filteredSubMenu];
        } else if (typeof afterSubMenu === 'string') {
          // insert after afterSubMenu
          const afterSubMenuIndex = filteredSubMenu.findIndex((item) => item.id === afterSubMenu || item.role === afterSubMenu);
          if (afterSubMenuIndex === -1) {
            throw new InsertMenuAfterSubMenuIndexError(afterSubMenu, menuID, menu);
          }
          filteredSubMenu = [...take(filteredSubMenu, afterSubMenuIndex + 1), ...newSubMenuItems, ...drop(filteredSubMenu, afterSubMenuIndex - 1)];
        }
        menu.submenu = filteredSubMenu;
        // leave this finding menu loop
        break;
      }
    }
    // if user wants to create a new menu in menubar
    if (!foundMenuName) {
      this.menuTemplate.push({
        label: menuID,
        submenu: newSubMenuItems,
      });
    }
    // update menuPartRecord
    if (menuPartKey !== undefined) {
      this.updateMenuPartRecord(menuPartKey, menuID, copyOfNewSubMenuItems);
    }
    await this.buildMenu();
  }
Example #25
Source File: cards.ts    From fishbowl with MIT License 5 votes vote down vote up
export function parseWordList(wordList: string) {
  return compact(wordList.split(",").map((word) => word.trim()))
}
Example #26
Source File: Keywords.tsx    From hub with Apache License 2.0 5 votes vote down vote up
Keywords = (props: Props) => {
  const history = useHistory();

  const cleanKeywords = (): string[] => {
    let keywords: string[] = [];

    if (!isUndefined(props.keywords) && !isNull(props.keywords)) {
      keywords = uniq(compact(props.keywords));
    }

    return keywords;
  };

  const [keywords, setKeywords] = useState<string[]>(cleanKeywords());

  useEffect(() => {
    setKeywords(cleanKeywords());
  }, [props.keywords]); /* eslint-disable-line react-hooks/exhaustive-deps */

  if (keywords.length === 0) return null;

  return (
    <>
      <SmallTitle text="Keywords" id="keywords-list" />
      <div className="mb-3" role="list" aria-describedby="keywords-list">
        <span data-testid="keywords">
          {keywords.map((keyword: string) => (
            <button
              className={`btn btn-sm d-inline badge fw-normal me-2 mb-2 mb-sm-0 mw-100 ${styles.badge}`}
              key={keyword}
              onClick={() => {
                history.push({
                  pathname: '/packages/search',
                  search: prepareQueryString({
                    tsQueryWeb: keyword,
                    pageNumber: 1,
                    deprecated: props.deprecated,
                  }),
                });
              }}
              aria-label={`Filter by ${keyword}`}
              role="listitem"
            >
              <div className="text-truncate">{keyword}</div>
            </button>
          ))}
        </span>
      </div>
    </>
  );
}
Example #27
Source File: aggregation.ts    From ui5-language-assistant with Apache License 2.0 5 votes vote down vote up
/**
 * Suggests Aggregation inside sap.ui.core.Element
 * For example: 'content' and 'footer' inside `sap.m.Page`
 */
export function aggregationSuggestions(
  opts: UI5ElementNameCompletionOptions
): UI5AggregationsInXMLTagNameCompletion[] {
  const ui5Model = opts.context;
  const prefix = opts.prefix ?? "";
  const xmlElement = opts.element;
  const parentXMLElement = xmlElement.parent;

  // The top level element cannot be an aggregation
  if (parentXMLElement.type === "XMLDocument") {
    return [];
  }

  const prefixParts = splitQNameByNamespace(prefix);

  // An aggregation must be on the parent tag namespace.
  // We suggest the completion even if the namespace was not defined.
  if (
    prefixParts.prefix !== undefined &&
    !isSameXMLNSFromPrefix(
      parentXMLElement.ns,
      parentXMLElement,
      prefixParts.prefix,
      xmlElement
    )
  ) {
    return [];
  }

  const parentUI5Class = getUI5ClassByXMLElement(parentXMLElement, ui5Model);
  if (!isElementSubClass(parentUI5Class)) {
    return [];
  }

  const existingAggregations = compact(
    uniq(map(parentXMLElement.subElements, (_) => _.name))
  );
  const existingAggregationsWithoutCurrent =
    xmlElement.name === null
      ? existingAggregations
      : reject(existingAggregations, (name) => name === xmlElement.name);

  const uniquePrefixMatchingAggregations = filterMembersForSuggestion(
    flattenAggregations(parentUI5Class),
    prefixParts.localName,
    existingAggregationsWithoutCurrent
  );

  return map(uniquePrefixMatchingAggregations, (_) => ({
    type: "UI5AggregationsInXMLTagName",
    ui5Node: _,
    astNode: xmlElement,
  }));
}
Example #28
Source File: basic.tsx    From S2 with MIT License 5 votes vote down vote up
function getRange(data) {
  const values = data.map((d) => d.value);
  const compactValue = compact(values);
  return {
    min: Math.min(...compactValue),
    max: Math.max(...compactValue),
  };
}
Example #29
Source File: role-editor.tsx    From erda-ui with GNU Affero General Public License v3.0 4 votes vote down vote up
AddRole = (props: IProps) => {
  const { data, updateRole } = props;
  const [{ visible, roleData, editData }, updater, update] = useUpdate({
    visible: false,
    roleData: [],
    editData: undefined as any,
  });

  React.useEffect(() => {
    updater.roleData(cloneDeep(map(data)));
  }, [data, updater]);

  const onOk = (v: any) => {
    const { roles } = v;
    const newRole = {};
    map(roles, (item) => {
      newRole[item.value] = item;
    });
    updateRole(newRole);
    onCancel();
  };

  const onOpen = () => {
    update({
      editData: { roles: roleData },
      visible: true,
    });
  };

  const onCancel = () => {
    update({
      visible: false,
      editData: undefined,
    });
  };

  const fields = [
    {
      label: i18n.t('Role'),
      component: 'arrayObj',
      key: 'roles',
      required: true,
      wrapperProps: {
        extra: '修改角色key或删除角色后,导出数据会删除对应的角色',
      },
      componentProps: {
        defaultItem: { value: '', name: '', isCustomRole: false },
        itemRender: (_data: Obj, updateItem: Function) => {
          return [
            <Input
              key="value"
              value={_data.value}
              onChange={(e: any) => updateItem({ value: e.target.value })}
              placeholder={i18n.t('please enter')}
            />,
            <Input
              key="name"
              value={_data.name}
              onChange={(e: any) => updateItem({ name: e.target.value })}
              placeholder={i18n.t('please enter')}
            />,
            <div key="isCustomRole" className="flex justify-between items-center">
              <span className="text-desc nowrap">
                {i18n.t('customize')} {i18n.t('Role')}
              </span>
              <Switch
                key="isCustomRole"
                checked={!!_data.isCustomRole}
                onChange={(v) => updateItem({ isCustomRole: v })}
                checkedChildren={i18n.t('common:Yes')}
                unCheckedChildren={i18n.t('common:No')}
              />
            </div>,
          ];
        },
      },
      rules: [
        {
          validator: (val = []) => {
            let tip = '';
            const valueArr = map(val, 'value');
            const nameArr = map(val, 'name');
            if (compact(valueArr).length !== val.length || compact(nameArr).length !== val.length) {
              tip = i18n.t('dop:this item cannot be empty');
            } else if (uniq(nameArr).length !== val.length) {
              tip = i18n.t('{name} already exists', { name: i18n.t('Name') });
            } else if (uniq(valueArr).length !== val.length) {
              tip = i18n.t('{name} already exists', { name: 'key' });
            }
            if (!tip) {
              const keyReg = /^[a-zA-Z]+$/;
              valueArr.forEach((item) => {
                if (!keyReg.test(item)) {
                  tip = i18n.t('key only can be letters');
                }
              });
            }
            return [!tip, tip];
          },
        },
      ],
    },
  ];

  return (
    <div className="flex justify-between items-center">
      <Button size="small" onClick={onOpen}>
        {i18n.t('edit {name}', { name: i18n.t('Role') })}
      </Button>
      <FormModal
        width={650}
        visible={visible}
        title={i18n.t('edit {name}', { name: i18n.t('Role') })}
        onOk={onOk}
        onCancel={onCancel}
        fieldList={fields}
        formData={editData}
      />
    </div>
  );
}