lodash#floor TypeScript Examples

The following examples show how to use lodash#floor. 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: Section.tsx    From dnde with GNU General Public License v3.0 6 votes vote down vote up
Generator = ({ length }: { length: number }) => {
  let content = [];
  const flexGrow = floor(100 / length);

  for (let i = 0; i < length; i++) {
    content.push(
      <div
        key={i + flexGrow}
        style={{
          display: 'flex',
          flexGrow,
          height: '16px',
          borderRight: i === length - 1 ? '' : '1px solid rgb(85, 85, 85)',
          borderRadius: '0px',
        }}
      ></div>
    );
  }
  return <>{content}</>;
}
Example #2
Source File: eventElementRelation.ts    From dnde with GNU General Public License v3.0 6 votes vote down vote up
closeToTopOrBottom = (event: any, target: HTMLElement) => {
  const pos = target.getBoundingClientRect();
  const eventY = event.clientY;

  if (isEventWithTargetElement(event, target)) {
    const middle = floor((pos.bottom - pos.top) / 2) + pos.top;
    if (eventY < middle) {
      return 'top';
    } else if (eventY > middle) {
      return 'bottom';
    }
  }

  return false;
}
Example #3
Source File: setToolbarPositions.ts    From dnde with GNU General Public License v3.0 6 votes vote down vote up
setToolBars = ({ pos, delete: { setDelX, setDelY }, copy: { setCopyX, setCopyY } }: SetToolBarsProps) => {
  const IconSize = 32;
  const numberOfIcons = 2 * IconSize;
  if (pos) {
    setDelX(pos.right + 4);
    const middle = floor((pos.bottom - pos.top) / 2) - numberOfIcons / 2;
    setDelY(pos.top + middle);
    setCopyX(pos.right + 4);
    // below the delete icon, with a little offset
    setCopyY(pos.top + middle + IconSize + 4);
  }
}
Example #4
Source File: test-list.tsx    From erda-ui with GNU Affero General Public License v3.0 6 votes vote down vote up
ExecuteResult = ({ totals }: { totals: { tests: number; statuses: TEST.Statuses } }) => {
  if (!totals) {
    return null;
  }
  const { failed, error, passed, skipped } = totals.statuses;
  const { tests } = totals;
  const passedPercent = tests ? floor(((passed + skipped) * 100) / tests, 2) : 0;
  const title = (
    <div>
      <div>
        {i18n.t('failed')}: {failed}
      </div>
      <div>
        {i18n.t('Error')}: {error}
      </div>
      <div>
        {i18n.t('dop:pass')}: {passed}
      </div>
      <div>
        {i18n.t('dop:Skipped')}: {skipped}
      </div>
    </div>
  );
  return (
    <Tooltip title={title} placement="right">
      <Progress
        percent={100}
        success={{
          percent: passedPercent,
        }}
        strokeColor={themeColor['default-02']}
        format={(_percent: number, successPercent: number) => `${Math.floor(successPercent)}%`}
      />
    </Tooltip>
  );
}
Example #5
Source File: test-list.tsx    From erda-ui with GNU Affero General Public License v3.0 6 votes vote down vote up
CodeCoverage = ({ data }: { data: Array<{ value: number[] }> }) => {
  let rowsTotal = 0;
  let rowsCover = 0;

  data.forEach((item) => {
    rowsTotal += item.value[0] || 0;
    rowsCover += item.value[9] || 0;
  });

  const percent = rowsTotal ? +((rowsCover * 100) / rowsTotal).toFixed(2) : 0;

  const title = (
    <>
      <div>
        {i18n.t('dop:Total number of rows')}: {rowsTotal}
      </div>
      <div>
        {i18n.t('dop:Covering the number of rows')}: {rowsCover}
      </div>
      <div>
        {i18n.t('dop:Line coverage')}: {percent}%
      </div>
    </>
  );
  return (
    <Tooltip title={title} placement="right">
      <Progress
        percent={100}
        success={{
          percent: percent,
        }}
        strokeColor={themeColor['default-02']}
        format={(_percent: number, successPercent: number) => `${Math.floor(successPercent)}%`}
      />
    </Tooltip>
  );
}
Example #6
Source File: test-list.tsx    From erda-ui with GNU Affero General Public License v3.0 5 votes vote down vote up
getTestDuration = (duration: any) => {
  const seconds = floor(parseInt(duration, 10) / 10 ** 9, 3); // 时间为纳秒
  return duration !== 0 && seconds === 0
    ? `${duration / 1000000} ${i18n.t('dop:millisecond(s)')}`
    : secondsToTime(seconds, true);
}
Example #7
Source File: chartMap.ts    From erda-ui with GNU Affero General Public License v3.0 5 votes vote down vote up
chartMap = merge(
  {
    sortTab: sortCreator(commonAttr.moduleName, 'sortTab'),
    sortList: {
      ...commonAttr,
      type: 'sortList',
      chartName: 'sortList',
    },
    performanceInterval: {
      ...commonAttr,
      titleText: i18n.t('Performance range'),
      chartName: 'performanceInterval',
    },
    pagePerformanceTrends: {
      ...commonAttr,
      titleText: i18n.t('msp:performance trend'),
      chartName: 'performanceTrends',
    },
    regionalLoadingTime: {
      titleText: i18n.t('msp:regional average load time'),
      ...commonAttr,
      chartName: 'geography-china',
      viewType: 'map',
      viewProps: {
        mapData: ChinaMap,
        formatter(params: any) {
          const data = params.data || {};
          if (!data) return `${data.name}`;
          if (!data.name) return null;
          const tps = data.tps ? `${floor(data.tps, 3)} cpm` : i18n.t('msp:No data');
          const time = data.value ? `${floor(data.value, 3)} s` : i18n.t('msp:No data');
          return `${data.name} <br /> 吞吐量: ${tps} <br /> ${i18n.t('msp:average load time')}: ${time}`;
        },
      },
    },
    slowTrack: {
      titleText: i18n.t('msp:slow loading tracking'),
      ...commonAttr,
      chartName: 'slow',
      viewRender: SlowTrack,
    },
  },
  ApiMap,
)
Example #8
Source File: sort-list.tsx    From erda-ui with GNU Affero General Public License v3.0 5 votes vote down vote up
SortList = (props: IProps) => {
  const { onClickItem, data } = props;

  const { loading, list } = data || {};
  const [chosen, setChosen] = React.useState('');

  const handleClick = (name: string) => {
    if (onClickItem) {
      setChosen(name);
    }
  };

  const handleClose = (e?: any) => {
    e && e.stopPropagation();
    setChosen('');
  };

  React.useEffect(() => {
    onClickItem && onClickItem(chosen);
  }, [chosen, onClickItem]);

  const renderList = (dataList: IData[]) => {
    if (dataList && dataList.length) {
      return map(dataList, (item, index) => {
        const { name, value, unit } = item;
        let background = {};
        const isChosen = chosen === name;
        if (!isChosen && unit === '%') {
          background = {
            background: `linear-gradient(to right, rgba(146, 225, 255, 0.34) ${value}%, #ECEEF6 ${value}%)`,
          };
        }
        return (
          <Tooltip key={index} title={name} placement="right" overlayClassName="tooltip-word-break">
            <li
              onClick={() => handleClick(name)}
              className={`sort-list-item ${isChosen ? 'active' : ''} ${onClickItem === null ? '' : 'cursor-pointer'}`}
              style={background}
            >
              <span className="name">
                {index + 1}. {name}
              </span>
              <span className="value">{`${floor(value as number, 2)} ${unit}`}</span>
              {isChosen ? <CustomIcon className="close-icon" type="guanbi-fill" onClick={handleClose} /> : null}
            </li>
          </Tooltip>
        );
      });
    }
    return <EmptyHolder />;
  };

  return (
    <Spin spinning={loading}>
      <ul className="topn-list">{renderList(list)}</ul>
    </Spin>
  );
}
Example #9
Source File: test-detail.tsx    From erda-ui with GNU Affero General Public License v3.0 4 votes vote down vote up
render() {
    const { checkedCaseKey, filterKey, suite, filterList } = this.state;
    const { totals, extra } = suite;
    const statuses = totals ? totals.statuses : {};
    const checkedTestCase = find(filterList, { key: checkedCaseKey }) || null;

    const result = map(statuses, (v, k) => ({ name: k, type: k, value: v }));
    const pieChartData = {
      loading: false,
      result,
    };
    const dataSource = map(extra, (v, k) => ({ env: k, value: v }));
    const cols = [
      {
        title: '',
        dataIndex: 'env',
      },
      {
        title: '',
        dataIndex: 'value',
        className: 'env-value',
      },
    ];
    const statusFilter = [
      { name: i18n.t('dop:All'), value: 'all', color: 'all' },
      { name: i18n.t('dop:pass'), value: 'passed', color: 'passed' },
      { name: i18n.t('dop:Skipped'), value: 'skipped', color: 'skipped' },
      { name: i18n.t('failed'), value: 'failed', color: 'failed' },
      { name: i18n.t('Error'), value: 'error', color: 'error' },
    ];
    statusFilter.forEach((i) => (i.name = firstCharToUpper(i.name)));
    return (
      <div className="application-test-detail">
        <div className="row-space" />
        <Row>
          <Col span={12} className="test-chart-container">
            <ChartContainer title={i18n.t('dop:Use case statistics')}>
              <TestPieChart data={pieChartData} />
            </ChartContainer>
          </Col>
          <Col span={12} className="test-env-container">
            <ChartContainer title={firstCharToUpper(i18n.t('test environment'))}>
              <Table
                loading={false}
                dataSource={dataSource}
                columns={cols}
                rowKey="env"
                showHeader={false}
                pagination={false}
                scroll={{ x: '100%' }}
              />
            </ChartContainer>
          </Col>
        </Row>
        <div className="row-space" />
        <Row className="test-detail-row">
          <Col span={8} className="test-list-container">
            <ChartContainer title={i18n.t('dop:Test case')}>
              <div className="filter">
                <Search
                  placeholder={i18n.t('dop:enter to filter use cases')}
                  onChange={(e) => this.onSearchKeyChange(e.target.value)}
                />
                <Select value={filterKey} onChange={this.changeFilterKey}>
                  {map(statusFilter, (item) => {
                    return (
                      <Option key={item.name} value={item.value}>
                        <span className="point-wrap">{item.name}</span>
                      </Option>
                    );
                  })}
                </Select>
              </div>
              <ul className="unit-test-list">
                {map(filterList, (item) => {
                  const { name, status, duration, key, classname } = item;
                  const seconds = floor(parseInt(duration, 10) / 10 ** 9, 2); // duration为纳秒
                  return (
                    <Tooltip
                      key={key}
                      placement="right"
                      title={name.length > 50 ? name : undefined}
                      overlayInnerStyle={{ width: '500px', fontSize: '12px' }}
                    >
                      <li
                        className={`test-item flex items-center ${key === checkedCaseKey ? 'active' : ''} ${status}`}
                        onClick={(e) => this.showTestInfo(key, e)}
                      >
                        <span className={`status-point ${status}`} />
                        <div className="flex-1 mx-2 truncate">
                          <div className="text-desc truncate">{classname}</div>
                          <div className="truncate">{name.slice(0, 100)}</div>
                        </div>
                        <span className="time nowrap">
                          {duration !== 0 && seconds === 0
                            ? `${duration / 1000000}${i18n.t('dop:millisecond(s)')}`
                            : secondsToTime(seconds, true)}
                        </span>
                      </li>
                    </Tooltip>
                  );
                })}
                {filterList.length === 0 && <li className="test-item-nodata">{i18n.t('dop:no matching data')}</li>}
              </ul>
            </ChartContainer>
          </Col>
          <Col span={16} className="test-output-container">
            <ChartContainer title={i18n.t('dop:Test output')}>
              {this.renderTestInfo(checkedTestCase as ITest)}
            </ChartContainer>
          </Col>
        </Row>
      </div>
    );
  }
