cspace-ui
Version:
CollectionSpace user interface for browsers
858 lines (660 loc) • 26 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getFirstColumnName = exports.findVocabularyUses = exports.findFieldConfigInPart = exports.findField = exports.getDefaultSearchVocabulary = exports.getDefaultSearchRecordType = exports.validateLocation = exports.isUtility = exports.isAuthority = exports.getRequiredMessage = exports.getFieldComputer = exports.getFieldCustomValidator = exports.getFieldDataType = exports.isFieldRequired = exports.isFieldRepeating = exports.isFieldCloneable = exports.getStickyFields = exports.getDefaults = exports.getDefaultValue = exports.getVocabularyConfigByServicePath = exports.getVocabularyConfigByShortID = exports.getRecordTypeNameByUri = exports.getRecordTypeConfigByUri = exports.getRecordTypeConfigByServicePath = exports.getRecordTypeNameByServiceObjectName = exports.getRecordTypeConfigByServiceObjectName = exports.getRecordTypeConfigByServiceDocumentName = exports.initConfig = exports.mergeConfig = exports.mergeStrategy = exports.applyPlugins = exports.applyPlugin = exports.evaluatePlugin = exports.finalizeRecordTypes = exports.initializeRecordTypes = exports.initializeExtensionFieldParents = exports.initializeExtensions = exports.dataPathToFieldDescriptorPath = exports.mergeKey = exports.configKey = void 0;
var _react = _interopRequireDefault(require("react"));
var _immutable = _interopRequireDefault(require("immutable"));
var _mergeWith = _interopRequireDefault(require("lodash/mergeWith"));
var _flatMap = _interopRequireDefault(require("lodash/flatMap"));
var _get = _interopRequireDefault(require("lodash/get"));
var _set = _interopRequireDefault(require("lodash/set"));
var _warning = _interopRequireDefault(require("warning"));
var _errorCodes = require("../constants/errorCodes");
var _dataTypes = require("../constants/dataTypes");
var _blobHelpers = require("./blobHelpers");
var _formatHelpers = require("./formatHelpers");
var _recordDataHelpers = require("./recordDataHelpers");
var _csidHelpers = require("./csidHelpers");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const onlyDigitsPattern = /^\d+$/;
const isNotNumeric = string => !onlyDigitsPattern.test(string);
const configKey = '[config]';
exports.configKey = configKey;
const mergeKey = '[merge]';
exports.mergeKey = mergeKey;
const dataPathToFieldDescriptorPath = dataPath => dataPath.filter(isNotNumeric);
/*
* Initialize the extension configurations in a configuration object. This function mutates the
* argument configuration.
*
* - Set the extensionName property of each top level field in the extension to the extension name
*/
exports.dataPathToFieldDescriptorPath = dataPathToFieldDescriptorPath;
const initializeExtensions = config => {
const {
extensions
} = config;
if (extensions) {
Object.keys(extensions).forEach(extensionName => {
const extension = extensions[extensionName];
const {
fields
} = extension;
if (fields) {
Object.values(fields).forEach(fieldDescriptor => {
(0, _set.default)(fieldDescriptor, [configKey, 'extensionName'], extensionName);
});
}
});
}
return config;
};
exports.initializeExtensions = initializeExtensions;
const initializeExtensionFieldParents = fieldDescriptor => {
if (fieldDescriptor) {
Object.keys(fieldDescriptor).filter(key => key !== configKey).forEach(key => {
const childFieldDescriptor = fieldDescriptor[key];
const isExtensionField = (0, _get.default)(childFieldDescriptor, [configKey, 'extensionName']);
if (isExtensionField) {
// Make a copy of this field descriptor and its configuration, so that different
// configuration can be applied to each use of the extension (really wishing I'd made the
// config an Immutable, so explicit copy wouldn't be necessary).
// Set the extension parent config in the extension field's config.
const childFieldDescriptorCopy = Object.assign({}, childFieldDescriptor, {
[configKey]: Object.assign({}, childFieldDescriptor[configKey], {
extensionParentConfig: fieldDescriptor[configKey]
})
}); // eslint-disable-next-line no-param-reassign
fieldDescriptor[key] = childFieldDescriptorCopy;
} else {
initializeExtensionFieldParents(childFieldDescriptor);
}
});
}
};
/*
* Initialize the record type configurations in a configuration object. This function mutates the
* argument configuration.
*
* - Set the name property of each recordTypes entry to its key
* - Set the name property of each vocabularies entry to its key
* - Set the parent property of any extension fields
*/
exports.initializeExtensionFieldParents = initializeExtensionFieldParents;
const initializeRecordTypes = config => {
const keys = ['recordTypes', ['invocables', 'report'], ['invocables', 'batch']];
keys.forEach(key => {
const recordTypesConfig = (0, _get.default)(config, key);
if (recordTypesConfig) {
Object.keys(recordTypesConfig).forEach(recordTypeName => {
const recordType = recordTypesConfig[recordTypeName];
recordType.name = recordTypeName;
const {
fields,
vocabularies
} = recordType;
if (fields) {
Object.values(fields).forEach(fieldDescriptor => {
initializeExtensionFieldParents(fieldDescriptor);
});
}
if (vocabularies) {
Object.keys(vocabularies).forEach(vocabularyName => {
vocabularies[vocabularyName].name = vocabularyName;
});
}
});
}
});
return config;
};
/*
* Finalize the record type configurations in a configuration object. This function mutates the
* argument configuration.
*
* - Delete any record type or vocabulary that is disabled
*/
exports.initializeRecordTypes = initializeRecordTypes;
const finalizeRecordTypes = config => {
const {
recordTypes
} = config;
if (recordTypes) {
Object.keys(recordTypes).forEach(recordTypeName => {
const recordType = recordTypes[recordTypeName];
if (recordType.disabled) {
delete recordTypes[recordTypeName];
} else {
const {
vocabularies
} = recordType;
if (vocabularies) {
Object.keys(vocabularies).forEach(vocabularyName => {
const vocabulary = vocabularies[vocabularyName];
if (vocabulary.disabled) {
delete vocabularies[vocabularyName];
}
});
}
}
});
}
return config;
};
exports.finalizeRecordTypes = finalizeRecordTypes;
const evaluatePlugin = (plugin, configContext) => {
const pluginType = typeof plugin;
const isValidType = plugin && (pluginType === 'function' || pluginType === 'object' && !Array.isArray(plugin));
process.env.NODE_ENV !== "production" ? (0, _warning.default)(isValidType, 'A plugin must be an object or a function.') : void 0;
if (!isValidType) {
return {};
}
const config = pluginType === 'object' ? plugin : plugin(configContext);
initializeExtensions(config);
initializeRecordTypes(config);
return config;
};
exports.evaluatePlugin = evaluatePlugin;
const applyPlugin = function applyPlugin(targetConfig, plugin) {
let configContext = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
const pluginConfigContribution = evaluatePlugin(plugin, configContext);
/* Gotta do this mutual recursion */
/* eslint-disable no-use-before-define */
return mergeConfig(targetConfig, pluginConfigContribution, configContext);
/* eslint-enable no-use-before-define */
};
exports.applyPlugin = applyPlugin;
const applyPlugins = function applyPlugins(targetConfig, plugins) {
let configContext = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
const isArray = Array.isArray(plugins);
process.env.NODE_ENV !== "production" ? (0, _warning.default)(isArray, 'Plugins must be an array.') : void 0;
if (!isArray) {
return targetConfig;
}
return plugins.reduce((updatedConfig, plugin) => {
// eslint-disable-next-line no-param-reassign
configContext.config = updatedConfig;
return applyPlugin(updatedConfig, plugin, configContext);
}, targetConfig);
};
exports.applyPlugins = applyPlugins;
const mergeStrategy = {
override: srcValue => Object.assign({}, srcValue, {
[mergeKey]: 'override'
})
};
exports.mergeStrategy = mergeStrategy;
const configMerger = (objValue, srcValue, key) => {
if (Array.isArray(objValue)) {
// Don't merge arrays. Just override with the source value.
return srcValue;
}
if (key === 'advancedSearch') {
// Don't merge advanced search config. Just override with the source value.
return srcValue;
}
if (_react.default.isValidElement(objValue)) {
// Don't merge React elements, e.g. in form templates. Just override with the source value.
return srcValue;
}
if (srcValue && typeof srcValue === 'object' && srcValue[mergeKey] === 'override') {
const srcValueCopy = Object.assign({}, srcValue);
delete srcValueCopy[mergeKey];
return srcValueCopy;
}
return undefined;
};
const mergeConfig = function mergeConfig(targetConfig, sourceConfig) {
let configContext = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
// eslint-disable-next-line no-param-reassign
configContext.config = targetConfig;
const pluginsAppliedConfig = sourceConfig && 'plugins' in sourceConfig ? applyPlugins(targetConfig, sourceConfig.plugins, configContext) : targetConfig;
const mergedConfig = (0, _mergeWith.default)({}, pluginsAppliedConfig, sourceConfig, configMerger);
delete mergedConfig.plugins;
return mergedConfig;
};
exports.mergeConfig = mergeConfig;
const initConfig = (config, configContext) => mergeConfig({}, config, configContext);
exports.initConfig = initConfig;
const getRecordTypeConfigByServiceDocumentName = (config, documentName) => {
if (!documentName) {
return undefined;
}
if (!config.recordTypesByServiceDocumentName) {
const recordTypesByServiceDocumentName = {};
const {
recordTypes
} = config;
Object.keys(recordTypes).forEach(recordType => {
const recordTypeConfig = recordTypes[recordType];
const {
serviceConfig
} = recordTypeConfig;
recordTypesByServiceDocumentName[serviceConfig.documentName] = recordTypeConfig;
});
/* eslint-disable no-param-reassign */
config.recordTypesByServiceDocumentName = recordTypesByServiceDocumentName;
/* eslint-enable no-param-reassign */
}
return config.recordTypesByServiceDocumentName[documentName];
};
exports.getRecordTypeConfigByServiceDocumentName = getRecordTypeConfigByServiceDocumentName;
const getRecordTypeConfigByServiceObjectName = (config, objectName) => {
if (!objectName) {
return undefined;
}
if (!config.recordTypesByServiceObjectName) {
const recordTypesByServiceObjectName = {};
const {
recordTypes
} = config;
Object.keys(recordTypes).forEach(recordType => {
const recordTypeConfig = recordTypes[recordType];
recordTypesByServiceObjectName[recordTypeConfig.serviceConfig.objectName] = recordTypeConfig;
});
/* eslint-disable no-param-reassign */
config.recordTypesByServiceObjectName = recordTypesByServiceObjectName;
/* eslint-enable no-param-reassign */
}
return config.recordTypesByServiceObjectName[objectName];
};
exports.getRecordTypeConfigByServiceObjectName = getRecordTypeConfigByServiceObjectName;
const getRecordTypeNameByServiceObjectName = (config, objectName) => {
const recordTypeConfig = getRecordTypeConfigByServiceObjectName(config, objectName);
return recordTypeConfig ? recordTypeConfig.name : undefined;
};
exports.getRecordTypeNameByServiceObjectName = getRecordTypeNameByServiceObjectName;
const getRecordTypeConfigByServicePath = (config, servicePath) => {
if (!servicePath) {
return undefined;
}
if (!config.recordTypesByServicePath) {
const recordTypesByServicePath = {};
const {
recordTypes
} = config;
Object.keys(recordTypes).forEach(recordType => {
const recordTypeConfig = recordTypes[recordType];
recordTypesByServicePath[recordTypeConfig.serviceConfig.servicePath] = recordTypeConfig;
});
/* eslint-disable no-param-reassign */
config.recordTypesByServicePath = recordTypesByServicePath;
/* eslint-enable no-param-reassign */
}
return config.recordTypesByServicePath[servicePath];
};
exports.getRecordTypeConfigByServicePath = getRecordTypeConfigByServicePath;
const getRecordTypeConfigByUri = (config, uri) => {
if (!uri) {
return undefined;
}
const servicePath = uri.split('/', 2)[1];
return getRecordTypeConfigByServicePath(config, servicePath);
};
exports.getRecordTypeConfigByUri = getRecordTypeConfigByUri;
const getRecordTypeNameByUri = (config, uri) => {
const recordTypeConfig = getRecordTypeConfigByUri(config, uri);
return recordTypeConfig ? recordTypeConfig.name : undefined;
};
exports.getRecordTypeNameByUri = getRecordTypeNameByUri;
const getVocabularyConfigByShortID = (recordTypeConfig, shortID) => {
if (!shortID) {
return undefined;
}
if (!recordTypeConfig.vocabulariesByShortID) {
const vocabulariesByShortID = {};
const {
vocabularies
} = recordTypeConfig;
if (vocabularies) {
Object.keys(vocabularies).forEach(vocabulary => {
const vocabularyConfig = vocabularies[vocabulary];
const {
servicePath
} = vocabularyConfig.serviceConfig;
if (servicePath && servicePath.indexOf('urn:cspace:name(') === 0 && servicePath.lastIndexOf(')') === servicePath.length - 1) {
const vocabularyShortID = servicePath.substring(16, servicePath.length - 1);
vocabulariesByShortID[vocabularyShortID] = vocabularyConfig;
}
});
/* eslint-disable no-param-reassign */
recordTypeConfig.vocabulariesByShortID = vocabulariesByShortID;
/* eslint-enable no-param-reassign */
}
}
return recordTypeConfig.vocabulariesByShortID[shortID];
};
exports.getVocabularyConfigByShortID = getVocabularyConfigByShortID;
const vocabularyServicePathPattern = /^urn:cspace:name\((.*?)\)$/;
const getVocabularyConfigByServicePath = (recordTypeConfig, servicePath) => {
const match = vocabularyServicePathPattern.exec(servicePath);
if (!match) {
return undefined;
}
const shortID = match[1];
return getVocabularyConfigByShortID(recordTypeConfig, shortID);
};
exports.getVocabularyConfigByServicePath = getVocabularyConfigByServicePath;
const getDefaultValue = fieldDescriptor => {
const config = fieldDescriptor[configKey];
if (config) {
const {
dataType,
defaultValue
} = config;
if (typeof defaultValue === 'object' && !_immutable.default.Map.isMap(defaultValue)) {
// If an object is supplied as a default value, convert it to an immutable map.
return _immutable.default.fromJS(defaultValue);
} else if (typeof defaultValue === 'undefined' && dataType === _dataTypes.DATA_TYPE_BOOL) {
// If no default value is configured for a boolean field, consider it to be false.
return false;
}
return defaultValue;
}
return undefined;
};
exports.getDefaultValue = getDefaultValue;
const getDefaults = function getDefaults(fieldDescriptor) {
let currentPath = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
let results = [];
const defaultValue = getDefaultValue(fieldDescriptor);
if (typeof defaultValue !== 'undefined') {
results = results.concat({
path: currentPath,
value: defaultValue
});
}
const childKeys = Object.keys(fieldDescriptor).filter(key => key !== configKey);
childKeys.forEach(childKey => {
const childPath = currentPath.concat(childKey);
const childfieldDescriptor = fieldDescriptor[childKey];
const childResults = getDefaults(childfieldDescriptor, childPath);
results = results.concat(childResults);
});
return results;
};
/**
* Returns an array of paths to sticky fields that exist under a given field.
*/
exports.getDefaults = getDefaults;
const getStickyFields = function getStickyFields(fieldDescriptor) {
let currentPath = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
if (!fieldDescriptor) {
return [];
}
const isSticky = (0, _get.default)(fieldDescriptor, [configKey, 'sticky']);
if (isSticky) {
return [currentPath];
}
return Object.keys(fieldDescriptor).filter(key => key !== configKey).reduce((results, childKey) => {
const childPath = currentPath.concat(childKey);
const childfieldDescriptor = fieldDescriptor[childKey];
const childResults = getStickyFields(childfieldDescriptor, childPath);
return results.concat(childResults);
}, []);
};
exports.getStickyFields = getStickyFields;
const isFieldCloneable = fieldDescriptor => {
const config = fieldDescriptor[configKey];
if (config && 'cloneable' in config) {
return config.cloneable;
}
return true;
};
exports.isFieldCloneable = isFieldCloneable;
const isFieldRepeating = fieldDescriptor => {
const config = fieldDescriptor[configKey];
if (config && 'repeating' in config) {
return config.repeating;
}
return false;
};
exports.isFieldRepeating = isFieldRepeating;
const isFieldRequired = (fieldDescriptor, recordData) => {
const required = (0, _get.default)(fieldDescriptor, [configKey, 'required']);
return !!(typeof required === 'function' ? required(recordData) : required);
};
exports.isFieldRequired = isFieldRequired;
const getFieldDataType = fieldDescriptor => {
let type;
const fieldConfig = fieldDescriptor[configKey];
if (fieldConfig) {
type = fieldConfig.dataType;
}
if (!type) {
// Check if there are child field descriptors. If so, default to map.
const keys = Object.keys(fieldDescriptor);
for (let i = 0; i < keys.length; i += 1) {
if (keys[i] !== configKey) {
type = _dataTypes.DATA_TYPE_MAP;
break;
}
}
}
if (!type) {
// Default to string.
type = _dataTypes.DATA_TYPE_STRING;
}
return type;
};
exports.getFieldDataType = getFieldDataType;
const getFieldCustomValidator = fieldDescriptor => {
let validator;
const fieldConfig = fieldDescriptor[configKey];
if (fieldConfig) {
validator = fieldConfig.validate;
}
return validator;
};
exports.getFieldCustomValidator = getFieldCustomValidator;
const getFieldComputer = fieldDescriptor => {
let computer;
const fieldConfig = fieldDescriptor[configKey];
if (fieldConfig) {
computer = fieldConfig.compute;
}
return computer;
};
exports.getFieldComputer = getFieldComputer;
const getRequiredMessage = fieldDescriptor => (0, _get.default)(fieldDescriptor, [configKey, 'messages', 'required']);
exports.getRequiredMessage = getRequiredMessage;
const isAuthority = recordTypeConfig => (0, _get.default)(recordTypeConfig, ['serviceConfig', 'serviceType']) === 'authority';
exports.isAuthority = isAuthority;
const isUtility = recordTypeConfig => (0, _get.default)(recordTypeConfig, ['serviceConfig', 'serviceType']) === 'utility';
exports.isUtility = isUtility;
const validateLocation = (config, location) => {
const {
recordType,
vocabulary,
csid,
subresource,
relatedRecordType,
relatedCsid
} = location;
const recordTypeConfig = (0, _get.default)(config, ['recordTypes', recordType]);
if (!recordTypeConfig || recordTypeConfig.disabled) {
return {
error: {
recordType,
code: _errorCodes.ERR_UNKNOWN_RECORD_TYPE
}
};
}
if (isAuthority(recordTypeConfig)) {
if (!vocabulary) {
return {
error: {
recordType,
code: _errorCodes.ERR_MISSING_VOCABULARY
}
};
}
const vocabularyConfig = (0, _get.default)(recordTypeConfig, ['vocabularies', vocabulary]);
if (!vocabularyConfig || vocabularyConfig.disabled) {
return {
error: {
recordType,
vocabulary,
code: _errorCodes.ERR_UNKNOWN_VOCABULARY
}
};
}
} else if (vocabulary) {
return {
error: {
recordType,
vocabulary,
code: _errorCodes.ERR_UNKNOWN_VOCABULARY
}
};
}
if (csid && !(0, _csidHelpers.isCsid)(csid) && !(0, _csidHelpers.isUrnCsid)(csid)) {
return {
error: {
csid,
code: _errorCodes.ERR_INVALID_CSID
}
};
}
if (subresource) {
const subresourceConfig = (0, _get.default)(config, ['subresources', subresource]);
if (!subresourceConfig) {
return {
error: {
subresource,
code: _errorCodes.ERR_UNKNOWN_SUBRESOURCE
}
};
}
}
if (relatedRecordType) {
const serviceType = (0, _get.default)(recordTypeConfig, ['serviceConfig', 'serviceType']);
const relatedServiceType = (0, _get.default)(config, ['recordTypes', relatedRecordType, 'serviceConfig', 'serviceType']);
if (serviceType !== 'procedure' && serviceType !== 'object' || relatedServiceType !== 'procedure' && relatedServiceType !== 'object') {
return {
error: {
recordType,
relatedRecordType,
code: _errorCodes.ERR_INVALID_RELATED_TYPE
}
};
}
}
if (relatedCsid && !(0, _csidHelpers.isCsid)(relatedCsid)) {
return {
error: {
csid: relatedCsid,
code: _errorCodes.ERR_INVALID_CSID
}
};
}
return {};
};
exports.validateLocation = validateLocation;
const getDefaultSearchRecordType = config => {
const {
recordTypes
} = config;
const names = Object.keys(recordTypes);
let defaultSearchRecordType;
for (let i = 0; i < names.length; i += 1) {
const name = names[i];
if (recordTypes[name].defaultForSearch) {
defaultSearchRecordType = name;
break;
}
}
return defaultSearchRecordType || names[0];
};
exports.getDefaultSearchRecordType = getDefaultSearchRecordType;
const getDefaultSearchVocabulary = recordTypeConfig => {
const {
vocabularies
} = recordTypeConfig;
const names = Object.keys(vocabularies);
let defaultSearchVocabulary;
for (let i = 0; i < names.length; i += 1) {
const name = names[i];
if (vocabularies[name].defaultForSearch) {
defaultSearchVocabulary = name;
break;
}
}
return defaultSearchVocabulary || names[0];
};
exports.getDefaultSearchVocabulary = getDefaultSearchVocabulary;
const findField = (parentFieldDescriptor, fieldName) => {
const keys = Object.keys(parentFieldDescriptor);
for (let i = 0; i < keys.length; i += 1) {
const key = keys[i];
const value = parentFieldDescriptor[key];
if (key === fieldName) {
return value;
}
if (key !== configKey) {
const fieldDescriptor = findField(value, fieldName);
if (fieldDescriptor) {
return fieldDescriptor;
}
}
}
return null;
};
exports.findField = findField;
const findFieldConfigInPart = (recordTypeConfig, partName, fieldName) => {
const partDescriptor = (0, _get.default)(recordTypeConfig, ['fields', 'document', "".concat(_recordDataHelpers.NS_PREFIX, ":").concat(partName)]);
if (!partDescriptor) {
return null;
} // 1. Look for the field as a direct child of the part.
let fieldDescriptor = partDescriptor[fieldName]; // 2. Check for a memoized result.
if (!fieldDescriptor) {
fieldDescriptor = (0, _get.default)(recordTypeConfig, ['fieldsByPart', partName, fieldName]);
} // 3. Search for a nested field.
if (typeof fieldDescriptor === 'undefined') {
fieldDescriptor = findField(partDescriptor, fieldName); // Memoize the result.
(0, _set.default)(recordTypeConfig, ['fieldsByPart', partName, fieldName], fieldDescriptor);
}
return fieldDescriptor ? fieldDescriptor[configKey] : null;
};
exports.findFieldConfigInPart = findFieldConfigInPart;
const findFieldsWithSource = (fieldDescriptor, shortId) => {
const fieldsWithSource = (0, _flatMap.default)(Object.keys(fieldDescriptor).filter(key => key !== configKey), childFieldName => findFieldsWithSource(fieldDescriptor[childFieldName], shortId));
const fieldConfig = fieldDescriptor[configKey];
const source = (0, _get.default)(fieldConfig, ['view', 'props', 'source']);
if (source === shortId) {
fieldsWithSource.push(fieldConfig);
}
return fieldsWithSource;
};
const findVocabularyUses = (config, shortId) => {
if (!shortId) {
return null;
}
const uses = {};
Object.values(config.recordTypes).forEach(recordTypeConfig => {
const fieldDescriptor = recordTypeConfig.fields;
if (fieldDescriptor) {
const fields = findFieldsWithSource(recordTypeConfig.fields, shortId);
if (fields.length > 0) {
uses[recordTypeConfig.name] = fields;
}
}
});
return uses;
};
exports.findVocabularyUses = findVocabularyUses;
const getFirstColumnName = function getFirstColumnName(config, recordType) {
let columnSetName = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'default';
const columnConfig = (0, _get.default)(config, ['recordTypes', recordType, 'columns', columnSetName]);
if (!columnConfig) {
return undefined;
}
const orderedColumnNames = Object.keys(columnConfig).filter(name => !columnConfig[name].disabled && columnConfig[name].formatValue !== _formatHelpers.formatWorkflowStateIcon && columnConfig[name].formatValue !== _blobHelpers.thumbnailImage).sort((nameA, nameB) => {
const orderA = columnConfig[nameA].order;
const orderB = columnConfig[nameB].order;
return orderA - orderB;
});
return orderedColumnNames[0];
};
exports.getFirstColumnName = getFirstColumnName;