Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Display configuration profile validation errors #438

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions app/assets/stylesheets/application.scss
Original file line number Diff line number Diff line change
Expand Up @@ -282,11 +282,6 @@ a:hover {
border-top: 3px solid $dashboard-background-color-highlight !important;
}

.cp-container {
margin-left: 10% !important;
margin-right: 10% !important;
}

.cp-step-row {
margin-bottom: 60%;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,15 @@ def call_action

@instance.send(action)
render json: @instance.reload, include: [standards_organizations: {include: :users}]
rescue CpState::NotYetReadyForTransition => e
message =
if @instance.incomplete?
ConfigurationProfile.validate_structure(@instance.structure, "complete")
else
e.message
end

render json: {message: message}, status: :internal_server_error
end

private
Expand Down
1 change: 1 addition & 0 deletions app/controllers/concerns/recoverable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ def self.included(this_class)
this_class.class_eval do
errors_and_messages.each do |error, config|
rescue_from error.to_s.constantize do |e|
byebug
error_message =
if config[:include_original_error_message]
t(config[:message_key], message: e.message)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,16 @@ const AbstractClasses = () => {
);
};

const handleNameBlur = () => {
if (!name) {
dispatch(setEditCPErrors("File Name can't be blank"));
return;
}

dispatch(setEditCPErrors(null));
saveChanges();
};

