Skip to content

Commit

Permalink
Merge pull request #1491 from hubmapconsortium/collectionPublish
Browse files Browse the repository at this point in the history
Collection publish
  • Loading branch information
yuanzhou authored Oct 21, 2024
2 parents ccd689c + 0fc666a commit f95042d
Show file tree
Hide file tree
Showing 3 changed files with 202 additions and 13 deletions.
78 changes: 70 additions & 8 deletions src/src/components/collections/collections.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import "../../App.css";
import SearchComponent from "../search/SearchComponent";
import {COLUMN_DEF_MIXED,COLUMN_DEF_MIXED_SM} from "../search/table_constants";
import { entity_api_get_entity,entity_api_create_entity, entity_api_update_entity} from '../../service/entity_api';
import {ingest_api_publish_collection,ingest_api_user_admin} from '../../service/ingest_api';
import { getPublishStatusColor } from "../../utils/badgeClasses";
import { generateDisplaySubtypeSimple_UBKG } from "../../utils/display_subtypes";
import Papa from 'papaparse';
Expand All @@ -15,15 +16,15 @@ import Dialog from "@material-ui/core/Dialog";
import DialogActions from "@material-ui/core/DialogActions";
import DialogContent from "@material-ui/core/DialogContent";
import GroupModal from "../uuid/groupModal";

import LoadingButton from '@mui/lab/LoadingButton';
import Table from '@mui/material/Table';
import TableBody from '@mui/material/TableBody';
import TableCell from '@mui/material/TableCell';
import TableContainer from '@mui/material/TableContainer';
import TableHead from '@mui/material/TableHead';
import TableRow from '@mui/material/TableRow';
import {DataGrid,GridToolbar} from "@mui/x-data-grid";

