import {getTableId} from 'app/common/DocActions'; import {EmptyRecordView, RecordView} from 'app/common/RecordView'; import {Role} from 'app/common/roles'; /** * Information about a user, including any user attributes. */ export interface UserInfo { Name: string | null; Email: string | null; Access: Role | null; Origin: string | null; LinkKey: Record; UserID: number | null; UserRef: string | null; SessionID: string | null; /** * This is a rowId in the _grist_Shares table, if the user is accessing a document * via a share. Otherwise null. */ ShareRef: number | null; [attributes: string]: unknown; } /** * Wrapper class for `UserInfo`. * * Contains methods for converting itself to different representations. */ export class User implements UserInfo { public Name: string | null = null; public UserID: number | null = null; public Access: Role | null = null; public Origin: string | null = null; public LinkKey: Record = {}; public Email: string | null = null; public SessionID: string | null = null; public UserRef: string | null = null; public ShareRef: number | null = null; [attribute: string]: any; constructor(info: Record = {}) { Object.assign(this, info); } /** * Returns a JSON representation of this class that excludes full row data, * only keeping user info and table/row ids for any user attributes. * * Used by the sandbox to support `user` variables in formulas (see `user.py`). */ public toJSON() { return this._toObject((value) => { if (value instanceof RecordView) { return [getTableId(value.data), value.get('id')]; } else if (value instanceof EmptyRecordView) { return null; } else { return value; } }); } /** * Returns a record representation of this class, with all user attributes * converted from `RecordView` instances to their JSON representations. * * Used by the client to support `user` variables in dropdown conditions. */ public toUserInfo(): UserInfo { return this._toObject((value) => { if (value instanceof RecordView) { return value.toJSON(); } else if (value instanceof EmptyRecordView) { return null; } else { return value; } }) as UserInfo; } private _toObject(mapValue: (value: unknown) => unknown) { const results: {[key: string]: any} = {}; for (const [key, value] of Object.entries(this)) { results[key] = mapValue(value); } return results; } }