js-base64#encode TypeScript Examples

The following examples show how to use js-base64#encode. 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: export-factory.ts    From vscode-code-review with MIT License 6 votes vote down vote up
private getCodeForFile(filename: string, lines: string): string {
    if (!filename) {
      filename = '';
    }
    if (!lines) {
      lines = '';
    }
    let result = '';
    const lineRanges = splitStringDefinition(lines); // split: 2:2-12:2|8:0-18:5
    const filePath = toAbsolutePath(this.workspaceRoot, filename);
    if (lineRanges) {
      lineRanges.forEach((rangeString: string) => {
        if (rangeString) {
          const range = rangeFromStringDefinition(rangeString, 1);
          const fileContent = stripIndent(getFileContentForRange(filePath, range));
          if (result) {
            result = `${result}${EOL}...${EOL}${EOL}${fileContent}`;
          } else {
            result = fileContent;
          }
        }
      });
    }
    return encode(result);
  }
Example #2
Source File: list.tsx    From erda-ui with GNU Affero General Public License v3.0 6 votes vote down vote up
getDetailId = (detail: Obj | null) => {
  if (detail) {
    try {
      const res = encode(JSON.stringify(detail));
      return res;
    } catch (error) {
      // eslint-disable-next-line no-console
      console.error(error);
      return null;
    }
  }
  return '';
}
Example #3
Source File: GroupCustomWebPanelRender.tsx    From tailchat with GNU General Public License v3.0 6 votes vote down vote up
GroupCustomWebPanelRender: React.FC<{ panelInfo: any }> = (props) => {
  const panelInfo = props.panelInfo;

  if (!panelInfo) {
    return <div>{Translate.notfound}</div>;
  }

  const html = panelInfo?.meta?.html;
  const src = useMemo(() => {
    if (isValidStr(html)) {
      const appendHtml = getInjectedStyle(); // 额外追加的样式
      try {
        return `data:text/html;charset=utf8;base64,${encode(
          sanitize(html + appendHtml, { replacementText: 'No allowed script' })
        )}`;
      } catch (e) {
        return undefined;
      }
    } else {
      return undefined;
    }
  }, [html]);

  return <iframe className="w-full h-full" src={src} />;
}
Example #4
Source File: judge0.ts    From netless-app with MIT License 6 votes vote down vote up
public async runCode(source: string, lang: string): Promise<string> {
    if (!this.hasLanguage(lang)) {
      return "Language not supported!\n";
    }

    try {
      const response = await fetch(
        "https://judge0-ce.p.rapidapi.com/submissions?base64_encoded=true&wait=true&fields=*",
        {
          method: "POST",
          headers: {
            "content-type": "application/json",
            "x-rapidapi-host": "judge0-ce.p.rapidapi.com",
            "x-rapidapi-key": this.apiKey,
          },
          body: JSON.stringify({
            language_id: Judge0.lanMap[lang],
            source_code: encode(source),
          }),
        }
      );

      const data = await response.json();

      if (data.stderr) {
        return decode(data.stderr);
      } else if (data.stdout) {
        return decode(data.stdout);
      }
      return "Unknown error\n";
    } catch (err) {
      return `${err instanceof Error ? err.message : String(err)}\n`;
    }
  }
