Skip to content

Commit

Permalink
Refine the project approval page for System Administrators (#673)
Browse files Browse the repository at this point in the history
  • Loading branch information
JaymeeH authored May 3, 2024
1 parent 8643ed0 commit acba714
Show file tree
Hide file tree
Showing 13 changed files with 258 additions and 19 deletions.
96 changes: 96 additions & 0 deletions app/assets/stylesheets/_settings.scss
Original file line number Diff line number Diff line change
Expand Up @@ -202,3 +202,99 @@
margin-top: 1em;
}
}

#approve{
.details{
margin-left: 2em;
}
.provenance{
display: inline-block;
margin-right: 23em;
margin-left: 23.5em;
}
.field{
display: inline-flex;
margin-bottom: 2em;
}
.form-directory{
min-width: 13em;
}
.form-directory-confirm{
margin-left: 1em;
min-width: fit-content;
}
.form-message{
min-width: 15em;
min-height: 3em;
margin-left: 5px;
}
.form-date{
min-width: 14em;
}
.form-dropdown{
max-width: fit-content;
margin-right: 1em;
}
h2 {// Heading for the details div
margin-left: 0.2em;
text-decoration: underline;
text-decoration-thickness: 3px;
.btn.btn-primary.btn-sm{
margin-left: 1.5em;
}
}
dl {
width: 100%;
overflow: hidden;
padding: 0;
margin: 0
}
dt {
float: left;
min-width: calc(25% + 5em);
/* adjust the width; make sure the total of both is 100% */
padding: 0;
margin: 0;
margin-left: 1em;
clear: both
}
dd{
margin-bottom: .5rem;


}
p {
margin-left: 1em;
}
label{
margin-right: 5em;
max-width: 8em;
font-weight: bold;
}
input{
.placeholder{
opacity: 1;
}
-webkit-outer-spin-button, -webkit-inner-spin-button {
display: none;
margin: 0;
}
[type=number]{
-moz-appearance:textfield;
}
width: 10em;
max-height: 38px;
margin-right: 5px;
}
select{
max-height: 38px;
}
button{
min-width: 160px;
min-height: 38px
}
a{
min-width: 160px;
min-height: 38px
}
}
20 changes: 19 additions & 1 deletion app/controllers/projects_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,19 @@ def update
if params.key?("mediaflux_id")
project_metadata = ProjectMetadata.new(project: project, current_user:)
project_params = params.dup
project_metadata.approve_project(params: project_params)
metadata_params = project_params.merge({
directory: project_params["project_directory"],
storage_capacity: {"size"=>{"approved"=>project_params["storage_capacity"].to_i,
"requested"=>project.metadata[:storage_capacity][:size][:requested]},
"unit"=>{"approved"=>"GB", "requested"=>"GB"}},
approval_note: {
note_by: current_user.uid,
note_date_time: Time.current.in_time_zone("America/New_York").iso8601,
event_type: project_params[:event_note],
message: project_params[:event_note_message]
}
})
project_metadata.approve_project(params: metadata_params)
end

#Edit action
Expand Down Expand Up @@ -198,6 +210,12 @@ def file_list_download
def approve
if current_user.eligible_sysadmin?
project
@departments = project.departments.join(", ")
@project_metadata = project.metadata
sponsor_uid = @project_metadata[:data_sponsor]
@data_sponsor = User.find_by(uid: sponsor_uid)
@provenance_events = project.provenance_events.where.not(event_type: ProvenanceEvent::STATUS_UPDATE_EVENT_TYPE)

@project_metadata = project.metadata
@title = @project_metadata["title"]
else redirect_to root_path
Expand Down
7 changes: 5 additions & 2 deletions app/models/project_metadata.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,13 @@ def approve_project(params:)
# approve a project by recording the mediaflux id & setting the status to 'approved'
project.mediaflux_id = params[:mediaflux_id]
project.metadata_json["status"] = Project::APPROVED_STATUS
project.save!
project.metadata_json["directory"] = params[:directory]
project.metadata_json["storage_capacity"] = params[:storage_capacity]

project.save!
# create two provenance events, one for approving the project and another for changing the status of the project
project.provenance_events.create(event_type: ProvenanceEvent::APPROVAL_EVENT_TYPE, event_person: current_user.uid, event_details: "Approved by #{current_user.display_name_safe}")
project.provenance_events.create(event_type: ProvenanceEvent::APPROVAL_EVENT_TYPE, event_person: current_user.uid, event_details: "Approved by #{current_user.display_name_safe}",
event_note: params[:approval_note])
project.provenance_events.create(event_type: ProvenanceEvent::STATUS_UPDATE_EVENT_TYPE, event_person: current_user.uid, event_details: "The Status of this project has been set to approved")
end

