Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
constructor(config, adminMeta, views) {
this.config = config;
this.adminMeta = adminMeta;
// TODO: undo this
Object.assign(this, config);
this.fields = config.fields.map(fieldConfig => {
const [Controller] = adminMeta.readViews([views[fieldConfig.path].Controller]);
return new Controller(fieldConfig, this, adminMeta, views[fieldConfig.path]);
});
this._fieldsByPath = arrayToObject(this.fields, 'path');
this.createMutation = gql`
mutation create($data: ${this.gqlNames.createInputName}!) {
${this.gqlNames.createMutationName}(data: $data) {
id
_label_
}
}
`;
this.createManyMutation = gql`
mutation createMany($data: ${this.gqlNames.createManyInputName}!) {
${this.gqlNames.createManyMutationName}(data: $data) {
id
}
}
`;
getAdminMeta({ schemaName }) {
// We've consciously made a design choice that the `read` permission on a
// list is a master switch in the Admin UI (not the GraphQL API).
// Justification: If you want to Create without the Read permission, you
// technically don't have permission to read the result of your creation.
// If you want to Update an item, you can't see what the current values
// are. If you want to delete an item, you'd need to be given direct
// access to it (direct URI), but can't see anything about that item. And
// in fact, being able to load a page with a 'delete' button on it
// violates the read permission as it leaks the fact that item exists.
// In all these cases, the Admin UI becomes unnecessarily complex.
// So we only allow all these actions if you also have read access.
const lists = arrayToObject(
this.listsArray.filter(list => list.access[schemaName].read && !list.isAuxList),
'key',
list => list.getAdminMeta({ schemaName })
);
return { lists, name: this.name };
}
async _processNonRealFields(data, processFunction) {
return resolveAllKeys(
arrayToObject(
Object.entries(omit(data, this.realKeys)).map(([path, value]) => ({
path,
value,
adapter: this.fieldAdaptersByPath[path],
})),
'path',
processFunction
)
);
}
list: { fields },
createItem,
isLoading,
} = this.props;
if (isLoading) return;
const { item, validationErrors, validationWarnings } = this.state;
if (countArrays(validationErrors)) {
return;
}
const creatable = fields
.filter(({ isPrimaryKey }) => !isPrimaryKey)
.filter(({ maybeAccess }) => !!maybeAccess.create);
const data = arrayToObject(creatable, 'path', field => field.serialize(item));
if (!countArrays(validationWarnings)) {
const { errors, warnings } = await validateFields(creatable, item, data);
if (countArrays(errors) + countArrays(warnings) > 0) {
this.setState(() => ({
validationErrors: errors,
validationWarnings: warnings,
}));
return;
}
}
createItem({
variables: { data },
onUpdate = async () => {
const { updateItem, isLoading, items } = this.props;
const { item, selectedFields, validationErrors, validationWarnings } = this.state;
if (isLoading) return;
if (countArrays(validationErrors)) {
return;
}
const data = arrayToObject(selectedFields, 'path', field => field.serialize(item));
if (!countArrays(validationWarnings)) {
const { errors, warnings } = await validateFields(selectedFields, item, data);
if (countArrays(errors) + countArrays(warnings) > 0) {
this.setState(() => ({
validationErrors: errors,
validationWarnings: warnings,
}));
return;
}
}
updateItem({
variables: {
onChange = selected => {
const { fields: listFields, isMulti, onChange } = this.props;
const arr = Array.isArray(selected) ? selected : [selected];
const diffMap = arrayToObject(arr, 'path', () => true);
const fields = [pseudoLabelField].concat(listFields).filter(i => diffMap[i.path]);
const value = isMulti ? fields : fields[0];
onChange(value);
};
this.getFieldsObject = memoizeOne(() =>
arrayToObject(
props.list.fields
.filter(({ isPrimaryKey }) => !isPrimaryKey)
.filter(({ isReadOnly }) => !isReadOnly)
.filter(({ maybeAccess }) => !!maybeAccess.update),
'path'
)
);