All files / src/config base.ts

91.89% Statements 102/111
63.63% Branches 14/22
41.66% Functions 5/12
98.07% Lines 102/104

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417          78x   78x         78x               78x 168x 168x                           6x 2x       4x 4x 4x 4x   4x                   156x 156x       156x     156x         156x 156x 156x   156x       78x               78x     78x         78x         78x         78x         78x         78x         78x         78x         78x         78x         78x         78x         78x       78x 78x 78x 78x 78x 78x 78x         78x         78x         78x         78x         78x           78x         78x           78x       78x     78x     78x         78x     78x   78x               78x     78x     78x     78x             78x     78x     78x           78x     78x     78x         78x         78x         78x     78x     78x     78x     78x     78x     78x                               78x             78x         78x         78x           78x                   78x                         78x     78x     78x     78x   78x         78x     78x     78x     78x     78x     78x         78x   78x 112x       78x 78x 78x 78x     78x         78x          
import { createFromIconfontCN } from '@ant-design/icons';
import { HttpMethod } from '@props/RecordProps';
import { RoleDomainName, StorageFieldValueDomainName } from '@config/domain';
 
/** 后台地址的后缀(相对于前台地址) */
export const BackendUrlFirstPartSuffix = "-server";
 
export const ServerUrlLocalStorageKey = "backendUrl";
 
/**
 * 特殊的前台地址到后台地址的一个关联表
 */
const FRONT_BACK_HOSTNAME_MAPPING: { [key: string]: string } = {
  "localhost:3000": "http://localhost:8080",
  "localhost": "http://localhost:8080",
  "contract-client.herokuapp.com": "https://contract-server.herokuapp.com",
  "clokmpre.boe.com.cn": "http://clokmpre.boe.com.cn:8080",
  "samt.myddm.com": "http://samt.myddm.com/api",
};
 
export const isIPAddress = (input: string): boolean => {
  const ipAddressRegex = /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
  return ipAddressRegex.test(input);
};
 
/**
 * Get default backend url based on frontend url
 * @param frontendHostname frontend url
 * @param suffix backend url suffix related to frontend url
 * @param protocol protocol of the url
 * @param port port of the url
 */
export function getDefaultBackendUrl(
  frontendHostname: string, suffix: string,
  protocol: string, port: string | null
): string {
  if (frontendHostname == null || frontendHostname === '') {
    return '';
  }
  // For local development environment
  // Frontend on 3000, backend on 8080
  const bp = (port === '3000') ? ':8080' : '';
  const firstPart = frontendHostname?.split(".")?.[0];
  const idxOfDot = frontendHostname?.indexOf(".");
  const otherParts = (idxOfDot === -1) ?
    '' : frontendHostname?.substring(idxOfDot);
  return `${protocol ?? 'https'}://${firstPart}${suffix}${otherParts}${bp}`;
}
 
/**
 * 获取后台系统的地址,按照如如下的优先级进行获取
 * 1. 从 localStorage 中的 backendUrl 变量
 * 2. 从 FRONT_BACK_HOSTNAME_MAPPING mapping中,使用前台的host查找
 * 3. 返回变量 DEFAULT_BACKEND_URL 的值
 */
export function getServerUrl(): string {
  const backendUrlInLocalStorage = localStorage.getItem(ServerUrlLocalStorageKey);
  Iif (backendUrlInLocalStorage != null) {
    return backendUrlInLocalStorage;
  }
 
  const { hostname, protocol, port } = window.location;
 
  // Check if the hostname is an IP address
  Iif (isIPAddress(hostname)) {
    return `${protocol}//${hostname}:8080`;
  }
 
  // http: | https: -> http | https
  const p = protocol.substring(0, protocol.length - 1);
  const backendUrl = FRONT_BACK_HOSTNAME_MAPPING[hostname];
  const bu = backendUrl == null ?
    getDefaultBackendUrl(hostname, BackendUrlFirstPartSuffix, p, port) : backendUrl;
  return bu;
}
 
function getWebSocketUrl(): string {
  return getServerUrl()
    .replace("http://", "ws://")
    .replace("https://", "wss://");
}
 
/**
 * 后台系统的地址
 */
export const SERVER_URL = getServerUrl();
 
/** Websocket 的请求地址 */
export const WEBSOCKET_SERVER_URL = getWebSocketUrl();
 