Expand Down
39 changes: 36 additions & 3 deletions app/views/projects/_approve_form.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,40 @@
<%= render 'data_list' %>

<div class="container" id="approve">
<label for="mediaflux_id" class="form-label">Input the Mediaflux ID for the project</label>
<input class="form-control" type="text" required name="mediaflux_id"></input>
<button type="submit" class="btn btn-primary">Approve </button>
<div class="field">
<label for="project_directory" class="form-label">Confirm Project Directory</label>
<input class="form-directory" type="text" name="project_directory-prefix" disabled readonly value= <%= Rails.configuration.mediaflux["api_root_ns"] %>></input> /
<input class="form-directory-confirm" type="text" name="project_directory" required placeholder=<%= "#{@project.metadata[:directory]}"%>></input>
</div>
<div class="field">
<label for="storage_capacity" class="form-label">Confirm Storage Capacity</label>
<input class="form-control" type="number" min="1" name="storage_capacity" required placeholder=<%= "#{@project.metadata[:storage_capacity][:size][:requested]}"%>>GB</input>
</div>
<div class="field">
<label for="mediaflux_id" class="form-label">Collection ID</label>
<input class="form-control" type="text" required name="mediaflux_id"></input>
</div>
<div class="field">
<label for="approver" class="form-label">Approver</label>
<input class="form-control" type="text" name="approver" disabled value=<%=current_user.uid%>></input>
</div>
<div class="field">
<label for="approval_date" class="form-label">Approval Date Time</label>
<input class="form-date" type="text" name="approval_date" disabled value=<%=Time.now.in_time_zone("America/New_York").iso8601%>></input>
</div>
<div class="field">
<label for="event_note" class="form-label">Event Note</label>
<select class="form-dropdown" name="event_note" id="Event Note">
<option disabled selected value> -- select an option -- </option>
<option value="Quota">Quota</option>
<option value="Tier">Tier</option>
<option value="Other">Other</option>
</select>
<label for="event_note_message" class="form-label">Message</label>
<input class="form-message" type="text" name="event_note_message"> </input>
</div>
<div class="controls">
<button type="submit" class="btn btn-primary">Approve</button>
<%= link_to "Cancel", root_path, class: "btn btn-secondary" %>
</div>
</div>
33 changes: 29 additions & 4 deletions app/views/projects/approve.html.erb
Original file line number Diff line number Diff line change
@@ -1,6 +1,31 @@
<approve id="approve">
<h1>Project Approval: <%=@title%> </h1>
<h2 >Approve this project by appending a mediaflux id</h2>

<%= form_with url: project_path(@project), method: :put do |form| %>
<%= render "approve_form" %>
<% end %>
<div class="details">
<h4>Metadata Highlights</h4>
<dl>
<dt>Data Sponsor</dt> <dd><%= @data_sponsor.display_name_safe %></dd>
<dt>Affiliated Department(s)</dt> <dd><%= @departments %></dd>
<dt>Project Directory</dt> <dd><%= Rails.configuration.mediaflux["api_root_ns"] %>/<%= @project.metadata[:directory] %></dd>
<dt>Title</dt> <dd><%=@project.metadata[:title] %></dd>
<dt>Project ID</dt> <dd><%= @project.metadata[:project_id] %></dd>
<dt>Storage Capacity - Request</dt> <dd><%= "#{@project.metadata[:storage_capacity][:size][:requested]} #{@project.metadata[:storage_capacity][:unit][:requested]}" %></dd>
</dl>
<p>
Submission
<ul class>
<% @provenance_events.each do |event| %>
<li class="provenance"> <%= event.event_details %>, <%=event.created_at.to_time.in_time_zone("America/New_York").iso8601%> </li>
<% end %>
</ul>
</p>
</div>

<div class="details">
<h4>Project Approval Confirmation Information</h4>
<%= form_with url: project_path(@project), method: :put do |form| %>
<%= render "approve_form" %>
<% end %>
</div>

</approve>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class AddEventNoteToProvenanceEvent < ActiveRecord::Migration[7.0]
def change
add_column :provenance_events, :event_note, :jsonb
end
end
3 changes: 2 additions & 1 deletion db/schema.rb

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions spec/factories/provenance_event.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,14 @@
factory :approval_event do
event_type { ProvenanceEvent::APPROVAL_EVENT_TYPE }
event_details { "The project was approved by #{FFaker::Name.name}" }
event_note do
{
NoteBy: FFaker::Name.name.to_s,
NoteDateTime: Time.current.in_time_zone("America/New_York").iso8601,
EventType: "Other",
Message: "Filler Message"
}
end
end
factory :status_update_event do
event_type { ProvenanceEvent::STATUS_UPDATE_EVENT_TYPE }
Expand Down
18 changes: 16 additions & 2 deletions spec/models/project_mediaflux_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,14 @@
Mediaflux::Http::AssetDestroyRequest.new(session_token: current_user.mediaflux_session, collection: incomplete_project.mediaflux_id, members: true).resolve
end
it "should raise a MetadataError if any required is missing" do
params = {mediaflux_id: 001}
params = {mediaflux_id: 001,
directory: incomplete_project.metadata[:directory],
storage_capacity: {"size"=>{"approved"=>600,
"requested"=>project.metadata[:storage_capacity][:size][:requested]},
"unit"=>{"approved"=>"GB", "requested"=>"GB"}},
event_note: "Other",
event_note_message: "Message filler"
}
project_metadata.approve_project(params:)
session_token = current_user.mediaflux_session

