diff --git a/react/src/pages/EditBox.js b/react/src/pages/EditBox.js index 74357914f..53c2d2b38 100644 --- a/react/src/pages/EditBox.js +++ b/react/src/pages/EditBox.js @@ -38,7 +38,7 @@ const DynamicSelect = (props) => { { props.subComponent && <> @@ -57,21 +57,21 @@ const InputLine = (props) => { { (input.readonlyOverridableOnCreate && props.isCreate) && <> -    +    { readonly ? <> setReadonly(false)}> :<> setReadonly(true)}>    } - + { (input.readonlyOverridableOnCreate && !readonly && input.readonlyOverridableOnCreateMessage) && <>
@@ -143,7 +143,7 @@ const EditBox = ({ inputs, setInputs, title, loading, onCreate, onUpdate, onDele function setFocus() { for (const input of inputs) { - const element = document.getElementById(input.name); + const element = document.getElementById(input.key); if (input.focus) { element.focus(); } @@ -170,12 +170,12 @@ const EditBox = ({ inputs, setInputs, title, loading, onCreate, onUpdate, onDele const input = getInputByName(e.target.id); if (input.required) { const currentValue = e.target.value?.toString(); - inputsRequiredStatus[input.name] = (currentValue?.toString()?.length > 0); + inputsRequiredStatus[input.key] = (currentValue?.toString()?.length > 0); setInputsRequiredStatus(current => ({...inputsRequiredStatus})); } if (input.type === "email") { const currentValue = e.target.value?.toString(); - inputsRequiredStatus[input.name] = isValidEmail(currentValue); + inputsRequiredStatus[input.key] = isValidEmail(currentValue); setInputsRequiredStatus(current => ({...inputsRequiredStatus})); } // @@ -191,7 +191,7 @@ const EditBox = ({ inputs, setInputs, title, loading, onCreate, onUpdate, onDele const dependentInputs = getInputDependencies(input); for (const dependentInput of dependentInputs) { if (typeof(dependentInput.value) === "function") { - const dependentElement = document.getElementById(dependentInput.name); + const dependentElement = document.getElementById(dependentInput.key); if (dependentElement) { const dependentValue = dependentInput.value(e.target.value?.toString()); if (dependentValue !== undefined) { @@ -207,7 +207,7 @@ const EditBox = ({ inputs, setInputs, title, loading, onCreate, onUpdate, onDele function getInputDependencies(input) { const results = []; if (input) { - const inputName = input.name; + const inputName = input.key; for (const input of inputs) { if (input.dependsOn === inputName) { results.push(input); @@ -217,9 +217,9 @@ const EditBox = ({ inputs, setInputs, title, loading, onCreate, onUpdate, onDele return results; } - function getInputByName(name) { + function getInputByName(key) { for (const input of inputs) { - if (input.name === name) { + if (input.key === key) { return input; } } @@ -232,7 +232,7 @@ const EditBox = ({ inputs, setInputs, title, loading, onCreate, onUpdate, onDele continue; } const originalValue = valueOf(input); - const element = document.getElementById(input.name); + const element = document.getElementById(input.key); const currentValue = element.value?.toString(); if (originalValue?.toString() !== currentValue?.toString()) { return true; @@ -243,7 +243,7 @@ const EditBox = ({ inputs, setInputs, title, loading, onCreate, onUpdate, onDele function resetInputValuesToOriginal() { for (const input of inputs) { - const element = document.getElementById(input.name); + const element = document.getElementById(input.key); if (element) { element.value = valueOf(input); } @@ -254,12 +254,12 @@ const EditBox = ({ inputs, setInputs, title, loading, onCreate, onUpdate, onDele function gatherCurrentInputValues() { const values = {} for (const input of inputs) { - let value = document.getElementById(input.name).value; + let value = document.getElementById(input.key).value; if (!input.readonly || (input.readonlyOverridableOnCreate && Str.HasValue(value))) { if (input.type === "boolean") { value = (value.toString().toLowerCase() === "true") ? true : false; } - values[input.name] = value; + values[input.key] = value; } } return values; @@ -291,17 +291,17 @@ const EditBox = ({ inputs, setInputs, title, loading, onCreate, onUpdate, onDele const inputsRequiredStatus = {}; for (const input of inputs) { if (input.required) { - inputsRequiredStatus[input.name] = document.getElementById(input.name)?.value?.toString()?.length > 0; + inputsRequiredStatus[input.key] = document.getElementById(input.key)?.value?.toString()?.length > 0; } if (input.type === "email") { - inputsRequiredStatus[input.name] = isValidEmail(document.getElementById(input.name)?.value?.toString()); + inputsRequiredStatus[input.key] = isValidEmail(document.getElementById(input.key)?.value?.toString()); } } setInputsRequiredStatus(inputsRequiredStatus); } function inputRequiredIndicatorColor(input) { - return inputsRequiredStatus[input.name] ? "green" : "red"; + return inputsRequiredStatus[input.key] ? "green" : "red"; } function allowSubmit() { @@ -332,14 +332,14 @@ const EditBox = ({ inputs, setInputs, title, loading, onCreate, onUpdate, onDele { input.type === "boolean" ? <> - :<> { input.type === "select" ? <> <> + {user.name}
+ {user.email}
+ {user.uuid} + }, { - name: "first_name", + key: "first_name", label: "First Name", required: true, + pages: [ "view", "edit", "create" ] }, { - name: "last_name", + key: "last_name", label: "Last Name", required: true, + pages: [ "view", "edit", "create" ] }, { - name: "group_titles", + key: "group_titles", label: "Groups", - pages: [ "view" ] + pages: [ "list", "view" ] }, { - name: "admin", + key: "admin", label: "Administrator", type: "boolean", pages: [ "edit" ] }, { - name: "status", + key: "status", label: "Status", type: "select", url: "/users/statuses", + mapWithUser: true, + map: (user) => user.status_title, pages: [ "list", "view", "edit" ] }, { - name: "created", + key: "created", label: "Created", + type: "datetime", readonly: true, map: value => DateTime.Format(value), pages: [ "list", "view", "edit" ] }, { - name: "updated", + key: "updated", label: "Updated", + type: "datetime", readonly: true, map: value => DateTime.Format(value), pages: [ "list", "view", "edit" ] }, { - name: "uuid", + key: "uuid", label: "UUID", readonly: true, readonlyOverridableOnCreate: true, @@ -73,35 +85,35 @@ const _UserInputsCommon = [ const _UserInputs = [ { - name: "email", + key: "email", label: "Email Address", type: "email", focus: true, required: true }, { - name: "first_name", + key: "first_name", label: "First Name", required: true, }, { - name: "last_name", + key: "last_name", label: "Last Name", required: true, }, { - name: "group_titles", + key: "group_titles", label: "Groups", pages: [ "view" ] }, { - name: "admin", + key: "admin", label: "Administrator", type: "boolean", pages: [ "edit" ] }, { - name: "role", + key: "role", label: "Role", type: "select", url: "/users/roles", @@ -110,7 +122,7 @@ const _UserInputs = [ pages: [ "list", "view", "edit" ] }, { - name: "institution", + key: "institution", label: "Institution", type: "select", url: "/users/institutions", @@ -120,7 +132,7 @@ const _UserInputs = [ pages: [ "list", "view", "edit" ] }, { - name: "project", + key: "project", label: "Project", type: "select", url: "/users/projects", @@ -128,7 +140,7 @@ const _UserInputs = [ pages: [ "list", "view", "edit" ] }, { - name: "award", + key: "award", label: "Award", type: "select", url: "/users/awards", @@ -137,7 +149,7 @@ const _UserInputs = [ pages: [ "list", "view", "edit" ] }, { - name: "lab", + key: "lab", label: "Lab", type: "select", url: "/users/labs", @@ -145,7 +157,7 @@ const _UserInputs = [ pages: [ "list", "view", "edit" ] }, { - name: "consortium", + key: "consortium", label: "Consortium", type: "select", url: "/users/consortia", @@ -154,7 +166,7 @@ const _UserInputs = [ pages: [ "list", "view", "edit" ] }, { - name: "submission_center", + key: "submission_center", label: "Submission Center", type: "select", url: "/users/submission_centers", @@ -162,28 +174,28 @@ const _UserInputs = [ pages: [ "list", "view", "edit" ] }, { - name: "status", + key: "status", label: "Status", type: "select", url: "/users/statuses", pages: [ "list", "view", "edit" ] }, { - name: "created", + key: "created", label: "Created", readonly: true, map: value => DateTime.Format(value), pages: [ "list", "view", "edit" ] }, { - name: "updated", + key: "updated", label: "Updated", readonly: true, map: value => DateTime.Format(value), pages: [ "list", "view", "edit" ] }, { - name: "uuid", + key: "uuid", label: "UUID", readonly: true, readonlyOverridableOnCreate: true, @@ -232,40 +244,49 @@ const _userInfo = { inputs: function () { const affiliationInfo = _userInfo[Env.FoursightTitleCgap].useAffiliationInfo(); const inputsAdditional = [ - { label: "Role", name: "role", mapWithUser: true, + { label: "Role", key: "role", type: "select", + url: "/users/roles", + dependsOn: "project", + mapWithUser: true, map: (user, value) => affiliationInfo.userRoleTitle(user, user.project) }, - { label: "Project", name: "project", + { label: "Project", key: "project", type: "select", + url: "/users/projects", + dependsOn: "project", map: value => affiliationInfo.projectTitle(value) }, - { label: "Institution", name: "institution", + { label: "Institution", key: "institution", type: "select", + url: "/users/institutions", + dependsOn: "institution", map: value => affiliationInfo.institutionTitle(value), subComponent: (institution) => }, - { label: "Roles", name: "roles", + { label: "Roles", key: "roles", ui: (user) => , toggle: true, - pages: [ "view", "edit" ] } + pages: [ "view" ] } ]; const inputs = [ ..._UserInputsCommon ]; - const index = inputs.findIndex((item) => item.name === "status"); + const index = inputs.findIndex((item) => item.key === "status"); inputs.splice(index, 0, ...inputsAdditional); return inputs; }, +/* affiliations: function (edit = false) { const affiliationInfo = _userInfo[Env.FoursightTitleCgap].useAffiliationInfo(); return [ - { label: "Role", name: "project", mapWithUser: true, + { label: "Role", key: "project", mapWithUser: true, //map: value => affiliationInfo.roleTitle(value) }, map: (user, value) => affiliationInfo.userRoleTitle(user, value) }, - { label: "Project", name: "project", + { label: "Project", key: "project", map: value => affiliationInfo.projectTitle(value) }, - { label: "Institution", name: "institution", + { label: "Institution", key: "institution", map: value => affiliationInfo.institutionTitle(value), subComponent: (institution) => }, - { label: "Roles", name: "roles", + { label: "Roles", key: "roles", ui: (user) => , toggle: true, flavors: [Env.FoursightTitleCgap], pages: [ "view", "edit" ] } ]; }, +*/ useAffiliationInfo: function () { const projects = useFetch("/users/projects", { cache: true }); const roles = useFetch("/users/roles", { cache: true }); @@ -275,7 +296,9 @@ const _userInfo = { roleTitle: (id) => roles.data?.find(item => item.id === id)?.title || "", institutionTitle: (id) => institutions.data?.find(item => item.id === id)?.title || "", userRole: (user, projectId) => user.roles?.find(item => item.project === projectId)?.role || "", - principleInvestigator: (institutionId) => institutions?.data?.find(item => item.id === institutionId)?.pi + principleInvestigator: (institutionId) => { + return institutions?.data?.find(item => item.id === institutionId)?.pi + } } response.userRoleTitle = (user, projectId) => response.roleTitle(response.userRole(user, projectId)) || ""; return response; @@ -346,9 +369,9 @@ const _userInfo = { affiliations: function (edit = false) { const affiliationInfo = _userInfo[Env.FoursightTitleSmaht].useAffiliationInfo(); return [ - { label: "Consortium", key: "consortium", name: "consortium", + { label: "Consortium", key: "consortium", key: "consortium", map: value => affiliationInfo.consortiumTitle(value) }, - { label: "Submission Center", key: "submission_center", name: "submission_center", + { label: "Submission Center", key: "submission_center", key: "submission_center", map: value => affiliationInfo.submissionCenterTitle(value) } ]; }, @@ -386,7 +409,7 @@ const useUserInfo = () => { const statuses = useFetch("/users/statuses", { cache: false }); userInfo.normalizeUser = (user) => { user.name = `${user.first_name} ${user.last_name}`.trim(); - if (Str.HasValue(user.title) && user.title !== user.name) { + if (Str.HasValue(user.title) && user.title !== user.key) { user.name = user.title; } user.group_titles = Str.StringArrayToCommaSeparatedListOfTitles(user.groups); diff --git a/react/src/pages/UserEditPage.js b/react/src/pages/UserEditPage.js index 8f8a4065c..f8c64b88a 100644 --- a/react/src/pages/UserEditPage.js +++ b/react/src/pages/UserEditPage.js @@ -41,21 +41,21 @@ const UserEditPage = () => { */ setInputs(inputs => { for (const input of inputs) { - if (input.name === "email") input.value = user.email; - else if (input.name === "first_name") input.value = user.first_name; - else if (input.name === "last_name") input.value = user.last_name; - else if (input.name === "admin") input.value = user.groups?.includes("admin") ? true : false; - else if (input.name === "role") input.value = (project) => affiliationInfo.userRole(user, project || user?.project); - else if (input.name === "project") input.value = user.project; - else if (input.name === "institution") input.value = user.institution; - else if (input.name === "award") input.value = user.award; - else if (input.name === "lab") input.value = user.lab; - else if (input.name === "consortium") input.value = user.consortia; - else if (input.name === "submission_center") input.value = user.submission_center; - else if (input.name === "status") input.value = user.status; - else if (input.name === "created") input.value = DateTime.Format(user.created); - else if (input.name === "updated") input.value = DateTime.Format(user.updated); - else if (input.name === "uuid") input.value = user.uuid; + if (input.key === "email") input.value = user.email; + else if (input.key === "first_name") input.value = user.first_name; + else if (input.key === "last_name") input.value = user.last_name; + else if (input.key === "admin") input.value = user.groups?.includes("admin") ? true : false; + else if (input.key === "role") input.value = (project) => affiliationInfo.userRole(user, project || user?.project); + else if (input.key === "project") input.value = user.project; + else if (input.key === "institution") input.value = user.institution; + else if (input.key === "award") input.value = user.award; + else if (input.key === "lab") input.value = user.lab; + else if (input.key === "consortium") input.value = user.consortia; + else if (input.key === "submission_center") input.value = user.submission_center; + else if (input.key === "status") input.value = user.status; + else if (input.key === "created") input.value = DateTime.Format(user.created); + else if (input.key === "updated") input.value = DateTime.Format(user.updated); + else if (input.key === "uuid") input.value = user.uuid; } return [...inputs]; }); diff --git a/react/src/pages/UserPage.js b/react/src/pages/UserPage.js index 3230f7f3b..18338c37e 100644 --- a/react/src/pages/UserPage.js +++ b/react/src/pages/UserPage.js @@ -45,7 +45,7 @@ const KeyValueBox = (props) => { const [ toggle, setToggle ] = useState({}); return
- {props.inputs.map((key, i) => + {props.inputs.map((key, i) => { props.separators && i > 0 && <> @@ -71,16 +71,15 @@ const KeyValueBox = (props) => { : setToggle(value => ({...value, [key.label]: true}))}> Show {Char.UpArrowHollow} } - foo :<> { key.mapWithUser ? <> - {(Type.IsFunction(key.map) ? key.map(props.value, props.value[key.name]) : props.value[key.name]) || Char.EmptySet} + {(Type.IsFunction(key.map) ? key.map(props.value, props.value[key.key]) : props.value[key.key]) || Char.EmptySet} :<> - {(Type.IsFunction(key.map) ? key.map(props.value[key.name]) : props.value[key.name]) || Char.EmptySet} + {(Type.IsFunction(key.map) ? key.map(props.value[key.key]) : props.value[key.key]) || Char.EmptySet} } } { key.subComponent && <> -
{key.subComponent(props.value[key.name])} +
{key.subComponent(props.value[key.key])} } diff --git a/react/src/pages/UsersPage.js b/react/src/pages/UsersPage.js index d62ca2430..1178e5f38 100644 --- a/react/src/pages/UsersPage.js +++ b/react/src/pages/UsersPage.js @@ -47,7 +47,8 @@ const UsersPage = () => { if (users.error) return - let columns = [ +/* + let xcolumns = [ { label: "" }, { label: "User", key: "email" }, { label: "Groups", key: "groups" }, @@ -56,7 +57,8 @@ const UsersPage = () => { { label: "Updated", key: "data_modified" }, // DOES NOT WORK (nested in last_modified) { label: "Created", key: "date_created" } ]; - columns = [ { label: "" }, ...inputs ]; +*/ + let columns = [ { label: "" }, ...inputs ]; const tdStyle = { verticalAlign: "top", paddingRight: "6pt", paddingTop: "4pt", paddingBottom: "8pt" }; const tdStyleNowrap = { ...tdStyle, whiteSpace: "nowrap" }; @@ -149,14 +151,32 @@ const UsersPage = () => { initialSort={"email.asc"}> {users.map("list", (user, index) => ( - - + { columns.map(column => <> + + )}
- {parseInt(args.get("offset")) + index + 1}. - - {user.name}
- {user.email}
- {user.uuid} -
+ { column.uiList ? <> + {column.uiList(user)} + :<> + { column.key ? <> + { column.type === "datetime" ? <> + {Date.Format(user[column.key])}
+ {Time.Format(user[column.key])} + :<> + { column.map ? <> + { column.mapWithUser ? <> + {column.map(user)} + :<> + {column.map(user[column.key], userInfo)} + } + :<> + {user[column.key]} + } + } + :<> + {parseInt(args.get("offset")) + index + 1}. + } + } +
{user.group_titles}