Example #10
Source File: status.tsx    From erda-ui with GNU Affero General Public License v3.0 4 votes vote down vote up
Status = () => {
  const query = routeInfoStore.useStore((s) => s.query);
  const dashboard = monitorStatusStore.useStore((s) => s.dashboard);
  const [isFetchingList] = useLoading(monitorStatusStore, ['getProjectDashboard']);
  const { getProjectDashboard, deleteMetric } = monitorStatusStore.effects;
  const { clearDashboardInfo } = monitorStatusStore.reducers;

  const { type = 'All' } = query || {};

  const [{ modalVisible, formData, filterType }, updater, update] = useUpdate({
    modalVisible: false,
    formData: null as MONITOR_STATUS.IMetricsBody | null,
    filterType: type,
  });

  useEffectOnce(() => {
    getProjectDashboard();
    return () => {
      clearDashboardInfo();
    };
  });

  const toggleModal = (_data?: MONITOR_STATUS.IMetricsBody) => {
    update({
      modalVisible: !modalVisible,
      formData: _data,
    });
  };

  const handleEdit = (_data: MONITOR_STATUS.IMetricsBody) => {
    toggleModal(_data);
  };

  const handleDelete = (id: string) => {
    Modal.confirm({
      title: i18n.t('msp:are you sure to delete this monitor?'),
      onOk: () => {
        deleteMetric(id).then(() => {
          getProjectDashboard();
        });
      },
    });
  };

  const handleDetailClick = (e: any, path: string) => {
    e.stopPropagation();
    goTo(path);
  };

  let data = [] as any[];
  if (dashboard && dashboard.metrics) {
    const curMetrics = dashboard.metrics;
    data = reverse(Object.keys(curMetrics)).map((id) => {
      return {
        id,
        ...(curMetrics[id] || {}),
      };
    });
  }
  let filterData = data;
  if (filterType !== 'All') {
    filterData = filter(filterData, (item) => item.status === filterType);
  }

  const typeMap = {
    All: {
      text: i18n.t('msp:All'),
      status: 'success',
      color: 'green',
    },
    Operational: {
      text: i18n.t('msp:Normal'),
      status: 'success',
      color: 'green',
    },
    'Major Outage': {
      text: i18n.t('msp:Downtime'),
      status: 'error',
      color: 'red',
    },
    Miss: {
      text: i18n.t('msp:No data'),
      status: 'default',
      color: 'grey',
    },
  };

  const defaultMap = {
    text: i18n.t('msp:No data'),
    color: 'grey',
  };

  const columns = [
    {
      title: i18n.t('msp:Index'),
      dataIndex: 'name',
    },
    {
      title: i18n.t('Status'),
      dataIndex: 'status',
      render: (status: string) => (
        <>
          <Badge status={(typeMap[status] || defaultMap).status} text={(typeMap[status] || defaultMap).text} />
        </>
      ),
    },
    {
      title: i18n.t('msp:Online rate'),
      dataIndex: 'uptime',
    },
    {
      title: `${i18n.t('msp:Downtime')}(${i18n.t('msp:last one hour')})`,
      dataIndex: 'downDuration',
    },
    {
      title: 'Apdex',
      dataIndex: 'apdex',
      render: (text: string) => text && floor(+text, 2),
    },
    {
      title: i18n.t('msp:Average response time'),
      dataIndex: 'latency',
      render: (text: string) => <span>{text} ms</span>,
    },
    {
      title: `${i18n.t('msp:response graph')}(${i18n.t('msp:last one hour')})`,
      dataIndex: 'chart',
      width: 160,
      render: (_text: string, record: MONITOR_STATUS.IMetricsBody) => {
        const { chart } = record;
        if (!chart) {
          return <div style={{ height: '58px' }} />;
        }
        return (
          <div>
            <StatusChart
              xAxisData={chart.time}
              data={chart.latency}
              style={{ width: '120px', height: '40px', minHeight: 0 }}
            />
            <ul className="status-list">
              {chart.status.map((item: string, i: number) => (
                <li key={String(i)} className={typeMap[item].color} />
              ))}
            </ul>
          </div>
        );
      },
    },
    {
      title: i18n.t('msp:Root cause analysis'),
      dataIndex: 'requestId',
      width: 90,
      hidden: true,
      render: (requestId: string) =>
        !!requestId && (
          <span
            className="reason-analysis-span"
            onClick={(e) => {
              handleDetailClick(e, resolvePath(`../error/request-detail/${requestId}`));
            }}
          >
            {i18n.t('msp:details')}
          </span>
        ),
    },
  ];

  const actions: IActions<MONITOR_STATUS.IMetricsBody> = {
    render: (record: MONITOR_STATUS.IMetricsBody) => renderMenu(record),
  };

  const renderMenu = (record: MONITOR_STATUS.IMetricsBody) => {
    const { editMonitor, deleteMonitor } = {
      editMonitor: {
        title: i18n.t('Edit'),
        onClick: () => handleEdit(record),
      },
      deleteMonitor: {
        title: i18n.t('Delete'),
        onClick: () => handleDelete(record.id),
      },
    };

    return [editMonitor, deleteMonitor];
  };
  let hasDown: { text: string; type: 'info' | 'error' | 'success' } = {
    text: 'No data',
    type: 'info',
  };
  if (dashboard.downCount !== undefined) {
    hasDown =
      dashboard.downCount > 0
        ? { text: `${dashboard.downCount} Down`, type: 'error' }
        : { text: 'All up', type: 'success' };
  }

  return (
    <div className="project-status-page">
      <TopButtonGroup>
        <Button className="add-button" type="primary" onClick={() => toggleModal()}>
          {i18n.t('msp:Add Monitoring')}
        </Button>
      </TopButtonGroup>
      <ErdaAlert className="erda-alert mb-2" message={hasDown.text} type={hasDown.type} closeable={false} />
      <RadioTabs
        className="mb-2"
        onChange={updater.filterType}
        defaultValue={filterType}
        options={map(typeMap, (item, key) => ({ value: key, label: item.text }))}
      />
      <AddModal
        modalVisible={modalVisible}
        toggleModal={toggleModal}
        formData={formData}
        afterSubmit={getProjectDashboard}
      />
      <Table
        rowKey="id"
        onRow={(record) => {
          return {
            onClick: () => goTo(`./${record.id}`),
          };
        }}
        actions={actions}
        loading={isFetchingList}
        columns={columns}
        dataSource={filterData}
        onChange={() => getProjectDashboard()}
      />
    </div>
  );
}
Example #11
Source File: TenantSizeResources.tsx    From console with GNU Affero General Public License v3.0 4 votes vote down vote up
TenantSizeResources = ({
  classes,
}: // updateAddField,
// isPageValid,

ITenantSizeResourcesProps) => {
  const dispatch = useDispatch();

  const nodes = useSelector(
    (state: AppState) => state.createTenant.fields.tenantSize.nodes
  );

  const resourcesSize = useSelector(
    (state: AppState) => state.createTenant.fields.tenantSize.resourcesSize
  );
  const selectedStorageClass = useSelector(
    (state: AppState) =>
      state.createTenant.fields.nameTenant.selectedStorageClass
  );
  const maxCPUsUse = useSelector(
    (state: AppState) => state.createTenant.fields.tenantSize.maxCPUsUse
  );
  const maxMemorySize = useSelector(
    (state: AppState) => state.createTenant.fields.tenantSize.maxMemorySize
  );

  const resourcesSpecifyLimit = useSelector(
    (state: AppState) =>
      state.createTenant.fields.tenantSize.resourcesSpecifyLimit
  );

  const resourcesCPURequestError = useSelector(
    (state: AppState) =>
      state.createTenant.fields.tenantSize.resourcesCPURequestError
  );
  const resourcesCPURequest = useSelector(
    (state: AppState) =>
      state.createTenant.fields.tenantSize.resourcesCPURequest
  );
  const resourcesCPULimitError = useSelector(
    (state: AppState) =>
      state.createTenant.fields.tenantSize.resourcesCPULimitError
  );
  const resourcesCPULimit = useSelector(
    (state: AppState) => state.createTenant.fields.tenantSize.resourcesCPULimit
  );

  const resourcesMemoryRequestError = useSelector(
    (state: AppState) =>
      state.createTenant.fields.tenantSize.resourcesMemoryRequestError
  );
  const resourcesMemoryRequest = useSelector(
    (state: AppState) =>
      state.createTenant.fields.tenantSize.resourcesMemoryRequest
  );
  const resourcesMemoryLimitError = useSelector(
    (state: AppState) =>
      state.createTenant.fields.tenantSize.resourcesMemoryLimitError
  );
  const resourcesMemoryLimit = useSelector(
    (state: AppState) =>
      state.createTenant.fields.tenantSize.resourcesMemoryLimit
  );

  // Common
  const updateField = useCallback(
    (field: string, value: any) => {
      dispatch(
        updateAddField({
          pageName: "tenantSize",
          field: field,
          value: value,
        })
      );
    },
    [dispatch]
  );

  /*Debounce functions*/

  useEffect(() => {
    dispatch(
      isPageValid({
        pageName: "tenantSize",
        valid:
          resourcesMemoryRequestError === "" &&
          resourcesMemoryLimitError === "" &&
          resourcesCPURequestError === "" &&
          resourcesCPULimitError === "",
      })
    );
  }, [
    dispatch,
    resourcesMemoryRequestError,
    resourcesMemoryLimitError,
    resourcesCPURequestError,
    resourcesCPULimitError,
  ]);

  /*End debounce functions*/

  /*Calculate Allocation*/
  useEffect(() => {
    // Get allocatable Resources
    api
      .invoke("GET", `api/v1/cluster/allocatable-resources?num_nodes=${nodes}`)
      .then((res: AllocableResourcesResponse) => {
        updateField("maxAllocatableResources", res);

        const maxAllocatableResources = res;

        const memoryExists = get(
          maxAllocatableResources,
          "min_allocatable_mem",
          false
        );

        const cpuExists = get(
          maxAllocatableResources,
          "min_allocatable_cpu",
          false
        );

        if (memoryExists === false || cpuExists === false) {
          updateField("cpuToUse", 0);

          updateField("maxMemorySize", "");
          updateField("maxCPUsUse", "");

          return;
        }

        const maxMemory = floor(
          res.mem_priority.max_allocatable_mem / 1024 / 1024 / 1024
        );
        // We default to Best CPU Configuration
        updateField("maxMemorySize", maxMemory.toString());
        updateField(
          "maxCPUsUse",
          res.cpu_priority.max_allocatable_cpu.toString()
        );

        const maxAllocatableCPU = get(
          maxAllocatableResources,
          "cpu_priority.max_allocatable_cpu",
          0
        );

        const baseCpuUse = Math.max(1, floor(maxAllocatableCPU / 2));
        if (resourcesCPURequest === "") {
          updateField("resourcesCPURequest", baseCpuUse);
        }

        const baseMemoryUse = Math.max(2, floor(maxMemory / 2));
        if (resourcesMemoryRequest === "") {
          updateField("resourcesMemoryRequest", baseMemoryUse);
        }
      })
      .catch((err: any) => {
        updateField("maxMemorySize", 0);
        updateField("resourcesCPURequest", "");
        updateField("resourcesMemoryRequest", "");

        console.error(err);
      });
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [nodes, updateField]);

  /*Calculate Allocation End*/

  return (
    <Fragment>
      <Grid item xs={12}>
        <div className={classes.headerElement}>
          <h3 className={classes.h3Section}>Resources</h3>
          <span className={classes.descriptionText}>
            You may specify the amount of CPU and Memory that MinIO servers
            should reserve on each node.
          </span>
        </div>
      </Grid>
      {resourcesSize.error !== "" && (
        <Grid item xs={12}>
          <div className={classes.error}>{resourcesSize.error}</div>
        </Grid>
      )}

      <Grid item xs={12} className={classes.formFieldRow}>
        <InputBoxWrapper
          label={"CPU Request"}
          id={"resourcesCPURequest"}
          name={"resourcesCPURequest"}
          onChange={(e) => {
            let value = parseInt(e.target.value);
            if (e.target.value === "") {
              updateField("resourcesCPURequestError", "");
            } else if (isNaN(value)) {
              updateField("resourcesCPURequestError", "Invalid number");
            } else if (value > parseInt(maxCPUsUse)) {
              updateField(
                "resourcesCPURequestError",
                `Request exceeds available cores (${maxCPUsUse})`
              );
            } else if (e.target.validity.valid) {
              updateField("resourcesCPURequestError", "");
            } else {
              updateField("resourcesCPURequestError", "Invalid configuration");
            }
            updateField("resourcesCPURequest", e.target.value);
          }}
          value={resourcesCPURequest}
          disabled={selectedStorageClass === ""}
          max={maxCPUsUse}
          error={resourcesCPURequestError}
          pattern={"[0-9]*"}
        />
      </Grid>

      <Grid item xs={12} className={classes.formFieldRow}>
        <InputBoxWrapper
          id="resourcesMemoryRequest"
          name="resourcesMemoryRequest"
          onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
            let value = parseInt(e.target.value);
            if (e.target.value === "") {
              updateField("resourcesMemoryRequestError", "");
            } else if (isNaN(value)) {
              updateField("resourcesMemoryRequestError", "Invalid number");
            } else if (value > parseInt(maxMemorySize)) {
              updateField(
                "resourcesMemoryRequestError",
                `Request exceeds available memory across ${nodes} nodes (${maxMemorySize}Gi)`
              );
            } else if (value < 2) {
              updateField(
                "resourcesMemoryRequestError",
                "At least 2Gi must be requested"
              );
            } else if (e.target.validity.valid) {
              updateField("resourcesMemoryRequestError", "");
            } else {
              updateField(
                "resourcesMemoryRequestError",
                "Invalid configuration"
              );
            }
            updateField("resourcesMemoryRequest", e.target.value);
          }}
          label="Memory Request"
          overlayObject={
            <InputUnitMenu
              id={"size-unit"}
              onUnitChange={() => {}}
              unitSelected={"Gi"}
              unitsList={[{ label: "Gi", value: "Gi" }]}
              disabled={true}
            />
          }
          value={resourcesMemoryRequest}
          disabled={selectedStorageClass === ""}
          error={resourcesMemoryRequestError}
          pattern={"[0-9]*"}
        />
      </Grid>

      <Grid item xs={12}>
        <FormSwitchWrapper
          value="resourcesSpecifyLimit"
          id="resourcesSpecifyLimit"
          name="resourcesSpecifyLimit"
          checked={resourcesSpecifyLimit}
          onChange={(e) => {
            const targetD = e.target;
            const checked = targetD.checked;

            updateField("resourcesSpecifyLimit", checked);
          }}
          label={"Specify Limit"}
        />
      </Grid>

      {resourcesSpecifyLimit && (
        <Fragment>
          <Grid item xs={12} className={classes.formFieldRow}>
            <InputBoxWrapper
              label={"CPU Limit"}
              id={"resourcesCPULimit"}
              name={"resourcesCPULimit"}
              onChange={(e) => {
                let value = parseInt(e.target.value);
                if (e.target.value === "") {
                  updateField("resourcesCPULimitError", "");
                } else if (isNaN(value)) {
                  updateField("resourcesCPULimitError", "Invalid number");
                } else if (e.target.validity.valid) {
                  updateField("resourcesCPULimitError", "");
                } else {
                  updateField(
                    "resourcesCPULimitError",
                    "Invalid configuration"
                  );
                }
                updateField("resourcesCPULimit", e.target.value);
              }}
              value={resourcesCPULimit}
              disabled={selectedStorageClass === ""}
              max={maxCPUsUse}
              error={resourcesCPULimitError}
              pattern={"[0-9]*"}
            />
          </Grid>

          <Grid item xs={12} className={classes.formFieldRow}>
            <InputBoxWrapper
              id="resourcesMemoryLimit"
              name="resourcesMemoryLimit"
              onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
                let value = parseInt(e.target.value);
                if (e.target.value === "") {
                  updateField("resourcesMemoryLimitError", "");
                } else if (isNaN(value)) {
                  updateField("resourcesMemoryLimitError", "Invalid number");
                } else if (e.target.validity.valid) {
                  updateField("resourcesMemoryLimitError", "");
                } else {
                  updateField(
                    "resourcesMemoryLimitError",
                    "Invalid configuration"
                  );
                }
                updateField("resourcesMemoryLimit", e.target.value);
              }}
              label="Memory Limit"
              overlayObject={
                <InputUnitMenu
                  id={"size-unit"}
                  onUnitChange={() => {}}
                  unitSelected={"Gi"}
                  unitsList={[{ label: "Gi", value: "Gi" }]}
                  disabled={true}
                />
              }
              value={resourcesMemoryLimit}
              disabled={selectedStorageClass === ""}
              error={resourcesMemoryLimitError}
              pattern={"[0-9]*"}
            />
          </Grid>
        </Fragment>
      )}
    </Fragment>
  );
}
Example #12
Source File: index.tsx    From nebula-studio with Apache License 2.0 4 votes vote down vote up
TaskItem = (props: IProps) => {
  const { 
    data: { 
      space,
      id, 
      name, 
      stats: { totalImportedBytes, totalBytes, numFailed, numReadFailed }, 
      status, 
      message,
      updateTime, 
      createTime 
    }, 
    showConfigDownload,
    onViewLog,
    onConfigDownload,
    onTaskStop, 
    onTaskDelete } = props;
  const [progressStatus, setStatus] = useState<'success' | 'active' | 'normal' | 'exception' | undefined>(undefined);
  const [extraMsg, setExtraMsg] = useState('');
  const addMsg = () => {
    const info: string[] = [];
    if(numFailed > 0) {
      info.push(intl.get('import.notImported', { total: numFailed }));
    }
    if(numReadFailed > 0) {
      info.push(intl.get('import.readFailed', { total: numReadFailed }));
    }
    info.length > 0 && setExtraMsg(info.join(', '));
  };
  useEffect(() => {
    if(status === ITaskStatus.StatusFinished) {
      setStatus('success');
      addMsg();
    } else if(status === ITaskStatus.StatusProcessing) {
      setStatus('active');
      addMsg();
    } else {
      setStatus('exception');
      if(message) {
        setExtraMsg(message);
      }
    }
  }, [status]);
  return (
    <div className={styles.taskItem}>
      <div className={styles.row}>
        <span>{intl.get('common.space')}: {space}</span>
        {showConfigDownload && <Button type="link" size="small" onClick={() => onConfigDownload(id)}>
          <Icon type="icon-studio-btn-download" />
          {intl.get('import.downloadConfig')}
        </Button>}
      </div>
      <div className={styles.row}>
        <div className={styles.progress}>
          <div className={styles.progressInfo}>
            <span className={styles.taskName}>
              {name}
              {status === ITaskStatus.StatusFinished && <span className={styles.completeInfo}>
                <CheckCircleFilled />
                {intl.get('import.importCompleted')}
                <span className={styles.red}>{extraMsg && ` (${extraMsg})`}</span>
              </span>}
              {status === ITaskStatus.StatusAborted && <span className={styles.errInfo}>
                {intl.get('import.importFailed')}
                {extraMsg && ` (${extraMsg})`}
              </span>}
              {status === ITaskStatus.StatusStoped && <span className={styles.errInfo}>
                {intl.get('import.importStopped')}
              </span>}
            </span>
            <div className={styles.moreInfo}>
              <span>
                {status !== ITaskStatus.StatusFinished && `${getFileSize(totalImportedBytes)} / `}
                {getFileSize(totalBytes)}{' '}
              </span>
              <span>{dayjs.duration(dayjs.unix(updateTime).diff(dayjs.unix(createTime))).format('HH:mm:ss')}</span>
            </div>
          </div>
          <Progress 
            format={percent => `${percent}%`}
            status={progressStatus} 
            percent={status !== ITaskStatus.StatusFinished ? floor(totalImportedBytes / totalBytes * 100, 2) : 100} 
            strokeColor={progressStatus && COLOR_MAP[progressStatus]} />
        </div>
        <div className={styles.operations}>
          <Button className="primaryBtn" onClick={() => onViewLog(id, space, status)}>{intl.get('import.viewLogs')}</Button>
          {status === ITaskStatus.StatusProcessing && 
          <Popconfirm
            placement="left"
            title={intl.get('import.endImport')}
            onConfirm={() => onTaskStop(id)}
            okText={intl.get('common.confirm')}
            cancelText={intl.get('common.cancel')}
          >
            <Button className="cancelBtn">{intl.get('import.endImport')}</Button>
          </Popconfirm>}
          {status !== ITaskStatus.StatusProcessing && 
          <Popconfirm
            placement="left"
            title={intl.get('common.ask')}
            onConfirm={() => onTaskDelete(id)}
            okText={intl.get('common.confirm')}
            cancelText={intl.get('common.cancel')}
          >
            <Button danger={true}>{intl.get('common.delete')}</Button>
          </Popconfirm>}
        </div>
      </div>
    </div>
  );
}