/**
 * 全文搜索页面默认显示的 card 数量
 */
export const FullTextSearchDefaultPageSize = 10;
 
/**
 * 非Popover中的列表页面默认的分页条数
 */
export const DEFAULT_PAGE_SIZE = 12;
 
/**
 * CardList中的列表页面默认的分页条数
 */
export const DEFAULT_PAGE_SIZE_FOR_CARD_LIST = 8;
 
/**
 * Popover中的列表页面默认的分页条数
 */
export const DRAWER_DEFAULT_PAGE_SIZE = 5;
 
/**
 * Finder 中的列表页面默认的分页条数
 */
export const FINDER_DEFAULT_PAGE_SIZE = 10;
 
/**
 * 在编辑和详情页面中显示的关联对象列表的默认分页条数
 */
export const DETAIL_DEFAULT_PAGE_SIZE = 10;
 
/**
 * 触发请求后台的对象搜索框的自动补全的最少输入长度
 */
export const TRIGGER_SEARCH_MINIMAL_INPUT_LENGTH = 2;
 
/**
 * 触发请求后台的对象搜索框的自动补全的最小时间间隔
 */
export const TRIGGER_SEARCH_MINIMAL_TIME_MS = 500;
 
/**
 * 触发后台背景线程请求后台进行字段校验的最小时间间隔
 */
export const TRIGGER_BACKGROUND_VALIDATION_MINIMAL_TIME_MS = 1000;
 
/**
 * Fields to hide on create page
 */
export const FieldsToHideOnCreatePage = ["id"];
 
/**
 * Fields to hide on edit page
 */
export const FieldsToHideOnEditPage = [];
 
/**
 * 台传递到前台的类型中的列表类型
 */
export const ArrayTypes: string[] = [
  "array", "subTable"
];
 
export const isRoles = (type: string): boolean => ("roles" === type);
export const isCode = (type: string): boolean => ("code" === type);
export const isRelateObjects = (type: string): boolean => (ArrayTypes.includes(type));
export const isDate = (type: string): boolean => ("date" === type || "datetime" === type);
export const isHttpMethod = (type: string): boolean => ("httpMethod" === type);
export const isCheckbox = (type: string): boolean => ("df_checkbox" === type);
export const isStaticField = (type: string): boolean => ("staticField" === type);
 
/**
 * For master-detail data, the width of master section when it's been collapse in edit page
 */
export const MasterCollapseWidth = 36;
 
/**
 * For master-detail data, the width of master section when it's been expanded in edit page
 */
export const MasterExpandWidth = 450;
 
/**
 * Master detail tree list form master part width
 */
export const MasterDetailListMasterTreeWidth = 300;
 
/**
 * Master detail simple list form master part width
 */
export const MasterDetailListMasterListWidth = 350;
 
/**
 * 每次收起或者展开 master 面板,增加或者减少的 px
 */
export const MasterDetailExpandWidth = 50;
 
/**
 * 基础日期格式。年-月-日 时:分:秒
 * 需要显示具体日期与时间时使用
 */
export const DateTimeFormat = "YYYY-MM-DD HH:mm:ss";
/**
 * 基础日期格式。年-月-日
 * 需要显示具体日期时使用
 */
export const DateFormat = "YYYY-MM-DD";
 
/**
 * 基础日期格式。时:分:秒
 * 需要显示具体时间时使用
 */
export const TimeFormat = "HH:mm:ss";
 
 
/** 系统的主色调 */
export const PrimaryColor = "#696AAD";
 
/** 默认文字颜色 */
export const TextColor = "rgba(0, 0, 0, 0.85)";
 
/** 特殊的前台到后台的 type 映射 */
export const SpecialFrontendToBackTypeMapping: { [propName: string]: string } = {
  "roles": RoleDomainName
};
 
/** 附件字段的 Domain 类型 */
export const FileFieldType = StorageFieldValueDomainName;
 
/** Action column 的 key 和 type, 注意不能和后台传递到前台的字段元数据中的 key 重复 */
export const ActionColumnKey = "zz-client-action";
 
export const CsvTemplateAdditionalComments = [
  ["; Lines begin with ; is treated as comment and will be ignored"],
  ["; Please quote each column within \"\"(one quote at the begining, one quote at the end)"],
  ["; Please escape \"(quote) within data using \"\"(two consecutive quotes)"],
  ["; Please leave column id(*) empty for new record"]
];
 
