// Copyright 2021 99cloud // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. import { isNil, isString, isUndefined, isNumber, isNaN, isArray, unescape, } from 'lodash'; import { customAlphabet } from 'nanoid'; import { getLocalTimeStr, getKeepTime, getSinceTime } from './time'; import { SIZE_VALUE, MILLISECOND_IN_TIME_UNIT } from './constants'; /** * format size, output the value with unit * @param {Number} size - the number need to be format */ export const formatSize = (size, start = 0) => { const divisor = 1024; const units = [ 'B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB', 'BiB', ]; let index = isNumber(start) ? start : 0; if (!isNumber(size) || isNaN(size)) { return size || '-'; } while (size >= divisor && index < units.length - 1) { size = parseFloat(size / divisor).toFixed(2); index += 1; } if (index === 0) { size = parseInt(size, 10); } return `${size} ${units[index]}`; }; /** * format used time(ms). * @param {Number} ms */ export const formatUsedTime = (ms) => { const { s, m, h, d, w } = MILLISECOND_IN_TIME_UNIT; if (ms < s) { return `${ms} ms`; } if (ms <= m) { return `${parseFloat(ms / s).toFixed(2)} s`; } if (ms <= h) { return `${parseFloat(ms / m).toFixed(2)} min`; } if (ms <= d) { return `${parseFloat(ms / h).toFixed(2)} h`; } if (ms <= w) { return `${parseFloat(ms / d).toFixed(2)} d`; } return `${parseFloat(ms / w).toFixed(2)} w`; }; export const generateId = (length) => customAlphabet('0123456789abcdefghijklmnopqrstuvwxyz', length || 6)(); export const getQueryString = (params) => Object.keys(params) .filter((key) => params[key]) .map((key) => `${key}=${params[key]}`) .join('&'); export const getYesNo = (input) => (input ? t('Yes') : t('No')); export const getGiBValue = (input) => { const gb = 1024; if (isNaN(input) || isNil(input) || !input || !isNumber(input)) { return 0; } return parseFloat(Number(input / gb).toFixed(2)); }; export const getNoValue = (input, def) => { if ( isNil(input) || isUndefined(input) || (isString(input) && input.trim() === '') ) { return def || '-'; } return input; }; export const firstUpperCase = (str) => { if (!isString(str) || str === '') { return str; } const [first, ...rest] = str; return first.toUpperCase() + rest.join(''); }; export const bytesFilter = (input) => { const { kb, mb, gb, tb } = SIZE_VALUE; if (isNaN(input) || isUndefined(input) || input === null || input < 0) { return ''; } if (input >= tb) { const size = Number(input / tb).toFixed(2); return t('{ size } TiB', { size }); } if (input >= gb) { const size = Number(input / gb).toFixed(2); return t('{ size } GiB', { size }); } if (input >= mb) { const size = Number(input / mb).toFixed(2); return t('{ size } MiB', { size }); } if (input >= kb) { const size = Number(input / kb).toFixed(2); return t('{ size } KiB', { size }); } const size = Math.floor(input); return t('{ size } bytes', { size }); }; export const uppercaseFilter = (input) => { if (!input || !isString(input)) { return '-'; } return input.toUpperCase(); }; export const toLocalTimeFilter = (input) => { if (!input) { return '-'; } let dateTime; if (typeof input === 'number') { dateTime = new Date(input); } else { if (!/\+00:00$/.test(input)) { if (!/Z$/.test(input)) { input = input.concat('Z'); } } dateTime = new Date(input); } let format = '%y-%m-%d %H:%M:%S'; const f = { y: dateTime.getYear() + 1900, m: dateTime.getMonth() + 1, d: dateTime.getDate(), H: dateTime.getHours(), M: dateTime.getMinutes(), S: dateTime.getSeconds(), }; Object.keys(f).forEach((timePart) => { format = format.replace( `%${timePart}`, f[timePart] < 10 ? `0${f[timePart]}` : f[timePart] ); }); return format; }; export const renderFilterMap = { sinceTime: getSinceTime, keepTime: getKeepTime, yesNo: getYesNo, GiBValue: getGiBValue, noValue: getNoValue, bytes: bytesFilter, uppercase: uppercaseFilter, formatSize, toLocalTime: toLocalTimeFilter, toLocalTimeMoment: getLocalTimeStr, }; export const getOptions = (obj) => Object.keys(obj).map((key) => ({ label: obj[key], value: key, key, })); export const getYesNoList = () => [ { value: true, label: t('Yes') }, { value: false, label: t('No') }, ]; /** * 生成一个从 start 到 end 的连续数组,左闭右开, * @param start * @param end */ export const generateArray = (start, end) => { const length = Math.abs(start - end); return Array.from(new Array(length).keys()).map((i) => i + start); }; export const NoSetValue = 'noSelect'; export const getOptionsWithNoSet = (options) => { const newOptions = isArray(options) ? options : getOptions(options); const noSet = { value: NoSetValue, label: t('Not select'), }; return [noSet, ...newOptions]; }; export const computePercentage = function (used, total, digits = 2) { if (used === 0) { return 0; } return parseFloat( ((parseFloat(used) / parseFloat(total)) * 100).toFixed(digits) ); }; export const groupArray = (arr, subGroupLength) => { let index = 0; const newArray = []; while (index < arr.length) { newArray.push(arr.slice(index, (index += subGroupLength))); } return newArray; }; export const updateObjToAddSelectArray = (value = {}) => { const values = []; Object.keys(value).forEach((it, index) => { values.push({ index, value: { key: it, value: value[it] }, }); }); return values; }; export const updateAddSelectValueToObj = (arr = []) => { const obj = {}; arr.forEach((it) => { const { key, value } = it.value; if ((isString(value) && value) || !isString(value)) { obj[key] = value; } }); return obj; }; export const unescapeHtml = (message) => { if (isString(message)) { return unescape(message); } return message; }; export const isAdminPage = (url) => url && url.indexOf('admin') >= 0; export const isUserCenterPage = (url) => url && (url === '/user' || url.startsWith('/user/')); export const allSettled = (promises) => { if (!Promise.allSettled) { return Promise.all( promises.map((promise) => promise .then((value) => ({ status: 'fulfilled', value })) .catch((reason) => ({ status: 'rejected', reason })) ) ); } return Promise.allSettled(promises); };