Expand All @@ -103,7 +110,14 @@
end

it "should raise a error if any error occurs in mediaflux" do
params = {mediaflux_id: 001}
params = {mediaflux_id: 001,
directory: incomplete_project.metadata[:directory],
storage_capacity: {"size"=>{"approved"=>600,
"requested"=>project.metadata[:storage_capacity][:size][:requested]},
"unit"=>{"approved"=>"GB", "requested"=>"GB"}},
event_note: "Other",
event_note_message: "Message filler"
}
project_metadata.approve_project(params:)
session_token = current_user.mediaflux_session

Expand Down
29 changes: 25 additions & 4 deletions spec/models/project_metadata_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,14 @@
describe "#approve_project" do
it "Records the mediaflux id and sets the status to approved" do
project_metadata = described_class.new(current_user: current_user, project:)
params = {mediaflux_id: 001 }
params = {mediaflux_id: 001,
directory: project.metadata[:directory],
storage_capacity: {"size"=>{"approved"=>600,
"requested"=>project.metadata[:storage_capacity][:size][:requested]},
"unit"=>{"approved"=>"GB", "requested"=>"GB"}},
event_note: "Other",
event_note_message: "Message filler"
}
project_metadata.approve_project(params:)

project.reload
Expand All @@ -157,8 +164,15 @@
end
it "Creates a Provenance Event: Approval" do
project_metadata = described_class.new(current_user: current_user, project:)
params = {data_sponsor: "abc", data_manager: "def", departments: "dep", directory: "dir", title: "title abc", description: "description 123" }
project_metadata.approve_project(params: {}) # doesn't call the doi service twice
params = {mediaflux_id: 001,
directory: project.metadata[:directory],
storage_capacity: {"size"=>{"approved"=>600,
"requested"=>project.metadata[:storage_capacity][:size][:requested]},
"unit"=>{"approved"=>"GB", "requested"=>"GB"}},
event_note: "Other",
event_note_message: "Message filler"
}
project_metadata.approve_project(params:) # doesn't call the doi service twice

project.reload
expect(project.provenance_events.count).to eq 2
Expand All @@ -176,7 +190,14 @@
Mediaflux::Http::AssetDestroyRequest.new(session_token: current_user.mediaflux_session, collection: valid_project.mediaflux_id, members: true).resolve
end
it "validates the doi for a project" do
params = {mediaflux_id: 001 }
params = {mediaflux_id: 001,
directory: valid_project.metadata[:directory],
storage_capacity: {"size"=>{"approved"=>600,
"requested"=>project.metadata[:storage_capacity][:size][:requested]},
"unit"=>{"approved"=>"GB", "requested"=>"GB"}},
event_note: "Other",
event_note_message: "Message filler"
}
project_metadata.approve_project(params:)

#create a project in mediaflux
Expand Down
7 changes: 7 additions & 0 deletions spec/models/provenance_event_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,15 @@
pe.event_type = ProvenanceEvent::APPROVAL_EVENT_TYPE
pe.event_details = "Approved by Jane Doe, 2023-01-19T12:00:00"
pe.event_person = "abc123"
pe.event_note = {
NoteBy: pe.event_person,
NoteDateTime: pe.created_at,
EventType: "Other",
Message: "Approval Note"
}
pe.save
expect(pe.event_type).to eq(ProvenanceEvent::APPROVAL_EVENT_TYPE)
expect(pe.event_note).not_to eq nil
end
end
context "when a project is approved" do
Expand Down
4 changes: 2 additions & 2 deletions spec/system/project_roles_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -219,14 +219,14 @@
sign_in system_admin
visit project_approve_path(project)
click_on "Approve"
expect(page).to have_content "Approve this project by appending a mediaflux id"
expect(page).to have_content "Metadata Highlights"
end

it "allows a super user to approve the project" do
sign_in superuser
visit project_approve_path(project)
click_on "Approve"
expect(page).to have_content "Approve this project by appending a mediaflux id"
expect(page).to have_content "Metadata Highlights"
end

it "does not allow a data sponsor to approve the project" do
Expand Down
Loading

0 comments on commit acba714

Please sign in to comment.