/** Number of lines to preview when import CSV file */
export const NumberOfCsvPreviewLine = 10;
 
/** Max width of the popover panel width when importing csv */
export const CsvOperateComponentPanelMaxWidth = "750px";
 
/** Max width of the action execute result panel width */
export const ActionExecuteResultPanelMaxWidth = "750px";
 
/** 客制化的图标集合,在 www.iconfont.cn 创建 */
export const CustomIcon = createFromIconfontCN({
  scriptUrl: [
    "//at.alicdn.com/t/font_2107988_96pef2tzhmt.js"
  ]
});
 
/** id 列在导出的 CSV 文件中的列头 */
export const IdColumnKeyInCsv = "id(*)";
 
/** id 列的 key */
export const IdColumnKey = "id";
 
/** 在 csv 文件中,使用 "NULL" 来表示空值的列类型列表 */
export const UseNULLForNullValueTypes = [
  'staticField', 'string'
] as Array<string>;
 
 
/** 前台搜索过滤开始执行的最短字符长度 */
export const FilterMinimalKeywordLength = 3;
 
/** 前台搜索的最短时间间隔 */
export const TRIGGER_CLIENT_SIDE_FILTER_MINIMAL_TIME_MS = 250;
 
/** 对单个对象启用的 action 的 scope */
export const ENABLE_SCOPE_FOR_SINGLE_OBJECT = [
  'OBJECT_SINGLE_MULTIPLE', 'OBJECT_SINGLE'
];
 
/** 对多个对象启用的 action 的 scope */
export const ENABLE_SCOPE_FOR_MULTIPLE_OBJECTS = [
  'OBJECT_SINGLE_MULTIPLE', 'OBJECT_MULTIPLE', 'OBJECT_SINGLE'
];
 
/** 只对 Domain Level 启用的 action 的 scope */
export const ENABLE_SCOPE_FOR_CLASS_LEVEL = [
  'CLASS_LEVEL'
];
 
/** Action 执行完成后 UI 页面跳转的等待时间(秒) */
export const ActionRedirectCountdown = 1;
 
/** 是否在 debug console 显示所有 API 请求的回应原始值 */
export const LogApiResponseToConsole = false && (['development', 'test'].includes(process.env.NODE_ENV));
 
/** 默认的字符类型的字段直接显示字符数,超过这个长度的字符会显示为 ... 控件 */
export const MaxTextCellDirectDisplayCharLength = 80;
 
/** Get 请求的缓存时间,单位为秒, 这个时间内的 Get 请求会直接从本地缓存获取 */
export const GetRequestCacheExpirySeconds = 10;
 
/** 如果有相同的 Get 请求,为了避免向服务器重复发送 API 请求,后面的请求的等待时间 */
export const GetRequestBundleWaitingSeconds = 2;
 
/** Pending 的 Get 请求列表的缓存 Key */
export const PendingRequestsCacheKey = `${SERVER_URL}_pending_get_requests`;
 
/** 特殊宽度的 Create 和 Update Modal, 如果 DomainName 满足 key 作为后缀,则使用此处配置的宽度 */
export const SpecialModalWidth: { [propName: string]: string } = {
  "DynamicLogic": "90%",
  "tech_muyan_dynamic_DynamicLogic": "90%",
  "tech_muyan_enterprisewiki_Article": "90%",
  "Feedback": "90%",
  "tech_muyan_feedback_Feedback": "90%",
  "Message": "90%",
  "tech_muyan_message_Message": "90%",
};
 
export interface LayoutProps {
  labelCol: { span: number };
  wrapperCol: { span: number };
}
 
/** 编辑和创建页面上默认的 Form Layout */
export const DefaultFormLayout: LayoutProps = {
  /* label 的宽度 */
  labelCol: { span: 7 },
  /* 字段的宽度 */
  wrapperCol: { span: 17 },
};
 
export const DefaultWidthLayout: LayoutProps = {
  labelCol: { span: 7 },
  wrapperCol: { span: 17 },
};
 
export const ActionWidthLayout: LayoutProps = {
  labelCol: { span: 24 },
  wrapperCol: { span: 24 },
};
 
export const FormLayoutConfig: { [propName: string]: typeof DefaultWidthLayout } = {
  "Wizard": DefaultWidthLayout,
  "Action": ActionWidthLayout,
};
 
