Skip to content

Commit

Permalink
added EForms SDK fields import confirmation
Browse files Browse the repository at this point in the history
  • Loading branch information
Kolea PLESCO authored and Kolea PLESCO committed Feb 6, 2025
1 parent b73d9ae commit 9ba8fdd
Show file tree
Hide file tree
Showing 7 changed files with 246 additions and 83 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from mapping_workbench.backend.fields_registry.models.field_registry import StructuralElement, \
APIListStructuralElementsPaginatedResponse, APIListStructuralElementsVersionedViewPaginatedResponse, \
StructuralElementsVersionedView, StructuralElementLabelOut, BaseStructuralElementIn, StructuralElementOut, \
StructuralElementIn
StructuralElementIn, APIValidateSDKVersionsToImportResponse
from mapping_workbench.backend.fields_registry.services import tasks
from mapping_workbench.backend.fields_registry.services.api import list_structural_elements_versioned_view, \
get_structural_elements_versioned_view, \
Expand All @@ -19,6 +19,8 @@
from mapping_workbench.backend.fields_registry.services.data import tree_of_structural_elements
from mapping_workbench.backend.fields_registry.services.generate_conceptual_mapping_rules import \
generate_conceptual_mapping_rules
from mapping_workbench.backend.fields_registry.services.import_fields_registry import \
eforms_sdk_versions_from_str_to_list, exists_eforms_versions_in_project, exists_import_eforms_versions_in_pool
from mapping_workbench.backend.project.models.entity import Project
from mapping_workbench.backend.project.services.api import get_project
from mapping_workbench.backend.security.services.user_manager import current_active_user
Expand Down Expand Up @@ -187,6 +189,28 @@ async def route_search_structural_elements_versioned_view_by_eforms_version(
return structural_elements_versioned_view


@router.post(
"/check_import_eforms_xsd",
description=f"Check Import eForms XSD",
name=f"{NAME_FOR_ONE}:check_import_eforms_xsd",
response_model=APIValidateSDKVersionsToImportResponse
)
async def route_check_import_eforms_xsd(
github_repository_url: str = Form(default=None),
branch_or_tag_name: str = Form(...),
project_id: PydanticObjectId = Form(...),
user: User = Depends(current_active_user)
):
versions = eforms_sdk_versions_from_str_to_list(branch_or_tag_name)
validated_versions = APIValidateSDKVersionsToImportResponse(

Check warning on line 205 in mapping_workbench/backend/fields_registry/entrypoints/api/routes.py

View check run for this annotation

Codecov / codecov/patch

mapping_workbench/backend/fields_registry/entrypoints/api/routes.py#L204-L205

Added lines #L204 - L205 were not covered by tests
in_project=(await exists_eforms_versions_in_project(project_id, versions)),
in_pool=(await exists_import_eforms_versions_in_pool(versions))
)
validated_versions.not_in_project = [item for item in versions if item not in validated_versions.in_project]
validated_versions.not_in_pool = [item for item in versions if item not in validated_versions.in_pool]
return validated_versions

Check warning on line 211 in mapping_workbench/backend/fields_registry/entrypoints/api/routes.py

View check run for this annotation

Codecov / codecov/patch

mapping_workbench/backend/fields_registry/entrypoints/api/routes.py#L209-L211

Added lines #L209 - L211 were not covered by tests


@router.post(
"/tasks/import_eforms_xsd",
description=f"Task Import eForms XSD",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,3 +189,10 @@ class BaseStructuralElementIn(BaseModel):
absolute_xpath: str
relative_xpath: Optional[str] = None
parent_node_id: Optional[str] = None


class APIValidateSDKVersionsToImportResponse(BaseModel):
in_project: List[str] = [],
not_in_project: List[str] = [],
in_pool: List[str] = [],
not_in_pool: List[str] = [],
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
from datetime import datetime
from typing import List, Union

from beanie import Link
from beanie import Link, PydanticObjectId
from beanie.odm.operators.find.comparison import Eq
from dateutil.tz import tzlocal

from mapping_workbench.backend.fields_registry.adapters.github_download import GithubDownloader
Expand All @@ -31,6 +32,26 @@
GROUP_CONTENT_TYPE = "group"



async def exists_eforms_versions_in_project(project_id: PydanticObjectId, versions: List[str]) -> List[str]:
existing_versions = []
for version in versions:
sdk_fields = await StructuralElement.find(

Check warning on line 39 in mapping_workbench/backend/fields_registry/services/import_fields_registry.py

View check run for this annotation

Codecov / codecov/patch

mapping_workbench/backend/fields_registry/services/import_fields_registry.py#L37-L39

Added lines #L37 - L39 were not covered by tests
Eq(StructuralElement.versions, version),
StructuralElement.project == Project.link_from_id(project_id)
).to_list()
if len(sdk_fields) > 0:
existing_versions.append(version)
return existing_versions

Check warning on line 45 in mapping_workbench/backend/fields_registry/services/import_fields_registry.py

View check run for this annotation

Codecov / codecov/patch

mapping_workbench/backend/fields_registry/services/import_fields_registry.py#L43-L45

Added lines #L43 - L45 were not covered by tests

async def exists_import_eforms_versions_in_pool(versions: List[str]) -> List[str]:
existing_versions = []
for version in versions:
sdk_fields = await PoolSDKField.find(PoolSDKField.version == version).to_list()
if len(sdk_fields) > 0:
existing_versions.append(version)
return existing_versions

Check warning on line 53 in mapping_workbench/backend/fields_registry/services/import_fields_registry.py

View check run for this annotation

Codecov / codecov/patch

mapping_workbench/backend/fields_registry/services/import_fields_registry.py#L48-L53

Added lines #L48 - L53 were not covered by tests

async def import_eforms_fields_from_pool_to_project(project_link: Link[Project], version: str) -> bool:
"""
Expand Down Expand Up @@ -231,6 +252,8 @@ async def import_eforms_fields_from_folder_to_pool(
fields_metadata=fields_metadata
)

def eforms_sdk_versions_from_str_to_list(versions_str: str) -> List[str]:
return [item.strip() for item in versions_str.split(',')]

async def import_eforms_xsd(
branch_or_tag_name: str,
Expand All @@ -242,7 +265,7 @@ async def import_eforms_xsd(
task_response = TaskResponse()

task_progress = TaskProgress(task_response)
versions = [item.strip() for item in branch_or_tag_name.split(',')]
versions = eforms_sdk_versions_from_str_to_list(branch_or_tag_name)

task_progress.start_progress(actions_count=1)
task_progress.start_action(name="Import EForms XSD", steps_count=len(versions))
Expand Down
6 changes: 6 additions & 0 deletions mapping_workbench/frontend/src/api/fields-registry/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ class FieldsRegistryApi extends SectionApi {
}
}

async validateImportEFormsXSD(request) {
let endpoint = this.paths['check_import_eforms_xsd'];
const headers = {"Content-Type": "multipart/form-data"};
return await appApi.post(endpoint, request, null, headers);
}

async getItemsTree() {
let filters = {}
if (this.isProjectResource) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import {useState} from "react";
import {useFormik} from "formik";
import {useRouter} from "next/router";
import * as Yup from "yup";

import Card from "@mui/material/Card";
Expand All @@ -23,14 +22,43 @@ import {RouterLink} from "src/components/router-link";
import {FormTextField} from "src/components/app/form/text-field";
import {fieldsOverviewApi as sectionApi} from 'src/api/fields-overview';
import {toastError, toastLoad, toastSuccess} from "src/components/app-toast";
import {fieldsRegistryApi} from "src/api/fields-registry";
import {EFormsImportValidator} from "../../../../sections/app/fields-registry/eforms-import-validation";
import {useDialog} from "../../../../hooks/use-dialog";


const Page = () => {
const confirmImportFieldsDialog = useDialog();
usePageView();
const router = useRouter()

const [isRunning, setIsRunning] = useState(false);

const handleConfirmImportFields = (validatedVersions, values) => {
if (!validatedVersions?.in_project?.length && !validatedVersions?.not_in_pool?.length) {
return true;
}
return new Promise((resolve) => {
confirmImportFieldsDialog.handleOpen({
open: true,
onConfirm: () => {
confirmImportFieldsDialog.handleClose();
resolve(true);
},
onClose: () => {
confirmImportFieldsDialog.handleClose();
resolve(false);
},
validatedVersions: validatedVersions,
values: values
});
});
};

const validateImportFieldRegistry = async (values) => {
const validatedVersions = await fieldsRegistryApi.validateImportEFormsXSD(values);
return handleConfirmImportFields(validatedVersions, values);
};

const formik = useFormik({
initialValues: {
github_repository_url: "",
Expand All @@ -47,92 +75,104 @@ const Page = () => {
onSubmit: async (values, helpers) => {
setIsRunning(true)
values['project_id'] = sessionApi.getSessionProject();

const toastId = toastLoad(`Importing eForm Fields ... `)
sectionApi.importEFormsXSD(values)
.then((res) => {
helpers.setStatus({success: true});
toastSuccess(`${res.task_name} successfully started.`, toastId)
// router.push({
// pathname: paths.app.fields_and_nodes.overview.index
// })
})
.catch(err => {
console.log(err)
helpers.setStatus({success: false});
helpers.setErrors({submit: err.message});
toastError(`eForm Fields import failed: ${err.message}.`, toastId);
})
.finally(setIsRunning(false))
if (await validateImportFieldRegistry(values)) {
sectionApi.importEFormsXSD(values)
.then((res) => {
helpers.setStatus({success: true});
toastSuccess(`${res.task_name} successfully started.`, toastId)
})
.catch(err => {
console.log(err)
helpers.setStatus({success: false});
helpers.setErrors({submit: err.message});
toastError(`eForm Fields import failed: ${err.message}.`, toastId);
})
.finally(setIsRunning(false))
} else {
setIsRunning(false);
toastSuccess(`Importing eForm Fields canceled.`, toastId)
}
}
});

return (
<Stack spacing={4}>
<div>
<Link
color="text.primary"
component={RouterLink}
href={paths.app.fields_and_nodes.overview.index}
sx={{
alignItems: 'center',
display: 'inline-flex'
}}
underline="hover"
>
<SvgIcon sx={{mr: 1}}>
<ArrowLeftIcon/>
</SvgIcon>
<Typography variant="subtitle2">
{sectionApi.SECTION_TITLE}
</Typography>
</Link>
</div>
<form onSubmit={formik.handleSubmit}>
<Card>
<CardHeader title="Import eForms XSD"/>
<CardContent sx={{pt: 0}}>
<Grid container
spacing={3}>
<Grid xs={12}
md={12}>
<FormTextField formik={formik}
name="branch_or_tag_name"
label="SDK Version(s)"
helperText="separated by comma (,)"
required/>
</Grid>
<Grid xs={12}
md={12}>
<FormTextField formik={formik}
name="github_repository_url"
label="GitHub Repository URL"
/>
</Grid>
</Grid>
</CardContent>
</Card>
<Card sx={{mt: 3}}>
<Stack
direction={{
xs: 'column',
sm: 'row'
<>
<Stack spacing={4}>
<div>
<Link
color="text.primary"
component={RouterLink}
href={paths.app.fields_and_nodes.overview.index}
sx={{
alignItems: 'center',
display: 'inline-flex'
}}
flexWrap="wrap"
spacing={3}
sx={{p: 3}}
underline="hover"
>
<Button
id='import'
disabled={isRunning}
type="submit"
variant="contained"
<SvgIcon sx={{mr: 1}}>
<ArrowLeftIcon/>
</SvgIcon>
<Typography variant="subtitle2">
{sectionApi.SECTION_TITLE}
</Typography>
</Link>
</div>
<form onSubmit={formik.handleSubmit}>
<Card>
<CardHeader title="Import eForms XSD"/>
<CardContent sx={{pt: 0}}>
<Grid container
spacing={3}>
<Grid xs={12}
md={12}>
<FormTextField formik={formik}
name="branch_or_tag_name"
label="SDK Version(s)"
helperText="separated by comma (,)"
required/>
</Grid>
<Grid xs={12}
md={12}>
<FormTextField formik={formik}
name="github_repository_url"
label="GitHub Repository URL"
/>
</Grid>
</Grid>
</CardContent>
</Card>
<Card sx={{mt: 3}}>
<Stack
direction={{
xs: 'column',
sm: 'row'
}}
flexWrap="wrap"
spacing={3}
sx={{p: 3}}
>
Import
</Button>
</Stack>
</Card>
</form>
</Stack>
<Button
id='import'
disabled={isRunning}
type="submit"
variant="contained"
>
Import
</Button>
</Stack>
</Card>
</form>
</Stack>
<EFormsImportValidator
open={confirmImportFieldsDialog.open}
onClose={confirmImportFieldsDialog.data?.onClose}
onConfirm={confirmImportFieldsDialog.data?.onConfirm}
validatedVersions={confirmImportFieldsDialog.data?.validatedVersions}
values={confirmImportFieldsDialog.data?.values}
/>
</>
);
};

Expand Down
1 change: 1 addition & 0 deletions mapping_workbench/frontend/src/paths.js
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,7 @@ export const apiPaths = {
items: '/fields_registry',
item: '/fields_registry/:id',
import_eforms_xsd: '/fields_registry/tasks/import_eforms_xsd',
check_import_eforms_xsd: '/fields_registry/check_import_eforms_xsd',
elements: '/fields_registry/elements',
elements_tree: '/fields_registry/elements_tree',
element: '/fields_registry/elements/:id',
Expand Down
Loading

0 comments on commit 9ba8fdd

Please sign in to comment.