const saveChanges = async (data = null) => {
dispatch(setSavingCP(true));

Expand Down Expand Up @@ -138,8 +148,8 @@ const AbstractClasses = () => {
className="form-control input-lg"
placeholder="The name of the skos file."
value={name}
onChange={(e) => setName(event.target.value)}
onBlur={() => saveChanges()}
onChange={e => setName(e.target.value.trim())}
onBlur={handleNameBlur}
autoFocus
/>
</div>
Expand All @@ -155,7 +165,7 @@ const AbstractClasses = () => {
placeholder="The version of the skos file"
maxLength={5}
value={version}
onChange={(e) => setVersion(event.target.value)}
onChange={e => setVersion(e.target.value.trim())}
onBlur={() => saveChanges()}
/>
</div>
Expand Down Expand Up @@ -188,7 +198,7 @@ const AbstractClasses = () => {
type="url"
className="form-control input-lg"
value={origin}
onChange={(e) => setOrigin(e.target.value)}
onChange={e => setOrigin(e.target.value.trim())}
pattern="https://.*"
size="30"
placeholder="https://example.com"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
SmallRemovableTab,
TabGroup,
} from "../utils";
import { EMAIL_REGEX } from "../../../../helpers/Constants";

const Agents = () => {
const leadMapperRef = useRef(false);
Expand Down Expand Up @@ -92,6 +93,31 @@ const Agents = () => {
updateAgentsData();
};

const handleEmailBlur = () => {
if (!email) {
dispatch(setEditCPErrors("Agent Email can't be blank"));
return;
}

if (!email.match(EMAIL_REGEX)) {
dispatch(setEditCPErrors("Agent Email is invalid"));
return;
}

dispatch(setEditCPErrors(null));
saveChanges();
};

const handleNameBlur = () => {
if (!fullname) {
dispatch(setEditCPErrors("Agent Full Name can't be blank"));
return;
}

dispatch(setEditCPErrors(null));
saveChanges();
};

const handleRemoveAgent = () => {
setConfirmationVisible(false);
let localCP = currentCP;
Expand Down Expand Up @@ -158,10 +184,8 @@ const Agents = () => {
name="fullname"
placeholder="The name of this agent"
value={fullname || ""}
onChange={(event) => {
setFullname(event.target.value);
}}
onBlur={saveChanges}
onChange={e => setFullname(e.target.value.trim())}
onBlur={handleNameBlur}
autoFocus
/>
</div>
Expand All @@ -174,16 +198,13 @@ const Agents = () => {
</label>
<div className="input-group input-group">
<input
id="email"
type="text"
className="form-control input-lg"
name="agentEmail"
placeholder="The email of this agent"
value={email || ""}
onChange={(event) => {
setEmail(event.target.value);
}}
onBlur={saveChanges}
onChange={e => setEmail(e.target.value.trim())}
onBlur={handleEmailBlur}
/>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React from "react";
import { useSelector } from "react-redux";

const CompleteStructureValidationErrors = () => {
const { completeStructureValidationErrors } = useSelector((state) => state.currentCP)

if (!completeStructureValidationErrors?.length) {
return null;
}

return (
<div className="alert alert-warning pt-3">
<h6>
The following issues prevent the configuration profile from being promoted to the "Complete" state:
</h6>

<ol>
{completeStructureValidationErrors.map((error, index) => (
<li key={index}>{error}</li>
))}
</ol>
</div>
);
};

export default CompleteStructureValidationErrors;
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ const ConceptSchemeMetadata = ({ schemaFileIdx, conceptSchemeIdx }) => {
id="origin"
value={origin || ""}
onChange={(event) => {
setOrigin(event.target.value);
setOrigin(event.target.value.trim());
}}
onBlur={() =>
handleUrlBlur(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
} from "../../../../actions/configurationProfiles";
import { validURL } from "../../../../helpers/URL";
import updateCP from "../../../../services/updateCP";
import { EMAIL_REGEX } from "../../../../helpers/Constants";

const DSOMetaData = ({ dsoData }) => {
const [name, setName] = useState("");
Expand All @@ -27,6 +28,31 @@ const DSOMetaData = ({ dsoData }) => {
setStandardsPage(standardsPage);
}, [dsoData]);

const handleEmailBlur = () => {
if (!email) {
dispatch(setEditCPErrors("DSO Email can't be blank"));
return;
}

if (!email.match(EMAIL_REGEX)) {
dispatch(setEditCPErrors("DSO Email is invalid"));
return;
}

dispatch(setEditCPErrors(null));
handleBlur();
};

const handleNameBlur = () => {
if (!name) {
dispatch(setEditCPErrors("DSO Name can't be blank"));
return;
}

dispatch(setEditCPErrors(null));
handleBlur();
};

const handleUrlBlur = (url) => {
if (!validURL(url)) {
dispatch(
Expand Down Expand Up @@ -85,10 +111,8 @@ const DSOMetaData = ({ dsoData }) => {
id="name"
placeholder="The name of the organization"
value={name || ""}
onChange={(event) => {
setName(event.target.value);
}}
onBlur={handleBlur}
onChange={e => setName(e.target.value.trim())}
onBlur={handleNameBlur}
autoFocus
/>
</div>
Expand All @@ -101,15 +125,12 @@ const DSOMetaData = ({ dsoData }) => {
</label>
<div className="input-group input-group">
<input
type="email"
className="form-control input-lg"
id="email"
placeholder="The email of the organization"
value={email || ""}
onChange={(event) => {
setEmail(event.target.value);
}}
onBlur={handleBlur}
onChange={e => setEmail(e.target.value.trim())}
onBlur={handleEmailBlur}
/>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
} from "../../../../actions/configurationProfiles";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faHome } from "@fortawesome/free-solid-svg-icons";
import CompleteStructureValidationErrors from "./CompleteStructureValidationErrors";

const EditConfigurationProfile = (props) => {
const [loading, setLoading] = useState(true);
Expand Down Expand Up @@ -82,15 +83,15 @@ const EditConfigurationProfile = (props) => {
) : (
<div className="col mt-5">
{errors && <AlertNotice message={errors} />}
<div className="row cp-container justify-content-center h-100">
<div className="col-3">
<div className="row h-100">
<div className="col-2">
<div className="row justify-content-center h-100">
<div className="col">
<StepsAside />
</div>
</div>
</div>
<div className="col-9">
<div className="col-7">
<div className="card border-top-dashboard-highlight h-100">
<div className="card-body d-flex flex-column">
<div className="row justify-content-center">
Expand All @@ -105,6 +106,9 @@ const EditConfigurationProfile = (props) => {
</div>
</div>
</div>
<div className="col-3">
<CompleteStructureValidationErrors />
</div>
</div>
</div>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,16 @@ const MappingPredicates = () => {
);
};

const handleNameBlur = () => {
if (!name) {
dispatch(setEditCPErrors("File Name can't be blank"));
return;
}

dispatch(setEditCPErrors(null));
saveChanges();
};

const handlePredicateChange = (e) => {
const { value } = e.target;
setPredicateStrongestMatch(value);
Expand Down Expand Up @@ -144,8 +154,8 @@ const MappingPredicates = () => {
className="form-control input-lg"
placeholder="The name of the skos file."
value={name}
onChange={(e) => setName(e.target.value)}
onBlur={() => saveChanges()}
onChange={e => setName(e.target.value.trim())}
onBlur={handleNameBlur}
autoFocus
/>
</div>
Expand Down Expand Up @@ -194,7 +204,7 @@ const MappingPredicates = () => {
type="url"
className="form-control input-lg"
value={origin}
onChange={(e) => setOrigin(e.target.value)}
onChange={e => setOrigin(e.target.value.trim())}
pattern="https://.*"
size="30"
placeholder="https://example.com"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ const SchemaFileMetadata = ({ schemaFileIdx }) => {
id="origin"
value={origin || ""}
onChange={(event) => {
setOrigin(event.target.value);
setOrigin(event.target.value.trim());
}}
onBlur={() =>
handleUrlBlur(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,19 @@ const StepsAside = () => {
const steps = [
{
number: 1,
description: "General data about the configuration profile",
description: "General info",
},
{
number: 2,
description: "Select the mapping predicates",
description: "Mapping predicates",
},
{
number: 3,
description: "Select the abstract classes",
description: "Abstract classes",
},
{
number: 4,
description: "DSO's information",
description: "DSOs",
},
];

Expand All @@ -30,7 +30,7 @@ const StepsAside = () => {
{steps.map((step) => {
return (
<div
className="row justify-content-center cp-step-row"
className="row cp-step-row"
key={step.number}
>
<div className="col-8">{step.description}</div>
Expand All @@ -40,7 +40,7 @@ const StepsAside = () => {
? "bg-dashboard-background-highlight col-background"
: "border-color-dashboard col-dashboard-highlight"
} p-3 text-center`}
style={{ maxWidth: "50px", height: "50px" }}
style={{ height: "50px", lineHeight: 1, maxWidth: "50px" }}
onClick={() => dispatch(setStep(step.number))}
>
{step.number}
Expand Down
2 changes: 2 additions & 0 deletions app/javascript/helpers/Constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,5 @@ export const APP_DOMAIN = process.env.APP_DOMAIN;
* JWT variables to encode/decode secret values
*/
export const PRIVATE_KEY = process.env.PRIVATE_KEY;

export const EMAIL_REGEX = "^\\S+@\\S+\\.\\S+$";
Loading