import {ErrBox} from "../../utils/ui_elements";
import Alert from '@mui/material/Alert';
import Collapse from '@mui/material/Collapse';
import LinearProgress from '@material-ui/core/LinearProgress';
Expand All @@ -48,20 +49,29 @@ export function CollectionForm (props){
var [associatedEntities, setassociatedEntities] = useState([]);
var [associatedEntitiesInitial, setassociatedEntitiesInitial] = useState([]);
var [selectedSources, setSelectedSources] = useState([]);
var [publishing, setPublishing] = useState(false);
var [fileDetails, setFileDetails] = useState();
var [buttonState, setButtonState] = useState('');
var [warningOpen, setWarningOpen] = React.useState(false);
var [openGroupModal, setOpenGroupModal] = useState(false


);
var [openGroupModal, setOpenGroupModal] = useState(false);
var [lookupShow, setLookupShow] = useState(false);
var [loadingDatasets, setLoadingDatasets] = useState(true);
var [hideUUIDList, setHideUUIDList] = useState(true);
var [loadUUIDList, setLoadUUIDList] = useState(false);
var [validatingSubmitForm, setValidatingSubmitForm] = useState(false);
var [entityInfo, setEntityInfo] = useState();
var [userAdmin, setUserAdmin] = useState(false);
var [pageError, setPageError] = useState("");
// var [publishError, setPublishError] = useState({
// status:"",
// message:"",
// });
// @TODO: See what we can globalize/memoize/notize here
var [errorHandler, setErrorHandler] = useState({
status: "",
message: "",
isError: null
});
var [formWarnings, setFormWarnings] = useState({
bulk_dataset_uuids:""
});
Expand All @@ -87,6 +97,18 @@ export function CollectionForm (props){
var [datatypeList] = useState(props.dtl_all);
var [editingCollection] = useState(props.editingCollection);


useEffect(() => {
ingest_api_user_admin(JSON.parse(localStorage.getItem("info")).groups_token)
.then((results) => {
console.debug('%c◉ ADMINCHECK ', 'color:#3F007b', results);
setUserAdmin(results)
})
.catch((err) => {
console.debug('%c⭗', 'color:#1f005d', "ingest_api_user_admin ERR", err );
})
}, []);

useEffect(() => {
if (editingCollection) {
setassociatedEntities([])
Expand Down Expand Up @@ -456,6 +478,27 @@ export function CollectionForm (props){
});
}

const handlePublish = () => {
setPublishing(true)
ingest_api_publish_collection(props.authToken,editingCollection.uuid)
.then((response) => {
if(response.status === 200){
console.debug('%c◉ Good ingest_api_publish_collection ', 'color:#00ff7b', response);
props.onProcessed(response.results);
}else{
console.debug('%c◉ ingest_api_publish_collection Bad result', 'color:#ff337b', response);
setPublishing(false)
let authMessage = response.status === 401 ? "User must be Authorized" : response.results.error.toString();
setPageError(response.status + " | " + authMessage);
}
})
.catch((error) => {
console.debug('%c⭗ handlePublishErr Broken Result', 'color:#ff005d', error);
setPageError(error.status + " | " + error.message);
setPublishing(false);
});
}

const handleUpdate = (formSubmit) => {
// Need to only pass what's changed now
console.debug('%c◉ formSubmit ', 'color:#00ff7b',formSubmit );
Expand Down Expand Up @@ -876,6 +919,18 @@ export function CollectionForm (props){
value={formValues.title}
/>
</FormControl>
{editingCollection && editingCollection.doi_url && (
<FormControl>
<TextField
label="DOI url"
name="DOIurl"
id="DOIurl"
disabled={true}
variant="standard"
value={editingCollection.doi_url}
/>
</FormControl>
)}
<FormControl>
<TextField
label="Description"
Expand All @@ -891,15 +946,13 @@ export function CollectionForm (props){
value={formValues.description}
/>
</FormControl>

<FormControl>
<Typography sx={{ color: 'rgba(0, 0, 0.2, 0.6)' }}>
Contributors
</Typography>
{formValues.contributors && formValues.contributors.length > 0 && (
<>{renderContribTable()} </>
)}

<div className="text-right">
<Typography variant='caption'>Please refer to the <a href="https://hubmapconsortium.github.io/ingest-validation-tools/contributors/current/" target='_blank'>contributor file schema information</a>, and this <a href='https://raw.githubusercontent.com/hubmapconsortium/dataset-metadata-spreadsheet/main/contributors/latest/contributors.tsv' target='_blank'>Example TSV File</a> </Typography>
</div>
Expand All @@ -926,6 +979,15 @@ export function CollectionForm (props){

<div className="row">
<div className="buttonWrapRight">
{userAdmin === true && !editingCollection.doi_url && (
<LoadingButton
loading={publishing}
onClick={() => handlePublish()}
variant="contained">
Publish
</LoadingButton>
)}

<Button
variant="contained"
onClick={() => handleSubmit()}
Expand Down
76 changes: 72 additions & 4 deletions src/src/components/collections/epicollections.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import "../../App.css";
import SearchComponent from "../search/SearchComponent";
import {COLUMN_DEF_MIXED,COLUMN_DEF_MIXED_SM,COLUMN_DEF_COLLECTION} from "../search/table_constants";
import { entity_api_get_entity,entity_api_create_entity, entity_api_update_entity} from '../../service/entity_api';
import {ingest_api_publish_collection,ingest_api_user_admin} from '../../service/ingest_api';
import { getPublishStatusColor } from "../../utils/badgeClasses";
import { generateDisplaySubtypeSimple_UBKG } from "../../utils/display_subtypes";
import Papa from 'papaparse';
Expand All @@ -15,6 +16,8 @@ import Dialog from "@material-ui/core/Dialog";
import DialogActions from "@material-ui/core/DialogActions";
import DialogContent from "@material-ui/core/DialogContent";
import GroupModal from "../uuid/groupModal";
import LoadingButton from '@mui/lab/LoadingButton';
import {ErrBox} from "../../utils/ui_elements";

import Table from '@mui/material/Table';
import TableBody from '@mui/material/TableBody';
Expand Down Expand Up @@ -51,17 +54,26 @@ export function EPICollectionForm (props){
var [fileDetails, setFileDetails] = useState();
var [buttonState, setButtonState] = useState('');
var [warningOpen, setWarningOpen] = React.useState(false);
var [openGroupModal, setOpenGroupModal] = useState(false


);
var [openGroupModal, setOpenGroupModal] = useState(false );
var [lookupShow, setLookupShow] = useState(false);
var [loadingDatasets, setLoadingDatasets] = useState(true);
var [hideUUIDList, setHideUUIDList] = useState(true);
var [loadUUIDList, setLoadUUIDList] = useState(false);
var [validatingSubmitForm, setValidatingSubmitForm] = useState(false);
var [entityInfo, setEntityInfo] = useState();
var [userAdmin, setUserAdmin] = useState(false);
var [pageError, setPageError] = useState("");
var [publishing, setPublishing] = useState(false);
// var [publishError, setPublishError] = useState({
// status:"",
// message:"",
// });
// @TODO: See what we can globalize/memoize/notize here
var [errorHandler, setErrorHandler] = useState({
status: "",
message: "",
isError: null
});
var [formWarnings, setFormWarnings] = useState({
bulk_dataset_uuids:""
});
Expand All @@ -87,6 +99,18 @@ export function EPICollectionForm (props){
var [datatypeList] = useState(props.dtl_all);
var [editingCollection] = useState(props.editingCollection);


useEffect(() => {
ingest_api_user_admin(JSON.parse(localStorage.getItem("info")).groups_token)
.then((results) => {
console.debug('%c◉ ADMINCHECK ', 'color:#3F007b', results);
setUserAdmin(results)
})
.catch((err) => {
console.debug('%c⭗', 'color:#1f005d', "ingest_api_user_admin ERR", err );
})
}, []);

useEffect(() => {
if (editingCollection) {
setassociatedEntities([])
Expand Down Expand Up @@ -462,6 +486,30 @@ export function EPICollectionForm (props){

});
}


const handlePublish = () => {
setPublishing(true)
ingest_api_publish_collection(props.authToken,editingCollection.uuid)
.then((response) => {
console.debug('%c◉ PUBLISHED ', 'color:#00ff7b', );
// props.onProcessed(response);
if(response.status === 200){
console.debug('%c◉ Good ingest_api_publish_collection ', 'color:#00ff7b', response);
props.onProcessed(response.results);
}else{
console.debug('%c◉ ingest_api_publish_collection Bad result', 'color:#ff337b', response);
setPublishing(false)
let authMessage = response.status === 401 ? "User must be Authorized" : response.results.error.toString();
setPageError(response.status + " | " + authMessage);
}
})
.catch((error) => {
console.debug('%c⭗ handlePublishErr Broken Result', 'color:#ff005d', error);
setPageError(error.status + " | " + error.message);
setPublishing(false);
});
}

const handleUpdate = (formSubmit) => {
// Need to only pass what's changed now
Expand Down Expand Up @@ -890,6 +938,18 @@ export function EPICollectionForm (props){
value={formValues.title}
/>
</FormControl>
{editingCollection && editingCollection.doi_url && (
<FormControl>
<TextField
label="DOI url"
name="DOIurl"
id="DOIurl"
disabled={true}
variant="standard"
value={editingCollection.doi_url}
/>
</FormControl>
)}
<FormControl>
<TextField
label="Description"
Expand Down Expand Up @@ -940,6 +1000,14 @@ export function EPICollectionForm (props){

<div className="row">
<div className="buttonWrapRight">
{userAdmin === true && !editingCollection.doi_url && (
<LoadingButton
loading={publishing}
onClick={() => handlePublish()}
variant="contained">
Publish
</LoadingButton>
)}
<Button
variant="contained"
onClick={() => handleSubmit()}
Expand Down
61 changes: 60 additions & 1 deletion src/src/service/ingest_api.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import FormData from "form-data";
export function ingest_api_users_groups(auth) {
const options = {headers:{Authorization: "Bearer " + auth,
"Content-Type":"application/json"}};

return axios
.get(
`${process.env.REACT_APP_METADATA_API_URL}/metadata/usergroups`, options)
Expand Down Expand Up @@ -44,6 +43,40 @@ export function ingest_api_users_groups(auth) {
}


/*
* Is User Admin
*
*/
export function ingest_api_user_admin(auth) {
const options = {headers:{Authorization: "Bearer " + auth,
"Content-Type":"application/json"}};
return axios
.get(
`${process.env.REACT_APP_METADATA_API_URL}/metadata/usergroups`, options)
.then(res => {

console.debug('%c◉ res ', 'color:#00ff7b', res);
let groups = res.data.groups;
console.debug('%c◉ ADMIN ', 'color:#FF227b', groups);

for (let group in groups) {
let groupName = groups[group].name
if(groupName.includes("hubmap-data-admin")){
return true
}else{
return false
}
}


})
.catch(error => {
console.debug("ERR ingest_api_users_groups", error, error.response);
return {error}
});
}



/*
* Upload a file
Expand Down Expand Up @@ -533,3 +566,29 @@ export function ingest_api_upload_bulk_metadata(type, dataFile, auth) {
return {error}
});
};



/*
* Notify
*
*/
export function ingest_api_publish_collection(auth, data) {
const options = {headers:{Authorization: "Bearer " + auth,"Content-Type":"application/json"}};
let url = `${process.env.REACT_APP_DATAINGEST_API_URL}/collections/${data}/register-doi`;
console.debug('%c◉ publish ', 'color:#00ff7b', url,options);
return axios
.put(url, data, options)
.then(res => {
let results = res.data;
return {status:res.status, results:results}
})
.catch(error => {
if(error.response){
return {status:error.response.status, results:error.response.data}
}else{
return {error}
}
});
};

0 comments on commit f95042d

Please sign in to comment.