From 9015dd55fdcf13461190ac5f49139d3b351b51fb Mon Sep 17 00:00:00 2001 From: Lorenzo Cavazzi Date: Fri, 21 Jan 2022 14:47:48 +0100 Subject: [PATCH 1/2] fix(client): restore projects data used by datasets --- client/src/api-client/project.js | 8 +++++- .../addtoproject/DatasetAdd.container.js | 6 +++-- client/src/project/shared/Projects.state.js | 26 ++++++++++++++----- 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/client/src/api-client/project.js b/client/src/api-client/project.js index b898c17804..32153fef71 100644 --- a/client/src/api-client/project.js +++ b/client/src/api-client/project.js @@ -153,7 +153,13 @@ function addProjectMethods(client) { namespace { fullPath } - path + path, + httpUrlToRepo, + userPermissions { + adminProject, + pushCode, + removeProject + } } } }`; diff --git a/client/src/dataset/addtoproject/DatasetAdd.container.js b/client/src/dataset/addtoproject/DatasetAdd.container.js index f50667b726..3d5f4fce73 100644 --- a/client/src/dataset/addtoproject/DatasetAdd.container.js +++ b/client/src/dataset/addtoproject/DatasetAdd.container.js @@ -134,10 +134,12 @@ function AddDataset(props) { const projectOptions = handlers.getFormDraftFieldProperty("project", ["options"]); - const selectedProject = projectOptions.find((project)=> + const selectedProject = projectOptions.find((project) => project.value === mappedInputs.project); - props.client.checkMigration(props.httpProjectUrl).then((response) => { + // TODO: is this what we want? Should we check that both the target and the source are up-to-date? + const target = selectedProject.value; // It was props.httpProjectUrl, but it's not always set + props.client.checkMigration(target).then((response) => { if (response && response.error !== undefined) { handlers.setSubmitLoader({ value: false, text: "" }); handlers.setServerErrors(response.error.reason); diff --git a/client/src/project/shared/Projects.state.js b/client/src/project/shared/Projects.state.js index 12436314d4..78d0f76b45 100644 --- a/client/src/project/shared/Projects.state.js +++ b/client/src/project/shared/Projects.state.js @@ -23,6 +23,9 @@ * Projects controller code. */ +import { ACCESS_LEVELS } from "../../api-client"; + + class ProjectsCoordinator { constructor(client, model) { this.client = client; @@ -31,11 +34,22 @@ class ProjectsCoordinator { _starredProjectMetadata(project) { let accessLevel = 0; - if (project.permissions && project.permissions.project_access) - accessLevel = Math.max(accessLevel, project.permissions.project_access.access_level); - - if (project.permissions && project.permissions.group_access) - accessLevel = Math.max(accessLevel, project.permissions.group_access.access_level); + // check permissions from v4 API + if (project?.permissions) { + if (project?.permissions?.project_access) + accessLevel = Math.max(accessLevel, project.permissions.project_access.access_level); + if (project?.permissions?.group_access) + accessLevel = Math.max(accessLevel, project.permissions.group_access.access_level); + } + // check permissions from GraphQL -- // ? REF: https://docs.gitlab.com/ee/user/permissions.html + else if (project?.userPermissions) { + if (project.userPermissions.removeProject) + accessLevel = Math.max(accessLevel, ACCESS_LEVELS.OWNER); + else if (project.userPermissions.adminProject) + accessLevel = Math.max(accessLevel, ACCESS_LEVELS.MAINTAINER); + else if (project.userPermissions.pushCode) + accessLevel = Math.max(accessLevel, ACCESS_LEVELS.DEVELOPER); + } // Project id can be a number e.g. 1234 or a string with the format: gid://gitlab/Project/1234 const projectFullId = typeof (project.id) === "number" ? [] : project.id.split("/"); @@ -51,7 +65,7 @@ class ProjectsCoordinator { owner: project.owner, last_activity_at: project.last_activity_at, access_level: accessLevel, - http_url_to_repo: project.http_url_to_repo, + http_url_to_repo: project.http_url_to_repo ? project.http_url_to_repo : project.httpUrlToRepo, namespace: project.namespace, path: project.path, avatar_url: project.avatar_url From 611c1a18f20fd96c46174f5405c3614ebbc8d868 Mon Sep 17 00:00:00 2001 From: Lorenzo Cavazzi Date: Tue, 25 Jan 2022 15:45:35 +0100 Subject: [PATCH 2/2] fix(client): prevent flashing dataset not in kg too early --- client/src/dataset/Dataset.container.js | 8 +++++++- client/src/dataset/Dataset.present.js | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/client/src/dataset/Dataset.container.js b/client/src/dataset/Dataset.container.js index bab474ee30..63d720bb67 100644 --- a/client/src/dataset/Dataset.container.js +++ b/client/src/dataset/Dataset.container.js @@ -27,6 +27,8 @@ export default function ShowDataset(props) { const [datasetKg, setDatasetKg] = useState(); const [datasetFiles, setDatasetFiles] = useState(); + const [fetchedKg, setFetchedKg] = useState(false); + const dataset = useMemo(() => mapDataset(props.datasets ? props.datasets.find(dataset => dataset.name === props.datasetId) @@ -79,9 +81,12 @@ export default function ShowDataset(props) { const id = props.insideProject ? dataset.identifier : props.identifier; props.client.fetchDatasetFromKG(id) .then((datasetInfo) => { - if (!unmounted && datasetKg === undefined && datasetInfo !== undefined) + if (!unmounted && datasetKg === undefined && datasetInfo !== undefined) { + setFetchedKg(true); setDatasetKg(datasetInfo); + } }).catch(error => { + setFetchedKg(true); if (!unmounted && error.case === API_ERRORS.notFoundError) setFetchError({ code: 404, message: "dataset not found or missing permissions" }); else if (!unmounted && error.case === API_ERRORS.internalServerError) @@ -98,6 +103,7 @@ export default function ShowDataset(props) { dataset={dataset} datasets={props.datasets} fetchError={fetchError} + fetchedKg={fetchedKg} fileContentUrl={props.fileContentUrl} history={props.history} httpProjectUrl={props.httpProjectUrl} diff --git a/client/src/dataset/Dataset.present.js b/client/src/dataset/Dataset.present.js index 08bd878fd0..db7cdb2c7c 100644 --- a/client/src/dataset/Dataset.present.js +++ b/client/src/dataset/Dataset.present.js @@ -437,7 +437,7 @@ export default function DatasetView(props) { : null } { - dataset.insideKg === false && props.projectInsideKg === true ? + props.fetchedKg === true && dataset.insideKg === false && props.projectInsideKg === true ? This dataset is not in the Knowledge Graph; this means that some operations on it are not possible.