/** 特殊的 Form Layout, 如果 DomainName 满足 key 作为后缀,则 Create 和 Edit 界面使用此处配置的 Layout*/
export const SpecialFormLayout: { [propName: string]: typeof DefaultWidthLayout } = {
  "DynamicLogic": DefaultWidthLayout,
  "tech_muyan_dynamic_DynamicLogic": DefaultWidthLayout,
  "Message": DefaultWidthLayout,
  "tech_muyan_message_Message": DefaultWidthLayout,
  "DynamicTheme": DefaultWidthLayout,
  "tech_muyan_dynamic_ui_DynamicTheme": DefaultWidthLayout,
};
 
/** TableMode 到页面默认显示条数的 Map */
export const TableModeDefaultPageSizeMapping = {
  "finder": FINDER_DEFAULT_PAGE_SIZE,
  "detail": DETAIL_DEFAULT_PAGE_SIZE,
  "detail-drawer": DRAWER_DEFAULT_PAGE_SIZE,
  "table-list": DEFAULT_PAGE_SIZE,
  "simple-list": DEFAULT_PAGE_SIZE,
  "card-list": DEFAULT_PAGE_SIZE_FOR_CARD_LIST,
};
 
/**
 * 编辑控件的基础宽度,所有的编辑控件均应该是这个宽度,
 * 所有其他宽度应该以本宽度为基准进行计算,而不应该设置绝对值
 */
export const EditableComponentDefaultWidth = 280;
 
/** 对象选择控件减去右边的汉堡包菜单图标的宽度 */
export const EditableObjectSelectDefaultWidth = (EditableComponentDefaultWidth - 30);
 
/** 编辑控件的基础 style, 所有的编辑控件均应该引用该 style */
export const EditableObjectSelectDefaultStyle = { width: `${EditableObjectSelectDefaultWidth}px` };
 
/** 所有可输入控件的默认 Style */
export const EditableComponentDefaultStyle = { width: `${EditableComponentDefaultWidth}px` };
 
export const HttpMethods: Array<HttpMethod> = [
  'GET', 'POST', 'DELETE', 'PUT', 'OPTIONS', 'PATCH', 'CONNECT', 'TRACE', 'HEAD'
];
 
/** 默认的上传文件大小限制 */
export const MaxUploadFileSizeInMB = 50;
 
/** 对于可以上传多个附件的文件字段,可上传的文件个数默认限制 */
export const MaxUploadFileCount = 20;
 
/** 附件字段总的上传文件大小 */
export const MaxTotalFileSizeInMB = 1000;
 
/** 左侧菜单宽度, 还需要修改 App.less 中的 @left-menu-width 变量才能保证排版 */
export const LeftMenuWidth = 220;
 
/** Full Text Search List 页面默认的高亮关键字前后的显示字符个数,默认显示关键字前后格这么多的字符 */
export const SearchKeywordHighlightContextSize = 170 / 2;
 
/** WebSocket 前后台 Dummy 请求用于 Heroku 上防止连接超时的 Message 内容 */
export const WebSocketDummyMessage = 'Dummy Ping';
 
/** hasDetailPanel 为 true 但是又想在 drawer 中显示的字段 */
//TODO 直接修改为所有的字段在 drawer 中都显示,但是要在每种字段的
//displayComponent 的实现,中,针对 tableMode 为 detail-drawer 的情况,做特殊处理
export const showInDrawerHasDetailFieldTypes = ['json', 'code', 'markdown', 'array', 'lineChart', 'tableChart'];
 
export const isDevelopmentEnv = (): boolean => {
  return (process.env.NODE_ENV === 'development');
};
 
/** different fetch types */
export const ExcludeArrayColumnsFetchType = "exclude_array_columns";
export const OnlyLabelFieldFetchType = "only_label_field";
export const AllColumnsFetchType = "all_columns";
export const IncludeArrayColumnsWithLabel = "include_array_columns_with_label";
 
/** 分页每页显示条目的选项 */
export const RECORD_PER_PAGE_OPTIONS = isDevelopmentEnv() ? [
  "1", "5", "10", "20", "50", "100", "200", "500"
] : [
  "10", "20", "50", "100", "200", "500"
];
export const DndItemTypes = {
  Collapse: 'collapse',
  List: 'list',
  FileItem: 'fileItem',
};