Example #5
Source File: xterm-binary.tsx    From erda-ui with GNU Affero General Public License v3.0 5 votes vote down vote up
function sendData(term: ITerminal, type: string, data?: string) {
  if (term.__socket) {
    term.__socket.send(type + encode(data || ''));
  }
}
Example #6
Source File: xterm-channel.tsx    From erda-ui with GNU Affero General Public License v3.0 5 votes vote down vote up
function sendData(term: ITerminal, type: string, data?: string) {
  if (term.__socket) {
    term.__socket.send(type + encode(data || ''));
  }
}
Example #7
Source File: xterm-channel.tsx    From erda-ui with GNU Affero General Public License v3.0 5 votes vote down vote up
function proxyInput(term: ITerminal) {
  const { __sendData } = term;
  term.off('data', __sendData);
  term.__sendData = (data) => {
    __sendData(`${Input}${encode(data || '')}`);
  };
  term.on('data', term.__sendData);
}
Example #8
Source File: register-command.tsx    From logseq-plugin-todo-master with MIT License 5 votes vote down vote up
export function registerCommand() {
  logseq.provideStyle(style);

  logseq.App.onMacroRendererSlotted(async ({ payload, slot }) => {
    const [type] = payload.arguments;
    if (!type?.startsWith(macroPrefix)) {
      return;
    }

    logseq.provideStyle({
      key: slot,
      style: `#${slot} {display: inline-flex;}`,
    });

    let maybeUUID = null;
    // Implicitly use the current block
    if (type === macroPrefix) {
      maybeUUID = payload.uuid;
    } else {
      maybeUUID = decode(type.substring(macroPrefix.length + 1));
    }
    if (maybeUUID) {
      startRendering(maybeUUID, slot);
    }
  });

  async function insertMacro(mode: "page" | "block" = "block") {
    const block = await logseq.Editor.getCurrentBlock();
    if (block && block.uuid) {
      let content = "";
      let maybeUUID = "";
      if (mode === "block") {
        // We will from now on always use implicit block IDs to get rid of "Tracking target not found" issue
        // maybeUUID = block.uuid;
      } else {
        const page = await logseq.Editor.getPage(block.page.id);
        if (page?.originalName) {
          maybeUUID = page.originalName;
        }
      }
      if (maybeUUID) {
        // Use base64 to avoid incorrectly rendering in properties
        content = `{{renderer ${macroPrefix}-${encode(maybeUUID)}}}`;
      } else {
        content = `{{renderer ${macroPrefix}}}`;
      }
      await logseq.Editor.insertAtEditingCursor(content);
    }
  }

  logseq.Editor.registerSlashCommand(
    "[TODO Master] Add Progress Bar",
    async () => {
      return insertMacro();
    }
  );
}
Example #9
Source File: index.tsx    From erda-ui with GNU Affero General Public License v3.0 4 votes vote down vote up
ClusterManage = () => {
  const list = clusterStore.useStore((s) => s.list);
  const { addCluster, updateCluster, getClusterList } = clusterStore.effects;
  const [loading] = useLoading(clusterStore, ['getClusterList']);
  const listRef = React.useRef<Obj | null>(null);

  const [
    {
      addModalVis,
      typeSelectorVis,
      addModalFormData,
      addClusterType,
      logRecordId,
      cloudVendor,
      aliCloudContainerFormVisible,
      aliCloudErdcFormVisible,
    },
    updater,
  ] = useUpdate({
    addModalVis: false,
    typeSelectorVis: false,
    addModalFormData: null,
    addClusterType: '',
    logRecordId: '',
    cloudVendor: '',
    aliCloudContainerFormVisible: false,
    aliCloudErdcFormVisible: false,
  });

  useEffectOnce(() => {
    const query = routeStore.getState((s) => s.query);
    getClusterList();
    if (query?.autoOpen) {
      updater.typeSelectorVis(true);
      setSearch({}, [], true);
    }
    return () => {
      clusterStore.reducers.clearClusterList();
    };
  });

  const toggleAddModalVis = (isCancel = false) => {
    if (addModalVis) {
      isCancel && !addClusterType && toggleTypeModalVis();
      updater.addClusterType('');
    }
    updater.addModalVis(!addModalVis);
  };

  const toggleTypeModalVis = () => {
    updater.typeSelectorVis(!typeSelectorVis);
  };

  const handleSelectType = (addType: string) => {
    if (['k8s', 'edas', 'dcos'].includes(addType)) {
      // 导入集群
      updater.addClusterType(addType);
      handleShowAddClusterModal();
    } else if (['alicloud-cs', 'alicloud-cs-managed'].includes(addType)) {
      updater.cloudVendor(addType);
      updater.aliCloudContainerFormVisible(true);
    } else if (addType === 'erdc') {
      updater.aliCloudErdcFormVisible(true);
    }
  };

  const handleShowAddClusterModal = (record?: any) => {
    if (record) {
      updater.addClusterType(record.type);
      updater.addModalFormData(record);
    } else {
      updater.addModalFormData(null);
    }
    toggleAddModalVis();
  };

  const handleAddCluster = async (values: any) => {
    const { id, credential: credentialData, ...restData } = values;
    const credential =
      credentialData?.content === '********'
        ? { address: credentialData?.address }
        : credentialData?.content
        ? { ...credentialData, content: encode(credentialData.content) }
        : credentialData;
    if (id) {
      // urls 中仍有其他配置,后面可能会加入
      await updateCluster({ ...values, credential });
      listRef.current?.reload();
    } else {
      await addCluster({ ...restData, credential });
      listRef.current?.reload();
      if (restData.credentialType === 'proxy') {
        setSearch({ autoOpenCmd: true, clusterName: restData.name }, [], true);
      }
    }
  };

  const handleAddAliCloudContainer = ({ recordID }: { recordID: string }) => {
    updater.logRecordId(recordID);
    updater.aliCloudContainerFormVisible(false);
  };

  const handleAddAliCloudErdc = ({ recordID }: { recordID: string }) => {
    updater.logRecordId(recordID);
    updater.aliCloudErdcFormVisible(false);
  };

  return (
    <div className="cluster-manage-ct">
      <Spin spinning={loading}>
        <ClusterList ref={listRef} onEdit={handleShowAddClusterModal} />
      </Spin>
      <TopButtonGroup>
        <Button onClick={() => goTo('./history')}>{i18n.t('cmp:History')}</Button>
        <Button type="primary" onClick={() => updater.typeSelectorVis(true)}>
          {i18n.t('Add')}
        </Button>
      </TopButtonGroup>
      <ClusterTypeModal visible={typeSelectorVis} toggleModal={toggleTypeModalVis} onSubmit={handleSelectType} />
      <AddClusterModal
        visible={addModalVis}
        initData={addModalFormData}
        toggleModal={toggleAddModalVis}
        onSubmit={handleAddCluster}
        clusterType={addClusterType}
        clusterList={list}
      />
      <ClusterLog recordID={logRecordId} onClose={() => updater.logRecordId('')} />
      <AliCloudContainerForm
        cloudVendor={cloudVendor}
        visible={aliCloudContainerFormVisible}
        onSubmit={handleAddAliCloudContainer}
        onClose={() => {
          toggleTypeModalVis();
          updater.aliCloudContainerFormVisible(false);
        }}
      />
      <AliCloudErdcForm
        visible={aliCloudErdcFormVisible}
        onSubmit={handleAddAliCloudErdc}
        onClose={() => {
          toggleTypeModalVis();
          updater.aliCloudErdcFormVisible(false);
        }}
      />
    </div>
  );
}
Example #10
Source File: index.tsx    From erda-ui with GNU Affero General Public License v3.0 4 votes vote down vote up
Pipeline = (props: IProps) => {
  const {
    appId,
    nodeId,
    pipelineId: _pipelineId,
    branchExist,
    projectId,
    pipelineName,
    appName,
    setNewPipelineUsed,
    projectName,
    pipelineDefinitionID,
  } = props;
  const { getTreeNodeDetailNew } = fileTreeStore;
  const [pipelineId, setPipelineId] = React.useState(_pipelineId);
  const { commit } = repoStore.effects;
  const [commitLoading] = useLoading(repoStore, ['commit']);
  const { getPipelineDetail } = buildStore.effects;
  const { clearPipelineDetail } = buildStore.reducers;
  const [pipelineDetail, setPipelineDetail] = React.useState<BUILD.IPipelineDetail>();
  const [nodeDetail, setNodeDetail] = React.useState<TREE.NODE>();
  const [mode, setMode] = React.useState<DetailMode>(DetailMode.empty);
  const [initPipeline, setInitPipeline] = React.useState(false);
  const [fileChanged, setFileChanged] = React.useState(false);

  // mobile_init is a special node, only allowed to run pipeline
  const isMobileInit = nodeId === 'mobile_init';
  useUnmount(() => {
    clearPipelineDetail();
  });

  React.useEffect(() => {
    if (pipelineId) {
      getPipelineDetail({ pipelineID: +pipelineId }).then((res) => {
        setPipelineDetail(res);
      });
    } else {
      setMode(DetailMode.file);
    }
  }, [pipelineId, getPipelineDetail]);

  React.useEffect(() => {
    pipelineDetail && setInitPipeline(true);
  }, [pipelineDetail]);

  useUpdateEffect(() => {
    initPipeline && initMode();
  }, [initPipeline]);

  const getNodeDetail = React.useCallback(() => {
    getTreeNodeDetailNew({ id: nodeId, scope: 'project-app', scopeID: appId }).then((res) => setNodeDetail(res));
  }, [nodeId, appId, getTreeNodeDetailNew]);

  React.useEffect(() => {
    getNodeDetail();
  }, [getNodeDetail]);

  const onUpdate = (ymlStr: string) => {
    const fileName = nodeDetail?.name;
    const { branch, path } = getBranchPath(nodeDetail);

    return commit({
      repoPrefix: `${projectName}/${appName}`,
      branch,
      message: `Update ${fileName}`,
      actions: [
        {
          content: ymlStr,
          path,
          action: 'update',
          pathType: 'blob',
        },
      ],
    }).then(() => {
      getNodeDetail();
    });
  };

  const initMode = () => {
    const pipelineYmlContent = pipelineDetail?.ymlContent;
    setMode(pipelineYmlContent ? DetailMode.execute : DetailMode.file);
  };

  React.useEffect(() => {
    const fileYmlContent = nodeDetail?.meta?.pipelineYml;
    const pipelineYmlContent = pipelineDetail?.ymlContent;

    if (fileYmlContent) {
      if (pipelineYmlContent) setFileChanged(fileYmlContent !== pipelineYmlContent);
      if (fileYmlContent === pipelineYmlContent) setMode(DetailMode.execute);
    }
  }, [pipelineDetail, nodeDetail, branchExist, isMobileInit, initPipeline]);

  const editAuth = { hasAuth: true };
  const deployAuth = { hasAuth: true };

  if (!branchExist && !pipelineId) return <EmptyHolder />;
  const editPipeline = () => {
    setMode(DetailMode.edit);
  };

  const isInApp = getIsInApp();
  const extraTitle = (
    <Tooltip title={i18n.t('dop:check execution history')}>
      <ErdaIcon
        onClick={() => {
          const params = {
            projectId,
            query: {
              // fix with base64 RFC 4648
              customFilter__urlQuery: encode(`{"title":"${pipelineName}"}`).replaceAll('/', '_').replaceAll('+', '-'),
            },
            jumpOut: true,
          };
          if (isInApp) {
            goTo(goTo.pages.appPipelineRecords, { ...params, appId });
          } else {
            goTo(goTo.pages.projectPipelineRecords, params);
          }
        }}
        fill="black-4"
        size="18"
        type="jsjl"
        className="cursor-pointer ml-2"
      />
    </Tooltip>
  );

  return mode && mode !== DetailMode.execute ? (
    <Editor
      mode={mode}
      projectId={projectId}
      loading={commitLoading}
      switchToExecute={() => setMode(DetailMode.execute)}
      setEditMode={(v) => setMode(v)}
      fileChanged={fileChanged}
      setPipelineId={(v) => {
        setPipelineId(v);
        setNewPipelineUsed?.(true);
      }}
      extraTitle={extraTitle}
      editAuth={editAuth.hasAuth}
      pipelineDetail={pipelineDetail}
      pipelineDefinitionID={pipelineDefinitionID}
      deployAuth={deployAuth.hasAuth}
      pipelineFileDetail={nodeDetail}
      onUpdate={onUpdate}
    />
  ) : pipelineId ? (
    <Execute
      appId={appId}
      setPipelineId={(v) => {
        setPipelineId(v);
        setNewPipelineUsed?.(true);
      }}
      projectId={projectId}
      pipelineId={pipelineId}
      switchToEditor={() => setMode(DetailMode.file)}
      pipelineDefinitionID={pipelineDefinitionID}
      extraTitle={extraTitle}
      fileChanged={fileChanged}
      deployAuth={deployAuth}
      pipelineDetail={pipelineDetail}
      pipelineFileDetail={nodeDetail}
      editPipeline={editPipeline}
    />
  ) : null;
}
Example #11
Source File: release-select.tsx    From erda-ui with GNU Affero General Public License v3.0 4 votes vote down vote up
ListSelectOverlay = ({
  selectedList,
  select,
  remove,
  onOk,
  clear,
  onCancel,
  renderSelectedItem,
}: OverlayProps) => {
  const { params } = routeInfoStore.useStore((s) => s);
  const { projectId } = params;
  const labelsList = projectLabel.useStore((s) => s.list);
  const appList = releaseStore.useStore((s) => s.appList);
  const { getAppList } = releaseStore.effects;
  const [app, setApp] = React.useState<number>();
  const [branchList, setBranchList] = React.useState(['master', 'develop']);
  const [memberList] = memberStore.useStore((s) => [s.list]);
  const { getMemberList } = memberStore.effects;
  const [filterData, setFilterData] = React.useState<FilterData>({ latest: 'true' });
  const [releaseList, setReleaseList] = React.useState<RELEASE.ReleaseDetail[]>([] as RELEASE.ReleaseDetail[]);
  const [releaseTotal, setReleaseTotal] = React.useState(0);
  const [pageNo, setPageNo] = React.useState(1);
  const listPagination = {
    total: releaseTotal,
    current: pageNo,
    pageSize: PAGINATION.pageSize,
    onChange: (_pageNo: number) => {
      getReleases(_pageNo);
    },
  };

  const getReleases = React.useCallback(
    async (_pageNo: number) => {
      setPageNo(_pageNo);
      const res = await getReleaseList({
        projectId,
        pageNo: _pageNo,
        isProjectRelease: false,
        pageSize: PAGINATION.pageSize,
        isStable: true,
        ...filterData,
      });
      const { data } = res;
      if (data) {
        const { list, total } = data;
        setReleaseList(list.map((item) => ({ ...item, id: item.releaseId, pId: item.applicationId })));
        setReleaseTotal(total);
      }
    },
    [projectId, filterData],
  );

  const getBranch = async (app: number) => {
    const params = {
      pinode: encode(`${projectId}/${app}`),
      pipelineCategoryKey: '',
      scope: 'project-app',
      scopeID: projectId,
    };

    const res = await getFileTree(params);
    if (res.success) {
      const { data } = res;
      setBranchList(data?.map((item) => item.name) || []);
    }
  };

  React.useEffect(() => {
    getAppList({ projectId });
    getMemberList({ scope: { id: projectId, type: MemberScope.PROJECT }, pageNo: 1, pageSize: 10000 });
  }, [projectId, getAppList, getMemberList]);

  React.useEffect(() => {
    getReleases(1);
  }, [getReleases]);

  React.useEffect(() => {
    if (app) {
      getBranch(app);
    } else {
      setBranchList(['master', 'develop']);
    }
  }, [app]);

  const fieldsList = [
    {
      key: 'applicationId',
      type: 'select',
      label: i18n.t('App'),
      mode: 'single',
      options: appList.map((item) => ({ label: item.displayName, value: item.id })),
      placeholder: i18n.t('filter by {name}', { name: i18n.t('App') }),
      itemProps: {
        showSearch: true,
        onChange: (value: number) => setApp(value),
      },
    },
    {
      key: 'branchName',
      type: 'select',
      label: i18n.t('dop:branch'),
      mode: 'single',
      options: branchList.map((item) => ({ label: item, value: item })),
      placeholder: i18n.t('filter by {name}', { name: i18n.t('dop:branch') }),
      itemProps: {
        showSearch: true,
      },
    },
    {
      key: 'commitId',
      type: 'input',
      label: 'commitID',
      placeholder: i18n.t('filter by {name}', { name: 'commitID' }),
    },
    {
      key: 'releaseId',
      type: 'input',
      label: `${i18n.t('Artifacts')}ID`,
      placeholder: i18n.t('filter by {name}', { name: `${i18n.t('Artifacts')}ID` }),
    },
    {
      key: 'userId',
      type: 'select',
      label: i18n.t('Creator'),
      mode: 'single',
      options: memberList.map((item) => ({ label: item.nick, value: item.userId })),
      placeholder: i18n.t('filter by {name}', { name: i18n.t('Creator') }),
    },
    {
      key: 'latest',
      type: 'select',
      label: i18n.t('dop:only the latest version is displayed'),
      mode: 'single',
      options: [{ label: i18n.t('common:Yes'), value: 'true' }],
    },
    {
      key: 'tags',
      type: 'tagsSelect',
      label: i18n.t('label'),
      options: labelsList.map((item) => ({ ...item, value: item.id })),
    },
    {
      key: 'q',
      outside: true,
      label: 'title',
      placeholder: i18n.t('filter by {name}', { name: i18n.t('Title') }),
      type: 'input',
    },
  ];

  return (
    <Row className="erda-list-select-overlay text-default-9 rounded">
      <Col span={12} className="px-2 h-full bg-default-02">
        <div className="erda-list-select-right-content flex">
          <div className="flex-1 pl-2 min-w-0">
            <div className="py-3 px-2 mb-2">
              <ConfigurableFilter
                hideSave
                value={filterData}
                fieldsList={fieldsList}
                onFilter={(values) => setFilterData(values)}
                onClear={() => {}}
              />
            </div>
            <div className="erda-list-select-list flex-1 flex flex-col justify-between">
              <div className="flex-1 overflow-y-auto">
                {releaseList?.map?.((item) => {
                  const checked = !!selectedList.find((listItem) => listItem.id === item.id);
                  return (
                    <div
                      className="px-2 py-3 rounded-sm cursor-pointer hover:bg-default-04 flex items-center"
                      onClick={() => select(item as Item, !checked)}
                      key={item.id}
                    >
                      <Radio multiple checked={checked} />
                      <div className="pl-3 flex-1 min-w-0 truncate">{renderItem(item as Item)}</div>
                    </div>
                  );
                })}

                {!releaseList.length ? (
                  <div className="h-full flex items-center justify-center flex-col">
                    <img src={empty} />
                    <div className="text-default-6 mt-2">
                      {i18n.t('dop:no {name}', { name: i18n.t('dop:App artifact') })}
                    </div>
                  </div>
                ) : null}
              </div>

              {listPagination ? <Pagination hidePageSizeChange {...listPagination} /> : null}
            </div>
          </div>
        </div>
      </Col>
      <Col span={12} className="px-2 h-full">
        <div className="py-3 px-2">
          {i18n.t('common:Selected')}
          {selectedList.length && selectedList.length !== 0 ? (
            <span className="selected-num ml-2 rounded-full">{selectedList.length}</span>
          ) : null}
        </div>
        <div className="erda-list-select-selected-list overflow-y-auto">
          {selectedList.map((item) => (
            <div
              className="erda-list-select-selected-item flex items-center p-2 hover:bg-default-04 rounded-sm"
              key={item.id}
            >
              <div className="flex-1 pr-2 min-w-0 truncate">{renderSelectedItem(item, false)}</div>
              <ErdaIcon
                type="close-small"
                size={24}
                className="erda-list-select-selected-item-delete cursor-pointer text-default-6"
                onClick={() => remove(item.id)}
              />
            </div>
          ))}
          {!selectedList.length ? (
            <div className="h-full flex items-center justify-center flex-col">
              <img src={empty} />
              <div className="text-default-6 mt-2">{i18n.t('dop:No app artifacts selected')}</div>
            </div>
          ) : null}
        </div>
        <div className="py-3 px-2 float-right">
          <Button className="mr-2" onClick={onCancel}>
            {i18n.t('Cancel')}
          </Button>
          <Button className="mr-2" onClick={clear}>
            {i18n.t('Clear with One Click')}
          </Button>
          <Button className="mr-2" type="primary" onClick={onOk}>
            {i18n.t('OK')}
          </Button>
        </div>
      </Col>
    </Row>
  );
}
Example #12
Source File: create.tsx    From erda-ui with GNU Affero General Public License v3.0 4 votes vote down vote up
CreateTestReport = () => {
  const [{ projectId }] = routeInfoStore.useStore((s) => [s.params, s.query]);
  const [form] = Form.useForm();
  const saving = saveTestReport.useLoading();
  const [{ testDashboard, issueDashboard, chosenIterationID }, updater] = useUpdate<IState>({
    testDashboard: null,
    issueDashboard: null,
    chosenIterationID: '',
  });

  const onClick = () => {
    form.validateFields().then((res) => {
      saveTestReport
        .fetch({
          projectId,
          ...res,
          iterationID: +res.iterationID,
          reportData: {
            'issue-dashboard': issueDashboard,
            'test-dashboard': testDashboard,
          },
        })
        .then(() => {
          goTo('../');
        });
    });
  };

  const changeIteration = (v: string) => {
    updater.chosenIterationID(v);
  };

  const inParams = { projectId };
  // TODO: better add a iterationID inparams; need backend support
  if (chosenIterationID) {
    inParams.filter__urlQuery = encode(`{"iteration":[${chosenIterationID}]}`);
  }

  const handleDashboardFilter = (data: Obj) => {
    return produce(data, (draft) => {
      const conditions = draft.protocol?.components?.filter?.state?.conditions || [];
      const reConditions = conditions.map((cond: Obj) => {
        if (cond.key === 'iteration') {
          return { ...cond, disabled: true };
        }
        return cond;
      });
      set(draft, 'protocol.components.filter.state.conditions', reConditions);
    });
  };

  return (
    <div>
      <TopButtonGroup>
        <Button type="primary" onClick={onClick} loading={saving}>
          {i18n.t('dop:Generate Test Report')}
        </Button>
      </TopButtonGroup>
      <div className="bg-white rounded p-2">
        <Form className="w-3/5" layout="vertical" form={form}>
          <Form.Item label={i18n.t('cmp:name-report')} name="name" rules={[{ required: true }]}>
            <Input />
          </Form.Item>
          <Form.Item label={i18n.t('dop:iteration')} name="iterationID" rules={[{ required: true }]}>
            <IterationSelect onChange={changeIteration} autoSelectFirst disabledBacklog />
          </Form.Item>
          <Form.Item label={i18n.t('dop:Test summary')} name="summary" rules={[{ required: true }]}>
            <MarkdownEditor />
          </Form.Item>
        </Form>
      </div>
      {chosenIterationID ? (
        <div key={chosenIterationID}>
          <Title title={i18n.t('dop:Test statistics')} />
          <DiceConfigPage
            scenarioType={'test-dashboard'}
            scenarioKey={'test-dashboard'}
            fullHeight={false}
            updateConfig={(v) => {
              updater.testDashboard(handleDashboardFilter(v));
            }}
            debugConfig={testDashboard}
            inParams={inParams}
          />

          <Title title={i18n.t('dop:Test statistics')} />
          <DiceConfigPage
            scenarioType={'issue-dashboard'}
            scenarioKey={'issue-dashboard'}
            inParams={inParams}
            fullHeight={false}
            debugConfig={issueDashboard}
            updateConfig={(v) => {
              updater.issueDashboard(handleDashboardFilter(v));
            }}
          />
        </div>
      ) : null}
    </div>
  );
}