{"version":3,"file":"9069cc5983dcd0af3b88283.js?3.6.10.39095fcb9.1720035904389","mappings":"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","sources":["webpack://mono-repo/./packages/core-asset/src/collections/attributes.js","webpack://mono-repo/./packages/core-asset/src/properties/attributes.js"],"sourcesContent":["/**\n * Attribute templates collection\n * This collection contains ALL attributes\n * It creates two sub collections of asset and clip attributes and maintains the two\n * No need to add to them individually - just add to this collection and they will get to where they need to be\n * @class\n */\nimport Base from '@netx/core/lib/netx-collection';\n\nimport {getPreference} from '@netx/core-user-next/utils/getPreference';\nimport {\n\tcurrentUserMeetsUserLevel,\n\tUserLevel,\n} from '@netx/core-user-next/utils/currentUserMeetsUserLevel';\n\nimport AssetAttributeDatumCollection from './assetAttributeDatum';\n\nimport BaseModel from '../models/attribute';\nimport DateModel from '../models/attribute_date';\nimport MultiselectModel from '../models/attribute_multiselect';\nimport NumberModel from '../models/attribute_number';\nimport SelectModel from '../models/attribute_select';\nimport SemanticModel from '../models/attribute_semantic';\nimport TagModel from '../models/attribute_tag';\nimport TagVocabModel from '../models/attribute_tagVocab';\nimport TextModel from '../models/attribute_text';\nimport TextareaModel from '../models/attribute_textarea';\n\nimport {checksumEnabled} from '@netx/core-asset-next/enablers';\nimport {ENFORCE_ATTRIBUTE_IDS} from '@netx/core-cms/services/settings/constants';\nimport hasUpdatedAttributesSystem from '@netx/core-cms/services/settings/utils/hasUpdatedAttributesSystem';\nimport {isPortal} from '@netx/core/utils/isPortal';\nimport {assetExpirationEnabled} from '@netx/core-asset-expiration/enablers';\n\nconst Models = {\n\tbase: BaseModel,\n\tdate: DateModel,\n\tmultiselect: MultiselectModel,\n\tnumber: NumberModel,\n\tselect: SelectModel,\n\tsemantic: SemanticModel,\n\ttag: TagModel,\n\ttagVocab: TagVocabModel,\n\ttext: TextModel,\n\ttextarea: TextareaModel,\n};\n\nimport {isEmptyValue} from '@netx/core/lib/underscore-netx';\nimport {\n\tids as typeIds,\n\ttypes,\n\tvocabularyAttributes,\n} from '../properties/attributes';\nimport {session} from '@netx/core-auth/collections/singleton';\n\nconst getPortal = () => isPortal() && Netx.cms?.portal?.id && Netx.cms?.portal;\n\nexport default class Attributes extends Base {\n\t/**\n\t * @type {Netx.Rpc}\n\t * @private\n\t */\n\tget rpc() {\n\t\treturn true;\n\t}\n\n\t/** @type {boolean} */\n\tget xhrTrackProgress() {\n\t\treturn true;\n\t}\n\n\t/** @type {object} */\n\tget xhrLoadingMessages() {\n\t\treturn {\n\t\t\tgetAttributeTemplates: 'Loading attributes',\n\t\t\tgetMetadataMapJson: 'Loading metadata maps',\n\t\t};\n\t}\n\n\t/** @type {object} */\n\tget xhrLoadedMessages() {\n\t\treturn {\n\t\t\tgetAttributeTemplates: 'Loaded attributes',\n\t\t\tgetMetadataMapJson: 'Loaded metadata maps',\n\t\t};\n\t}\n\n\t/**\n\t * Since we are overriding the model proeprty as a method\n\t * we need to point backbone into the right direction with model prototype accessing\n\t * This is the only method in all of the backbone collection code that relys on getting the a property from the model prototype\n\t * @override\n\t * @param {object} attrs Attributes\n\t * @return {mixed} Model id\n\t */\n\tmodelId(attrs) {\n\t\treturn attrs[Models.base.prototype.idAttribute || 'id'];\n\t}\n\n\t/**\n\t * Return an array of the IDs of the models in this collection.\n\t * Se note about `this.modelId` - this is an override of code in module:core/lib/netx-collection\n\t * @override\n\t * @param {boolean} omitSystem Omit system attributes\n\t * @return {array} Array of model ids\n\t */\n\tids(omitSystem) {\n\t\tconst ids = this.pluck(Models.base.prototype.idAttribute || 'id');\n\t\tif (!omitSystem) return ids;\n\n\t\t// Omit system attributes\n\t\treturn ids.filter((id) => id > 0);\n\t}\n\n\t/** @method */\n\tcomparator(attrA, attrB) {\n\t\t// DAM-20153: if there is a portal, sort by attributeIds array\n\t\tconst portal = getPortal();\n\t\tif (portal) {\n\t\t\tconst attributeIds = portal.get('attributeIds');\n\t\t\tconst detailAttributes = portal.get('detailAttributes') || [];\n\t\t\t// maintain order of detailAttributes if portal has not been\n\t\t\t// edited since attributes upgrade\n\t\t\tif (\n\t\t\t\t!hasUpdatedAttributesSystem(portal.attributes) &&\n\t\t\t\tdetailAttributes.length\n\t\t\t) {\n\t\t\t\tconst aIndex = detailAttributes.indexOf(attrA.id);\n\t\t\t\tconst bIndex = detailAttributes.indexOf(attrB.id);\n\t\t\t\tif (aIndex < 0 && bIndex > -1) return 1;\n\t\t\t\tif (aIndex > -1 && bIndex < 0) return -1;\n\t\t\t\tif (aIndex < 0 && bIndex < 0)\n\t\t\t\t\treturn (\n\t\t\t\t\t\tattributeIds.indexOf(attrA.id) - attributeIds.indexOf(attrB.id)\n\t\t\t\t\t);\n\t\t\t\treturn aIndex - bIndex;\n\t\t\t}\n\n\t\t\t// Edited since upgrade, use the explicit order in the portal\n\t\t\tif (hasUpdatedAttributesSystem(portal.attributes)) {\n\t\t\t\treturn attributeIds.indexOf(attrA.id) - attributeIds.indexOf(attrB.id);\n\t\t\t}\n\n\t\t\t// Not edited since upgrade and there are no detailAttributes defined\n\t\t\t// use the explicit order in the portal, except force `file` to the top like we would have in old portals\n\t\t\t// NOTE: if we just fall through to the classic comparator here, we do not line up with the list the user\n\t\t\t// would see when editing their portal. And any edit made (without explictely going in and managing the attrs)\n\t\t\t// would then cause us to hit the `if` just above and now your attributes are in an unpredictable order based\n\t\t\t// on what you would have just seen (in portal proper) prior to an edit.\n\t\t\tif (attrA.id === -101) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t\tif (attrB.id === -101) {\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\treturn attributeIds.indexOf(attrA.id) - attributeIds.indexOf(attrB.id);\n\t\t}\n\n\t\t// DAM-11580\n\t\t// If attrA is `file` it comes before\n\t\tif (attrA.id === -101) {\n\t\t\treturn -1;\n\t\t}\n\t\t// If attrB is `file`, attrA comes after\n\t\tif (attrB.id === -101) {\n\t\t\treturn 1;\n\t\t}\n\n\t\tif (this.keepAlphabetical) {\n\t\t\tconst aName = attrA.get('name').toLowerCase();\n\t\t\tconst bName = attrB.get('name').toLowerCase();\n\t\t\t// This is then the standard sort you would expect by `name`\n\t\t\tif (aName < bName) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t\tif (bName < aName) {\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t} else {\n\t\t\tconst aOrderby = attrA.get('orderby');\n\t\t\tconst bOrderby = attrB.get('orderby');\n\t\t\t// This is then the standard sort you would expect by `orderby`\n\t\t\tif (aOrderby < bOrderby) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t\tif (bOrderby < aOrderby) {\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t}\n\n\t\t// Equal\n\t\treturn 0;\n\t}\n\n\t/**\n\t * @property {object} methods - Collection RPC methods\n\t * @property {method} methods.read - Fetch attribute templates, metadata and metadata maps\n\t *\n\t * @property {method} methods.getAttributeTemplatesForCategoryContext - Provided an array of category ids, fetch all attribute templates, for those categories, that have editing permissions.\n\t * @property {method} methods.getAttributeTemplates - Fetch attribute templates\n\t * @property {method} methods.getAttributeObjects - Fetch attribute templates by id\n\t * @property {method} methods.getAllAttributeIds - Fetch attribute templates ids\n\t * @property {method} methods.getDataSetList - Fetch datasets (deprecated)\n\t * @property {method} methods.setAttributeTemplateOrder - Set new attribute template order\n\t * @property {method} methods.getMetadataMapJson - Fetch metadata map json\n\t * @property {method} methods._getMetadataMap - Fetch metadata map\n\t * @property {method} methods._setMetadataMap - Update metadata map\n\t */\n\tget methods() {\n\t\treturn {\n\t\t\t/**\n\t\t\t * @function\n\t\t\t * @param {object} opts Request options\n\t\t\t */\n\t\t\tread(opts) {\n\t\t\t\t// First get the templates\n\t\t\t\treturn (\n\t\t\t\t\tthis.categoryIds.length\n\t\t\t\t\t\t? this.getAttributeTemplatesForCategoryContext\n\t\t\t\t\t\t: this.getAttributeTemplates\n\t\t\t\t)(opts).then((attrs) => {\n\t\t\t\t\tthis.set(attrs);\n\t\t\t\t\t// Get all other pertinent attribute data\n\t\t\t\t\treturn this.when(\n\t\t\t\t\t\tthis.getMetadata(opts),\n\t\t\t\t\t\tthis.getMetadataMap(opts),\n\t\t\t\t\t).then(() => {\n\t\t\t\t\t\t// Resolve\n\t\t\t\t\t\treturn attrs;\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t},\n\n\t\t\t/** @method */\n\t\t\tgetAllAttributeIds: ['getAllAttributeIds'],\n\t\t\t/** @method */\n\t\t\tgetAttributeObjects: ['getAttributeObjects', 'attributeIds'],\n\t\t\t/** @method */\n\t\t\tgetAttributeTemplatesForCategoryContext() {\n\t\t\t\t// See @todo in constructor\n\t\t\t\tlet categoryIds = this.categoryIds;\n\t\t\t\tif (categoryIds.length > 1) {\n\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t'multiple ids are not actually supported for `getAttributeTemplatesForCategoryContext`. Ignoring all but the first id.',\n\t\t\t\t\t);\n\t\t\t\t\tcategoryIds = [categoryIds[0]];\n\t\t\t\t}\n\t\t\t\treturn [\n\t\t\t\t\t'getAttributeTemplatesForCategoryContext',\n\t\t\t\t\tcategoryIds,\n\t\t\t\t\tthis.writableOnly,\n\t\t\t\t];\n\t\t\t},\n\t\t\t/** @method */\n\t\t\tgetAttributeTemplates: ['getAttributeTemplates'],\n\t\t\t/**\n\t\t\t * @method\n\t\t\t * @param {object} opts Request options\n\t\t\t * @deprecated\n\t\t\t * @see parsers.getDataSetList\n\t\t\t */\n\t\t\tgetDataSetList(opts) {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t'Do not fetch datasets via the attributes collection. Method will be removed in 9.0 and will result in an error.',\n\t\t\t\t);\n\t\t\t\treturn ['getDataSetList', ''];\n\t\t\t},\n\t\t\t/** @method */\n\t\t\t_getMetadataMap: ['getMetadataMap'],\n\t\t\t/** @method */\n\t\t\tgetMetadataMapJson: ['getMetadataMapJson'],\n\t\t\t/**\n\t\t\t * @method\n\t\t\t * @param {array} ids IDs\n\t\t\t * @param {object} opts Request options\n\t\t\t */\n\t\t\tsetAttributeTemplateOrder(ids, opts) {\n\t\t\t\treturn ['setAttributeTemplateOrder', ids, false];\n\t\t\t},\n\t\t\t/**\n\t\t\t * @method\n\t\t\t * @param {object} opts Request options\n\t\t\t */\n\t\t\t_setMetadataMap(opts) {\n\t\t\t\treturn ['setMetadataMap', this.metadataMapArgs];\n\t\t\t},\n\t\t};\n\t}\n\n\t/**\n\t * @property {object} parsers - Collection parsers\n\t * @property {function} parsers.getAllAttributeIds - Parse fetch of attribute ids\n\t * @property {function} parsers.getAttributeObjects - Parse fetch of attribute templates\n\t * @property {function} parsers.getAttributeTemplates - Parse fetch of attribute templates\n\t * @property {function} parsers.getAttributeTemplatesForCategoryContext - Parse fetch of attribute templates\n\t * @property {function} parsers.getDataSetList - Parse fetch of datasets (deprecated)\n\t * @property {function} parsers._getMetadataMap - Parse fetch of metadata map\n\t * @property {function} parsers.getMetadataMapJson - Parse fetch of metadata map json\n\t * @property {function} parsers.setAttributeTemplateOrder - Parse update of attribute template order\n\t * @property {function} parsers._setMetadataMap - parse update of metadata map\n\t */\n\tget parsers() {\n\t\treturn {\n\t\t\t/**\n\t\t\t * @function\n\t\t\t * @param {array} ids Attribute ids\n\t\t\t * @param {object} opts Request options\n\t\t\t */\n\t\t\tgetAllAttributeIds(ids, opts) {\n\t\t\t\t// NOTE: the attribute object's returned id field is 'attributeid', all lower case,\n\t\t\t\t// while the RPC call is getAllAttributeIds() (uppercase I).\n\t\t\t\t// I'm keeping with the somewhat standard \"Ids\" format used in the rest of the codebase.\n\t\t\t\tthis.attributeIds = ids;\n\t\t\t},\n\t\t\t/**\n\t\t\t * @function\n\t\t\t * @param {array} attributes Attribute templates\n\t\t\t * @param {object} opts Request options\n\t\t\t */\n\t\t\tgetAttributeObjects(attributes, opts) {\n\t\t\t\tthis.set(this.parseAndCorrect(attributes), opts);\n\t\t\t},\n\t\t\t/**\n\t\t\t * @function\n\t\t\t * @param {array} attributes Attribute templates\n\t\t\t * @param {object} opts Request options\n\t\t\t */\n\t\t\tgetAttributeTemplates(attributes, opts) {\n\t\t\t\treturn this.parseAndCorrect(attributes);\n\t\t\t},\n\t\t\t/**\n\t\t\t * @function\n\t\t\t * @param {array} attributes Attribute templates\n\t\t\t * @param {object} opts Request options\n\t\t\t */\n\t\t\tgetAttributeTemplatesForCategoryContext(attributes, opts) {\n\t\t\t\treturn this.parseAndCorrect(attributes);\n\t\t\t},\n\t\t\t/**\n\t\t\t * @function\n\t\t\t * @param {array} datasets Datasets\n\t\t\t * @param {object} opts Request options\n\t\t\t * @deprecated\n\t\t\t */\n\t\t\tgetDataSetList(datasets, opts) {\n\t\t\t\t// TODO: No! thise objects are nothin like our models whatsoever\n\t\t\t\t// it does not look like anything is using this\n\t\t\t\t// Deprecating\n\t\t\t\tconsole.warn('How do you like them errors in the console?');\n\t\t\t\tthis.set(datasets, opts);\n\t\t\t},\n\t\t\t/**\n\t\t\t * We have fetched our metadata map - which contains parallel arrays of importIds/importValues and exportIds/exportValues\n\t\t\t * @method\n\t\t\t * @param {object} metadataMap Metadata map data object\n\t\t\t * @param {object} opts Request options\n\t\t\t * @example\n\t\t\t * {\n\t\t\t * \"exportIds\": [],\n\t\t\t * \"exportImagePortalBlockOnProcess\": false,\n\t\t\t * \"exportImagePortalBlockOnSave\": false,\n\t\t\t * \"exportValues\": [],\n\t\t\t * \"importIds\": [\n\t\t\t * 7\n\t\t\t * ],\n\t\t\t * \"importValues\": [\n\t\t\t * \"ID3:Track\"\n\t\t\t * ],\n\t\t\t * \"modUserId\": 0\n\t\t\t * }\n\t\t\t */\n\t\t\t_getMetadataMap(metadataMap, opts) {\n\t\t\t\t// We want a true clone - no reference to one another\n\t\t\t\tthis.metadataMapArgs = JSON.parse(JSON.stringify(metadataMap));\n\t\t\t\t// We want a true clone - no reference to one another\n\t\t\t\tthis.metadataMap = JSON.parse(JSON.stringify(metadataMap));\n\t\t\t},\n\t\t\t/**\n\t\t\t * We have fetched our metadata map json - which is an array of schemas with an array options within\n\t\t\t * The result of this call is used to populate the metadata sync options available to a user who can manage attribute templates\n\t\t\t * @method\n\t\t\t * @param {array} metadata Metadata options array\n\t\t\t * @param {object} opts Request options\n\t\t\t * @example\n\t\t\t * [\n\t\t\t * {\n\t\t\t * \"label\": \"Dublin Core\",\n\t\t\t * \"options\": [\n\t\t\t * {\n\t\t\t * \"direction\": \"both\",\n\t\t\t * \"label\": \"Dublin Core contributor\",\n\t\t\t * \"value\": \"dc:contributor\"\n\t\t\t * },\n\t\t\t * {\n\t\t\t * \"direction\": \"import\",\n\t\t\t * \"label\": \"Dublin Core format\",\n\t\t\t * \"value\": \"dc:format\"\n\t\t\t * },\n\t\t\t * ...\n\t\t\t * ]\n\t\t\t * },\n\t\t\t * ...\n\t\t\t * ]\n\t\t\t */\n\t\t\tgetMetadataMapJson(metadata, opts) {\n\t\t\t\tthis.metadata = metadata;\n\t\t\t},\n\t\t\t/**\n\t\t\t * @function\n\t\t\t * @param {null} response Null\n\t\t\t * @param {array} ids IDs\n\t\t\t * @param {object} opts Request options\n\t\t\t */\n\t\t\tsetAttributeTemplateOrder(response, ids, opts) {\n\t\t\t\t// Correct our models `orderby`\n\t\t\t\tlet model;\n\t\t\t\t_.each(ids, (id, idx) => {\n\t\t\t\t\tmodel = this.get(id);\n\t\t\t\t\t// Set silently as we will sort after this\n\t\t\t\t\t// If we trigger a change on each one we can cause the ui to become sluggish\n\t\t\t\t\t// as it will trigger renders and all sorts of unneeded checks\n\t\t\t\t\tmodel && model.set('orderby', idx + 1, {silent: true});\n\t\t\t\t});\n\t\t\t\tthis.sort();\n\t\t\t},\n\t\t\t/**\n\t\t\t * Updates attribute templates metadata synchronization\n\t\t\t * @method\n\t\t\t * @param {object} opts Request options\n\t\t\t */\n\t\t\t_setMetadataMap(opts) {\n\t\t\t\t// We want a true clone - no reference to one another\n\t\t\t\tthis.metadataMap = JSON.parse(JSON.stringify(this.metadataMapArgs));\n\t\t\t},\n\t\t};\n\t}\n\n\t/**\n\t * @method\n\t * @param {array} attrs Attributes\n\t * @return {array}\n\t */\n\tparseAndCorrect(attrs) {\n\t\t// DAM-20153: this will one day be a feature of theme proper\n\t\tconst portal = getPortal();\n\t\tif (portal) {\n\t\t\tconst attributeIds = portal.get('attributeIds');\n\t\t\t// Right now the portal falls back to attribute -101 if no attributes are available\n\t\t\t// Due to attribute permission, this can happen regardless of what the server does\n\t\t\t// Though, the server should be enforcing that -100 and -101 are always returned until\n\t\t\t// we can properly address the hard coding in the portal\n\t\t\t// Also, the portal has no idea about clip only attributes\n\t\t\tconst filteredAttrs = attrs.filter(\n\t\t\t\t(attr) =>\n\t\t\t\t\tattributeIds.includes(attr.attributeid) &&\n\t\t\t\t\tattr.objectTypes.includes('asset'),\n\t\t\t);\n\t\t\tENFORCE_ATTRIBUTE_IDS.forEach((id) => {\n\t\t\t\tif (!filteredAttrs.find((attr) => attr.attributeid === id))\n\t\t\t\t\tfilteredAttrs.push(id);\n\t\t\t});\n\t\t\tattrs = filteredAttrs;\n\t\t}\n\n\t\treturn _.compact(\n\t\t\t_.map(attrs, (attr) => {\n\t\t\t\tlet attrName = attr.name;\n\n\t\t\t\t// We now allow some editing of system attributes as if they were regular attributes\n\t\t\t\t// turns out the server is not considering this data mandatory on their end\n\t\t\t\t// DAM-19292 - when this ticket is done we can remove this piece of code\n\t\t\t\tif ([-100, -101].includes(attr.attributeid)) {\n\t\t\t\t\tattr.mandatory = 1;\n\t\t\t\t\tattr.permission = currentUserMeetsUserLevel(UserLevel.MANAGER);\n\t\t\t\t}\n\n\t\t\t\tif (\n\t\t\t\t\t(attrName !== 'checksum' ||\n\t\t\t\t\t\tsession.getToken() ||\n\t\t\t\t\t\tchecksumEnabled()) &&\n\t\t\t\t\t(attrName !== 'expireDate' ||\n\t\t\t\t\t\tassetExpirationEnabled() ||\n\t\t\t\t\t\tsession.getToken()) &&\n\t\t\t\t\tattrName !== 'path' &&\n\t\t\t\t\tattrName !== 'modUser' &&\n\t\t\t\t\tattrName !== 'thumbPath'\n\t\t\t\t) {\n\t\t\t\t\tif (attr.system) {\n\t\t\t\t\t\tswitch (attrName) {\n\t\t\t\t\t\t\tcase 'fileSize':\n\t\t\t\t\t\t\t\tattrName = 'fileSize2';\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase 'creationDate':\n\t\t\t\t\t\t\t\tattrName = 'creationdate';\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase 'expireDate':\n\t\t\t\t\t\t\t\tattrName = 'expirationDate';\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase 'fileType':\n\t\t\t\t\t\t\t\tattrName = 'filetypelabel';\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase 'modDate':\n\t\t\t\t\t\t\t\tattrName = 'moddate';\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn _.extend(attr, {\n\t\t\t\t\t\tname: attrName,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}),\n\t\t);\n\t}\n\n\t/** @override */\n\tconstructor(models, opts = {}) {\n\t\topts.model =\n\t\t\topts.model ||\n\t\t\tfunction (attrs, opts) {\n\t\t\t\tconst typeName = types[attrs.type];\n\t\t\t\tconst modelClass = Models[typeName] || Models.base;\n\t\t\t\treturn new modelClass(attrs, opts);\n\t\t\t};\n\n\t\t// Circular\n\t\t//AssetAttributeDatumCollection = require('./assetAttributeDatum');\n\t\tsuper(models, opts);\n\n\t\t/**\n\t\t * For use with `getAttributeTemplatesForCategoryContext`\n\t\t * Only respected when `permission.attributesEnabled` is true\n\t\t * @memberOf Netx.Collections.Attributes\n\t\t * @todo Andrew has noted that we will be eventually only allowing a single id here\n\t\t * We do not use more than one id as of yet and should not moving forward. The request\n\t\t * method will just send the first id and console log a warning if there is more than\n\t\t * one present in the mean time.\n\t\t * @alias categoryIds\n\t\t * @type {number}\n\t\t */\n\t\tthis.categoryIds =\n\t\t\t(getPreference('permission.attributesEnabled', true) &&\n\t\t\t\topts.categoryIds) ||\n\t\t\t[];\n\n\t\t/**\n\t\t * @memberof module:asset/collections/attributes\n\t\t * @alias keepAlphabetical\n\t\t * @type {boolean}\n\t\t */\n\t\tthis.keepAlphabetical = getPreference(\n\t\t\t'metadata.keepListAlphabetical',\n\t\t\ttrue,\n\t\t);\n\n\t\t/**\n\t\t * Stores our metadata sync map\n\t\t * @type {object}\n\t\t * @default\n\t\t * @see this.getMetadataMap\n\t\t */\n\t\tthis.metadataMap = {\n\t\t\t// \"exportIds\": [\n\t\t\t// \t4,\n\t\t\t// \t5,\n\t\t\t// \t9\n\t\t\t// ],\n\t\t\t// \"exportImagePortalBlockOnProcess\": false,\n\t\t\t// \"exportImagePortalBlockOnSave\": false,\n\t\t\t// \"exportValues\": [\n\t\t\t// \t\"cdt:Type\",\n\t\t\t// \t\"fill:HasTransfo\",\n\t\t\t// \t\"pdf:Keywords\"\n\t\t\t// ],\n\t\t\t// \"importIds\": [\n\t\t\t// \t4,\n\t\t\t// \t5,\n\t\t\t// \t8\n\t\t\t// ],\n\t\t\t// \"importValues\": [\n\t\t\t// \t\"cdt:Type\",\n\t\t\t// \t\"fill:HasTransfo\",\n\t\t\t// \t\"ID3:Year\"\n\t\t\t// ],\n\t\t\t// \"modUserId\": 0\n\t\t};\n\n\t\t/**\n\t\t * Stores the metadata that is defined by the server as syncable\n\t\t * @type {array}\n\t\t * @default\n\t\t */\n\t\tthis.metadata = [\n\t\t\t// {\n\t\t\t// \t\"label\": \"Dublin Core\",\n\t\t\t// \t\"options\": [\n\t\t\t// \t\t{\n\t\t\t// \t\t\t\"direction\": \"both\",\n\t\t\t// \t\t\t\"label\": \"Dublin Core contributor\",\n\t\t\t// \t\t\t\"value\": \"dc:contributor\"\n\t\t\t// \t\t},\n\t\t\t// \t\t{\n\t\t\t// \t\t\t\"direction\": \"both\",\n\t\t\t// \t\t\t\"label\": \"Dublin Core coverage\",\n\t\t\t// \t\t\t\"value\": \"dc:coverage\"\n\t\t\t// \t\t}\n\t\t\t// \t]\n\t\t\t// }\n\t\t];\n\n\t\t/**\n\t\t * A clone of this.metadataMap (once fetched) so that we may make some comparisons\n\t\t * as to whether or not the metadata map needs saving - since it all gets saved at once\n\t\t * it can be quite expensive\n\t\t * @type {object}\n\t\t * @default\n\t\t * @see this.metadataMap\n\t\t */\n\t\tthis.metadataMapArgs = {\n\t\t\texportImagePortalBlockOnProcess: false,\n\t\t\texportImagePortalBlockOnSave: false,\n\t\t\texportIds: [],\n\t\t\texportValues: [],\n\t\t\timportIds: [],\n\t\t\timportValues: [],\n\t\t\tmodUserId: 0,\n\t\t};\n\n\t\t/**\n\t\t * @memberof module:asset/collections/attributes\n\t\t * @alias writableOnly\n\t\t * @type {boolean}\n\t\t */\n\t\tthis.writableOnly = opts.writableOnly === true;\n\n\t\t// Hey, listen!\n\t\tthis.listenTo(this, 'sync', (collection, results, opts) => {\n\t\t\t// Models sync too\n\t\t\tif (this !== collection) return;\n\n\t\t\tthis.stopListening(this, 'add change remove');\n\t\t\tthis.listenTo(this, 'add', this.attributeAdded);\n\t\t\tthis.listenTo(this, 'change', this.attributeChanged);\n\t\t\tthis.listenTo(this, 'remove', this.attributeRemoved);\n\t\t});\n\t}\n\n\t/**\n\t * @method\n\t * @param {Netx.Models.Attribute} model Attribute template model\n\t * @fires module:asset#asset:attribute:added\n\t */\n\tattributeAdded(model) {\n\t\t// Dispatch event\n\t\t// TODO: fix this, no dispatching from models/collections\n\t\tdispatcher.trigger('asset:attribute:added', model);\n\t}\n\n\t/**\n\t * @method\n\t * @param {Netx.Models.Attribute} model Attribute template model\n\t * @fires module:asset#asset:attribute:changed\n\t */\n\tattributeChanged(model) {\n\t\t// Dispatch event\n\t\t// TODO: fix this, no dispatching from models/collections\n\t\tdispatcher.trigger('asset:attribute:changed', model);\n\t}\n\n\t/**\n\t * @method\n\t * @param {Netx.Models.Attribute} model Attribute template model\n\t * @fires module:asset#asset:attribute:removed\n\t */\n\tattributeRemoved(model) {\n\t\t// Dispatch event\n\t\t// TODO: fix this, no dispatching from models/collections\n\t\tdispatcher.trigger('asset:attribute:removed', model);\n\t}\n\n\t/**\n\t * @method\n\t * @param {array} ids Array of attribute template ids\n\t */\n\tdeleteAttributes(ids) {\n\t\treturn this.deleteMultiple(ids);\n\t}\n\n\t/**\n\t * @method\n\t * @param {string} objectType Object type (asset/clip)\n\t */\n\tfilterByObjectType(objectType) {\n\t\tconst filter = () => {\n\t\t\treturn this.filter((model) => model.isForObjectType(objectType));\n\t\t};\n\n\t\t// When we change, so should the filtered collection\n\t\tconst collection = new this.constructor(filter());\n\t\treturn collection\n\t\t\t.listenTo(this, 'add', (attributes, attribute) => {\n\t\t\t\tcollection.add(attribute);\n\t\t\t})\n\t\t\t.listenTo(this, 'remove', (attributes, attribute) => {\n\t\t\t\tcollection.remove(attribute);\n\t\t\t})\n\t\t\t.listenTo(this, 'reset', (attributes) => {\n\t\t\t\tcollection.reset(filter());\n\t\t\t})\n\t\t\t.listenTo(this, 'sync', (attributes, data, opts) => {\n\t\t\t\tif (attributes !== this) return;\n\t\t\t\tcollection.set(filter(), opts);\n\t\t\t\tcollection.trigger('sync', collection);\n\t\t\t});\n\t}\n\n\t/**\n\t * @method\n\t * @param {array} types Types of attributes to return\n\t * @param {boolean} editableOnly Only return editable attributes\n\t * @return {Netx.Collection.Attributes}\n\t */\n\tfilterByTypes(types, editableOnly) {\n\t\t// Wrap\n\t\tif (!_.isArray(types)) {\n\t\t\ttypes = [types];\n\t\t}\n\n\t\t// For now we need to be the holders of this data\n\t\t// In 8.12 we will have flags on the templates themselves for this\n\t\tconst editableSystemAttributes = ['description', 'name'];\n\n\t\t// Support the user passing strings instead of type ids\n\t\t// Convert them over to type ids before going forward\n\t\ttypes = _.map(types, (type) =>\n\t\t\t!_.isNumeric(type) ? typeIds[type] : parseInt(type),\n\t\t);\n\n\t\t// Return filtered collection\n\t\treturn new this.constructor(\n\t\t\tthis.filter(\n\t\t\t\t(attr) =>\n\t\t\t\t\t// If we want only editable attributes then we need to omit any system attributes that cannot be edited - all other attribute types are editable by default\n\t\t\t\t\t_.contains(types, attr.get('type')) &&\n\t\t\t\t\t(!editableOnly ||\n\t\t\t\t\t\t!attr.get('system') ||\n\t\t\t\t\t\t_.contains(editableSystemAttributes, attr.get('name'))),\n\t\t\t),\n\t\t);\n\t}\n\n\t/**\n\t * @method\n\t * @return {module:asset/collections/attributes} Attributes tracking history\n\t */\n\tfilterByHistory() {\n\t\treturn new this.constructor(this.where({trackHistory: true}));\n\t}\n\n\t/**\n\t * @method\n\t * @return {module:asset/collections/assetAttributeDatum} Asset attribute datum\n\t */\n\tgetAttributeDatum(defaultValues) {\n\t\tconst attributeDatum = new AssetAttributeDatumCollection([\n\t\t\t{\n\t\t\t\tassetId: 0,\n\t\t\t\tattributes: [],\n\t\t\t},\n\t\t]);\n\n\t\tconst record = attributeDatum.at(0);\n\n\t\tthis.each((model) => {\n\t\t\tlet value = defaultValues ? model.get('value') : null;\n\n\t\t\tif (isEmptyValue(value)) {\n\t\t\t\tvalue = [];\n\t\t\t} else if (!_.isArray(value)) {\n\t\t\t\tvalue = [value];\n\t\t\t}\n\n\t\t\trecord.addAttribute({\n\t\t\t\tassetId: 0,\n\t\t\t\tmultivalue: model.get('multivalue'),\n\t\t\t\tpermission: 'w',\n\t\t\t\tvalues: value,\n\t\t\t\ttypeName: model.getTypeName(),\n\t\t\t\ttemplateId: model.id,\n\t\t\t\tname: model.get('name'),\n\t\t\t});\n\t\t});\n\n\t\treturn attributeDatum;\n\t}\n\n\t/**\n\t * For attr storage purposes: get an id for a name\n\t * Unfortunately in a lot of the old interface, attribute names were used over ids (diplayed attributes, attribute field sets etc)\n\t * @method\n\t * @param {string} name Attribute name\n\t * @return {number} Attribute id\n\t */\n\tgetIdByName(name) {\n\t\tconst attr = this.findWhere({name: name});\n\t\treturn attr ? attr.get('attributeid') : undefined;\n\t}\n\n\t/**\n\t * @method\n\t * @param {boolean} withoutDefaultValues Only return attributes without default values\n\t * @return {module:asset/collections/attributes}\n\t */\n\tgetMandatory(withoutDefaultValues, withoutSystem) {\n\t\treturn new this.constructor(\n\t\t\tthis.filter(\n\t\t\t\t(m) =>\n\t\t\t\t\tm.isMandatory() &&\n\t\t\t\t\t(!withoutDefaultValues || !m.hasDefaultValue()) &&\n\t\t\t\t\t(!withoutSystem || !m.get('system')),\n\t\t\t),\n\t\t);\n\t}\n\n\t/**\n\t * @method\n\t * @return {Netx.Collections.Attributes} Collection of system attributes\n\t */\n\tgetSystemAttributes() {\n\t\treturn new this.constructor(this.filter((attr) => attr.get('system')));\n\t}\n\n\t/**\n\t * Are there mandatory attributes?\n\t * @method\n\t * @return {array} List of attribute models that are mandatory, or 'undefined' (instead of empty array) if there are none.\n\t */\n\thasMandatory() {\n\t\tconst list = this.filter((m) => m.get('mandatory') == 1);\n\t\treturn list.length ? list : undefined;\n\t}\n\n\t/**\n\t * For asset sorting purposes, return an object of names of known attributes.\n\t * @method\n\t * @param {boolean} system Include system attributes\n\t * @return {object} names\n\t */\n\tnames(system) {\n\t\tconst names = {};\n\t\tthis.each((attr) => {\n\t\t\tif (system && attr.get('system') === true) {\n\t\t\t\tnames[attr.get('code')] = attr.get('name');\n\t\t\t} else if (attr.get('system') !== true) {\n\t\t\t\tnames[attr.get('name')] = attr.get('name');\n\t\t\t}\n\t\t});\n\t\treturn names;\n\t}\n\n\t/**\n\t * Vocabulary has been updated\n\t * @param {number} vocabularyId Vocabulary ID\n\t */\n\tupdatedVocabulary(vocabularyId) {\n\t\t// Every attribute that uses this vocab needs to be refetched\n\t\tthis.each((model) => {\n\t\t\tif (!vocabularyAttributes.includes(model.get('type'))) return;\n\t\t\tmodel.get('spec1') === vocabularyId && model.fetch();\n\t\t});\n\t}\n\n\t////////////////////////////////////\n\t// METADATA SYNC\n\t////////////////////////////////////\n\t/**\n\t * We have modified the metadata to sync on an attribute template\n\t * This is really fun - we do not have a call to simply update an attribute template's metadata sync parameters\n\t * we have to actually pass the whole updated thing at once - so we need to manually go through and deal with the parallel arrays\n\t * ourselves\n\t * @method\n\t * @param {module:asset/models/assetAttribute} model AssetAttribute model\n\t * @param {object} data Metadata sync data\n\t * @todo Get a call that can handle passing an array of attributes and their metadata sync values\n\t */\n\tattributeModifySyncMetadata(model, data) {\n\t\t// In this case, only `import` is allowed\n\t\tif (\n\t\t\tdata.syncMetadataType === '' &&\n\t\t\t!getPreference('share.metadata.roundtrip.enabled')\n\t\t) {\n\t\t\tdata.syncMetadataType = 'import';\n\t\t}\n\n\t\t// Find sync schema\n\t\tconst schema = _.findWhere(Netx.attributes.metadata, {\n\t\t\tlabel: data.syncMetadataSchema,\n\t\t});\n\n\t\t// For memory sake\n\t\tconst exportIds = this.metadataMapArgs.exportIds || [];\n\t\tconst exportValues = this.metadataMapArgs.exportValues || [];\n\t\tconst importIds = this.metadataMapArgs.importIds || [];\n\t\tconst importValues = this.metadataMapArgs.importValues || [];\n\n\t\tlet value, validDirections;\n\t\t// Mapped schema\n\t\tif (schema) {\n\t\t\t// Find sync value on sync schema options\n\t\t\tvalue = _.findWhere(schema.options, {value: data.syncMetadataValue});\n\t\t\t// Found sync value\n\t\t\tif (value) {\n\t\t\t\t// Check valid direction\n\t\t\t\tif (value.direction === 'both') {\n\t\t\t\t\tvalidDirections = ['both', 'export', 'import'];\n\t\t\t\t} else {\n\t\t\t\t\tvalidDirections = [value.direction];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// Assume custom schema\n\t\telse {\n\t\t\tvalidDirections = ['both', 'export', 'import'];\n\t\t}\n\n\t\t// Valid direction\n\t\tif (_.indexOf(validDirections, data.syncMetadataType) > -1) {\n\t\t\t// Find in imports\n\t\t\tconst importIdx = _.indexOf(this.metadataMap.importIds, model.id);\n\t\t\t// Find in exports\n\t\t\tconst exportIdx = _.indexOf(this.metadataMap.exportIds, model.id);\n\n\t\t\t// Is in the importIds array\n\t\t\tif (importIdx > -1) {\n\t\t\t\t// Is no longer valid as the directions do not match\n\t\t\t\tif (\n\t\t\t\t\tdata.syncMetadataType !== 'both' &&\n\t\t\t\t\tdata.syncMetadataType !== 'import'\n\t\t\t\t) {\n\t\t\t\t\timportIds.splice(importIdx, 1);\n\t\t\t\t\timportValues.splice(importIdx, 1);\n\t\t\t\t}\n\t\t\t\t// Update the value\n\t\t\t\telse {\n\t\t\t\t\timportValues.splice(importIdx, 1, data.syncMetadataValue);\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Is not in the importIds array\n\t\t\telse if (\n\t\t\t\tdata.syncMetadataType === 'both' ||\n\t\t\t\tdata.syncMetadataType === 'import'\n\t\t\t) {\n\t\t\t\timportIds.push(model.id);\n\t\t\t\timportValues.push(data.syncMetadataValue);\n\t\t\t}\n\t\t\t// Is in the exportIds array\n\t\t\tif (exportIdx > -1) {\n\t\t\t\t// Is no longer valid as the directions do not match\n\t\t\t\tif (\n\t\t\t\t\tdata.syncMetadataType !== 'both' &&\n\t\t\t\t\tdata.syncMetadataType !== 'export'\n\t\t\t\t) {\n\t\t\t\t\texportIds.splice(exportIdx, 1);\n\t\t\t\t\texportValues.splice(exportIdx, 1);\n\t\t\t\t}\n\t\t\t\t// Update the value\n\t\t\t\telse {\n\t\t\t\t\texportValues.splice(exportIdx, 1, data.syncMetadataValue);\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Is not in the exportIds array\n\t\t\telse if (\n\t\t\t\tdata.syncMetadataType === 'both' ||\n\t\t\t\tdata.syncMetadataType === 'export'\n\t\t\t) {\n\t\t\t\texportIds.push(model.id);\n\t\t\t\texportValues.push(data.syncMetadataValue);\n\t\t\t}\n\t\t}\n\t\t// Update on server\n\t\treturn this.setMetadataMap().then(() => {\n\t\t\tmodel.trigger('change', model);\n\t\t\tmodel.trigger('change:metadataSync', model, true);\n\t\t});\n\t}\n\n\t/**\n\t * Remove metadata sync from an attribute template\n\t * @method\n\t * @param {module:asset/models/assetAttribute} model AssetAttribute model\n\t */\n\tattributeRemoveSyncMetadata(model) {\n\t\tconst importIdx = _.indexOf(this.metadataMap.importIds, model.id);\n\t\tconst exportIdx = _.indexOf(this.metadataMap.exportIds, model.id);\n\t\tconst metadataMapArgs = this.metadataMapArgs;\n\n\t\t// Remove from import\n\t\tif (importIdx > -1) {\n\t\t\tmetadataMapArgs.importIds.splice(importIdx, 1);\n\t\t\tmetadataMapArgs.importValues.splice(importIdx, 1);\n\t\t}\n\t\t// Remove from export\n\t\tif (exportIdx > -1) {\n\t\t\tmetadataMapArgs.exportIds.splice(exportIdx, 1);\n\t\t\tmetadataMapArgs.exportValues.splice(exportIdx, 1);\n\t\t}\n\t\t// Update on server\n\t\treturn this.setMetadataMap().then(() => {\n\t\t\tmodel.trigger('change', model);\n\t\t\tmodel.trigger('change:metadataSync', model, false);\n\t\t});\n\t}\n\n\t/**\n\t * This fetches our metadata map json - which is an array of schemas with an array options within\n\t * The result of this call is used to populate the metadata sync options available to a user who can manage attribute templates\n\t * @method\n\t */\n\tgetMetadata() {\n\t\t// Should only need to fetch it once (and only for admins)\n\t\tif (!currentUserMeetsUserLevel(UserLevel.ADMIN) || this.metadata.length) {\n\t\t\treturn new $.Deferred().resolve(this.metadata);\n\t\t}\n\n\t\treturn this.getMetadataMapJson().then((response) => {\n\t\t\treturn this.metadata;\n\t\t});\n\t}\n\n\t/**\n\t * This fetches our metadata map - which contains parallel arrays of importIds/importValues and exportIds/exportValues\n\t * The values represent to the metadata to sync with the attribute and the ids are the attribute templates wishing to sync\n\t * If the same value and id match in the same position in both import and export, that is a round trip sync (both)\n\t * @method\n\t * @param {object} opts Request options\n\t */\n\tgetMetadataMap(opts) {\n\t\t// Should only need to fetch it once (and only for admins)\n\t\tif (\n\t\t\t!currentUserMeetsUserLevel(UserLevel.ADMIN) ||\n\t\t\t!_.isEmpty(this.metadataMap.length)\n\t\t) {\n\t\t\treturn new $.Deferred().resolve(this.metadataMap);\n\t\t}\n\n\t\treturn this._getMetadataMap(opts).then((response) => {\n\t\t\treturn this.metadataMap;\n\t\t});\n\t}\n\n\t/**\n\t * Updates the metadata to sync with attribute templates\n\t * @method\n\t * @param {object} opts Request options\n\t */\n\tsetMetadataMap(opts) {\n\t\t// Check if any updating is needed\n\t\tif (_.isEqual(this.metadataMap, this.metadataMapArgs)) {\n\t\t\treturn new $.Deferred().resolve(this.metadataMap);\n\t\t}\n\n\t\treturn this._setMetadataMap(opts).then((response) => {\n\t\t\treturn this.metadataMap;\n\t\t});\n\t}\n\t////////////////////////////////////\n\t// !METADATA SYNC\n\t////////////////////////////////////\n\n\t/** @type {string} */\n\tstatic get __name__() {\n\t\treturn 'Attributes';\n\t}\n}\n","import {i18n} from '@netx/core/i18n';\nimport _ from 'underscore';\nimport {consituentClipsEnabled} from '@netx/core-constituents/enablers';\n\nexport const ids = {\n\ttext: 1,\n\ttextarea: 2,\n\tselect: 3, // these often have spec1 = 4\n\tdate: 4,\n\tmultiselect: 5,\n\ttag: 6, // This requires the system property dataManager.enabled = true. Can be check with Netx.user.prefs.get('dataManager')['enabled']\n\tnumber: 7,\n\thierarchical: 8, // Stupid terrible beast\n\tsemantic: 12,\n\ttagVocab: 13,\n};\n\nexport let defaultAttributeColumns = [\n\t{code: 'name', name: i18n.t('i18n.name')},\n\t{code: 'filetypelabel', name: i18n.t('i18n.fileType')},\n\t{code: null, name: i18n.t('i18n.fileInfo')},\n\t{code: 'fileSize2', name: i18n.t('i18n.fileSize')},\n\t{code: 'creationdate', name: i18n.t('i18n.creationDate')},\n\t{code: null, name: i18n.t('i18n.status')},\n];\n\nexport const systemAttributes = [\n\t{code: 'name', key: 'name', id: -100, name: i18n.t('i18n.name')},\n\t{code: 'file', key: 'file', id: -101, name: i18n.t('i18n.file')},\n\t{code: 'assetId', key: 'assetId', id: -102, name: i18n.t('i18n.assetId')},\n\t{\n\t\tcode: 'fileSize2',\n\t\tkey: 'fileSize2',\n\t\tid: -104,\n\t\tname: i18n.t('i18n.fileSize'),\n\t},\n\t{\n\t\tcode: 'filetypelabel',\n\t\tkey: 'filetypelabel',\n\t\tid: -105,\n\t\tname: i18n.t('i18n.fileType'),\n\t},\n\t{\n\t\tcode: 'fileFormatFamily',\n\t\tkey: 'fileFormatFamily',\n\t\tid: -106,\n\t\tname: i18n.t('i18n.fileFormatFamily'),\n\t},\n\t{\n\t\tcode: 'categoryPaths',\n\t\tkey: 'folderPath',\n\t\tid: -108,\n\t\tname: i18n.t('i18n.folderPath'),\n\t},\n\t{code: 'moddate', key: 'moddate', id: -110, name: i18n.t('i18n.modDate')},\n\t{\n\t\tcode: 'creationdate',\n\t\tkey: 'creationdate',\n\t\tid: -111,\n\t\tname: i18n.t('i18n.creationDate'),\n\t},\n\t{\n\t\tcode: 'importDate',\n\t\tkey: 'importDate',\n\t\tid: -112,\n\t\tname: i18n.t('i18n.importDate'),\n\t},\n\t{\n\t\tcode: 'smart labels',\n\t\tkey: 'smart labels',\n\t\tid: -119,\n\t\tname: i18n.t('i18n.smartLabels'),\n\t},\n];\n\n// !!! hierarchical is not supported for edit !!!\n// !!! I REPEAT: hierarchical is not editable !!!\nexport let editable = [\n\t1, // text\n\t2, // textarea\n\t3, // select\n\t4, // date\n\t5, // multiselect\n\t6, // tag\n\t7, // number\n\t12, // semantic\n\t13, // tag (vocab)\n];\n\n// Attribute types that are allowed to be facets\nexport let facetAttributeSupport = [\n\t3, // Select\n\t5, // Multiselect\n\t6, // Tag\n\t13, // Tag (vocab)\n];\n\n// Attribute types that use vocabularies\nexport let vocabularyAttributes = [\n\t3, // Select\n\t5, // Multiselect\n\t6, // Tag\n\t13, // Tag (vocab)\n];\n\nexport let numberTypes = [\n\t{\n\t\tkey: 'whole',\n\t\tname: i18n.t('i18n.wholeNumber'),\n\t\tvalidator: '^-?\\\\d+$',\n\t\twarning: i18n.t('i18n.wholeNumberWarning'),\n\t},\n\t{\n\t\tkey: 'oneDecimal',\n\t\tname: i18n.t('i18n.oneDecimal'),\n\t\tvalidator: '^(-?\\\\d+(\\\\.\\\\d{0,1})?|-?\\\\.\\\\d{1})$',\n\t\twarning: i18n.t('i18n.oneDecimalWarning'),\n\t\tmaxDecimal: 1,\n\t},\n\t{\n\t\tkey: 'twoDecimals',\n\t\tname: i18n.t('i18n.twoDecimals'),\n\t\tvalidator: '^(-?\\\\d+(\\\\.\\\\d{0,2})?|-?\\\\.\\\\d{1,2})$',\n\t\twarning: i18n.t('i18n.twoDecimalsWarning'),\n\t\tmaxDecimal: 2,\n\t},\n\t{\n\t\tkey: 'threeDecimals',\n\t\tname: i18n.t('i18n.threeDecimals'),\n\t\tvalidator: '^(-?\\\\d+(\\\\.\\\\d{0,3})?|-?\\\\.\\\\d{1,3})$',\n\t\twarning: i18n.t('i18n.threeDecimalsWarning'),\n\t\tmaxDecimal: 3,\n\t},\n\t{\n\t\t// \"free,\" but not negative\n\t\tkey: 'unlimited',\n\t\tname: i18n.t('i18n.unlimited'),\n\t\tvalidator: '^\\\\d*\\\\.?\\\\d+$',\n\t\twarning: i18n.t('i18n.unlimitedWarning'),\n\t\tmaxDecimal: Infinity,\n\t},\n\t{\n\t\t// TODO: what is 'sortable' - should all number not be sortable ?\n\t\tkey: 'sortable',\n\t\tname: i18n.t('i18n.sortable'),\n\t\tvalidator: '.*',\n\t\twarning: '',\n\t\tmaxDecimal: Infinity,\n\t},\n];\n\n// Attribute object types asset/clip\n// See the dispatcher listener below for clip setup\nexport let objectTypes = [\n\t{\n\t\tkey: 'asset',\n\t\tlabel: i18n.t('i18n.asset'),\n\t},\n];\n\n// For the textTypes and numberTypes array, the array index is the value stored in the attribute spec field\n// (spec1 for text, spec2 for number)\nexport let textTypes = [\n\t{\n\t\tname: 'None',\n\t},\n\t{\n\t\tname: 'Clear',\n\t},\n];\n\nexport let typeLabels = {\n\tdate: i18n.t('i18n.date'),\n\thierarchical: i18n.t('i18n.hierarchical'),\n\tmultiselect: i18n.t('i18n.multiSelectBox'),\n\tnumber: i18n.t('i18n.number'),\n\tselect: i18n.t('i18n.pulldown'),\n\tsemantic: i18n.t('i18n.semantic'),\n\ttag: i18n.t('i18n.tag'),\n\ttagVocab: i18n.t('i18n.tagVocab'),\n\ttext: i18n.t('i18n.text'),\n\ttextarea: i18n.t('i18n.textarea'),\n};\n\nexport let types = _.invert(ids);\n\n// Update `objectTypes`\nif (consituentClipsEnabled()) {\n\tobjectTypes.push({\n\t\tkey: 'clip',\n\t\tlabel: i18n.t('i18n.assetConstituentClip'),\n\t});\n}\n\nexport default {\n\tdefaultAttributeColumns,\n\teditable,\n\tfacetAttributeSupport,\n\tnumberTypes,\n\tobjectTypes,\n\ttextTypes,\n\ttypes,\n};\n"],"names":["Models","base","BaseModel","date","DateModel","multiselect","MultiselectModel","number","NumberModel","select","SelectModel","semantic","SemanticModel","tag","TagModel","tagVocab","TagVocabModel","text","TextModel","textarea","TextareaModel","getPortal","_Netx$cms","_Netx$cms$portal","_Netx$cms2","isPortal","Netx","cms","portal","id","Attributes","Base","rpc","xhrTrackProgress","xhrLoadingMessages","getAttributeTemplates","getMetadataMapJson","xhrLoadedMessages","modelId","attrs","prototype","idAttribute","ids","omitSystem","this","pluck","filter","comparator","attrA","attrB","attributeIds","get","detailAttributes","hasUpdatedAttributesSystem","attributes","length","aIndex","indexOf","bIndex","keepAlphabetical","aName","toLowerCase","bName","aOrderby","bOrderby","methods","read","opts","categoryIds","getAttributeTemplatesForCategoryContext","then","set","when","getMetadata","getMetadataMap","getAllAttributeIds","getAttributeObjects","console","warn","writableOnly","getDataSetList","_getMetadataMap","setAttributeTemplateOrder","_setMetadataMap","metadataMapArgs","parsers","parseAndCorrect","datasets","metadataMap","JSON","parse","stringify","metadata","response","model","_","each","idx","silent","sort","filteredAttrs","attr","includes","attributeid","objectTypes","ENFORCE_ATTRIBUTE_IDS","find","push","compact","map","attrName","name","mandatory","permission","currentUserMeetsUserLevel","UserLevel","session","checksumEnabled","assetExpirationEnabled","system","extend","constructor","models","typeName","types","type","super","getPreference","exportImagePortalBlockOnProcess","exportImagePortalBlockOnSave","exportIds","exportValues","importIds","importValues","modUserId","listenTo","collection","results","stopListening","attributeAdded","attributeChanged","attributeRemoved","dispatcher","trigger","deleteAttributes","deleteMultiple","filterByObjectType","objectType","isForObjectType","attribute","add","remove","reset","data","filterByTypes","editableOnly","isArray","editableSystemAttributes","isNumeric","parseInt","typeIds","contains","filterByHistory","where","trackHistory","getAttributeDatum","defaultValues","attributeDatum","AssetAttributeDatumCollection","assetId","record","at","value","isEmptyValue","addAttribute","multivalue","values","getTypeName","templateId","getIdByName","findWhere","undefined","getMandatory","withoutDefaultValues","withoutSystem","m","isMandatory","hasDefaultValue","getSystemAttributes","hasMandatory","list","names","updatedVocabulary","vocabularyId","vocabularyAttributes","fetch","attributeModifySyncMetadata","syncMetadataType","schema","label","syncMetadataSchema","validDirections","options","syncMetadataValue","direction","importIdx","exportIdx","splice","setMetadataMap","attributeRemoveSyncMetadata","$","Deferred","resolve","isEmpty","isEqual","__name__","hierarchical","defaultAttributeColumns","code","i18n","systemAttributes","key","facetAttributeSupport","numberTypes","validator","warning","maxDecimal","Infinity","consituentClipsEnabled","editable","textTypes"],"sourceRoot":""}