From cbd395e584026ea17b80577d881b4ecd62fc6dab Mon Sep 17 00:00:00 2001 From: Philip Durbin Date: Fri, 15 Sep 2023 16:53:31 -0400 Subject: [PATCH 01/10] make configure tools available at the dataset level #9589 --- doc/release-notes/9589-ds-configure-tool.md | 1 + .../source/admin/external-tools.rst | 2 +- .../source/api/external-tools.rst | 4 +- .../edu/harvard/iq/dataverse/DatasetPage.java | 16 ++++ .../externaltools/ExternalToolHandler.java | 7 ++ src/main/java/propertyFiles/Bundle.properties | 1 + src/main/webapp/dataset.xhtml | 11 +++ .../iq/dataverse/api/ExternalToolsIT.java | 79 +++++++++++++++++++ .../ExternalToolHandlerTest.java | 42 ++++++++++ 9 files changed, 160 insertions(+), 3 deletions(-) create mode 100644 doc/release-notes/9589-ds-configure-tool.md diff --git a/doc/release-notes/9589-ds-configure-tool.md b/doc/release-notes/9589-ds-configure-tool.md new file mode 100644 index 00000000000..70ac5fcaa6a --- /dev/null +++ b/doc/release-notes/9589-ds-configure-tool.md @@ -0,0 +1 @@ +Configure tools are now available at the dataset level. They appear under the "Edit Dataset" menu. See also #9589. diff --git a/doc/sphinx-guides/source/admin/external-tools.rst b/doc/sphinx-guides/source/admin/external-tools.rst index 67075e986bb..68b5f493d49 100644 --- a/doc/sphinx-guides/source/admin/external-tools.rst +++ b/doc/sphinx-guides/source/admin/external-tools.rst @@ -115,7 +115,7 @@ Dataset level explore tools allow the user to explore all the files in a dataset Dataset Level Configure Tools +++++++++++++++++++++++++++++ -Configure tools at the dataset level are not currently supported. +Dataset level configure tools can be launched by users who have edit access to the dataset and are found under the "Edit Dataset" menu. Writing Your Own External Tool ------------------------------ diff --git a/doc/sphinx-guides/source/api/external-tools.rst b/doc/sphinx-guides/source/api/external-tools.rst index 05affaf975e..ed68bb09ee0 100644 --- a/doc/sphinx-guides/source/api/external-tools.rst +++ b/doc/sphinx-guides/source/api/external-tools.rst @@ -40,7 +40,7 @@ How External Tools Are Presented to Users An external tool can appear in your Dataverse installation in a variety of ways: - as an explore, preview, query or configure option for a file -- as an explore option for a dataset +- as an explore or configure option for a dataset - as an embedded preview on the file landing page See also the :ref:`testing-external-tools` section of the Admin Guide for some perspective on how Dataverse installations will expect to test your tool before announcing it to their users. @@ -92,7 +92,7 @@ Terminology scope Whether the external tool appears and operates at the **file** level or the **dataset** level. Note that a file level tool much also specify the type of file it operates on (see "contentType" below). - types Whether the external tool is an **explore** tool, a **preview** tool, a **query** tool, a **configure** tool or any combination of these (multiple types are supported for a single tool). Configure tools require an API token because they make changes to data files (files within datasets). Configure tools are currently not supported at the dataset level. The older "type" keyword that allows you to pass a single type as a string is deprecated but still supported. + types Whether the external tool is an **explore** tool, a **preview** tool, a **query** tool, a **configure** tool or any combination of these (multiple types are supported for a single tool). Configure tools require an API token because they make changes to data files (files within datasets). The older "type" keyword that allows you to pass a single type as a string is deprecated but still supported. toolUrl The **base URL** of the tool before query parameters are added. diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java b/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java index d20175b6e1a..78ccb5542ce 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java +++ b/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java @@ -391,6 +391,7 @@ public void setShowIngestSuccess(boolean showIngestSuccess) { Map> fileQueryToolsByFileId = new HashMap<>(); List fileQueryTools = new ArrayList<>(); private List datasetExploreTools; + private List datasetConfigureTools; public Boolean isHasRsyncScript() { return hasRsyncScript; @@ -2153,6 +2154,7 @@ private String init(boolean initFull) { previewTools = externalToolService.findFileToolsByType(ExternalTool.Type.PREVIEW); fileQueryTools = externalToolService.findFileToolsByType(ExternalTool.Type.QUERY); datasetExploreTools = externalToolService.findDatasetToolsByType(ExternalTool.Type.EXPLORE); + datasetConfigureTools = externalToolService.findDatasetToolsByType(ExternalTool.Type.CONFIGURE); rowsPerPage = 10; if (dataset.getId() != null && canUpdateDataset()) { hasRestrictedFiles = workingVersion.isHasRestrictedFile(); @@ -5572,6 +5574,10 @@ public List getDatasetExploreTools() { return datasetExploreTools; } + public List getDatasetConfigureTools() { + return datasetConfigureTools; + } + Boolean thisLatestReleasedVersion = null; public boolean isThisLatestReleasedVersion() { @@ -5789,6 +5795,16 @@ public void explore(ExternalTool externalTool) { PrimeFaces.current().executeScript(externalToolHandler.getExploreScript()); } + public void configure(ExternalTool externalTool) { + ApiToken apiToken = null; + User user = session.getUser(); + if (user instanceof AuthenticatedUser) { + apiToken = authService.findApiTokenByUser((AuthenticatedUser) user); + } + ExternalToolHandler externalToolHandler = new ExternalToolHandler(externalTool, dataset, apiToken, session.getLocaleCode()); + PrimeFaces.current().executeScript(externalToolHandler.getConfigureScript()); + } + private FileMetadata fileMetadataForAction; public FileMetadata getFileMetadataForAction() { diff --git a/src/main/java/edu/harvard/iq/dataverse/externaltools/ExternalToolHandler.java b/src/main/java/edu/harvard/iq/dataverse/externaltools/ExternalToolHandler.java index a52679deebc..de4317464e6 100644 --- a/src/main/java/edu/harvard/iq/dataverse/externaltools/ExternalToolHandler.java +++ b/src/main/java/edu/harvard/iq/dataverse/externaltools/ExternalToolHandler.java @@ -253,4 +253,11 @@ public String getExploreScript() { logger.fine("Exploring with " + toolUrl); return getScriptForUrl(toolUrl); } + + // TODO: Consider merging with getExploreScript + public String getConfigureScript() { + String toolUrl = this.getToolUrlWithQueryParams(); + logger.fine("Configuring with " + toolUrl); + return getScriptForUrl(toolUrl); + } } diff --git a/src/main/java/propertyFiles/Bundle.properties b/src/main/java/propertyFiles/Bundle.properties index 997f0470cc3..837d8b2f7c1 100644 --- a/src/main/java/propertyFiles/Bundle.properties +++ b/src/main/java/propertyFiles/Bundle.properties @@ -1367,6 +1367,7 @@ dataset.pageTitle=Add New Dataset dataset.accessBtn=Access Dataset dataset.accessBtn.header.download=Download Options dataset.accessBtn.header.explore=Explore Options +dataset.accessBtn.header.configure=Configure Options dataset.accessBtn.header.compute=Compute Options dataset.accessBtn.download.size=ZIP ({0}) dataset.accessBtn.too.big=The dataset is too large to download. Please select the files you need from the files table. diff --git a/src/main/webapp/dataset.xhtml b/src/main/webapp/dataset.xhtml index 67dcf89c380..55bf113abec 100644 --- a/src/main/webapp/dataset.xhtml +++ b/src/main/webapp/dataset.xhtml @@ -453,6 +453,17 @@ + + + + +
  • + + + +
  • +
    +
  • diff --git a/src/test/java/edu/harvard/iq/dataverse/api/ExternalToolsIT.java b/src/test/java/edu/harvard/iq/dataverse/api/ExternalToolsIT.java index 6f414fb3e24..a9f6055fc9e 100644 --- a/src/test/java/edu/harvard/iq/dataverse/api/ExternalToolsIT.java +++ b/src/test/java/edu/harvard/iq/dataverse/api/ExternalToolsIT.java @@ -1,5 +1,6 @@ package edu.harvard.iq.dataverse.api; +import edu.harvard.iq.dataverse.util.json.JsonUtil; import io.restassured.RestAssured; import io.restassured.path.json.JsonPath; import io.restassured.response.Response; @@ -235,6 +236,84 @@ public void testDatasetLevelTool1() { } + @Test + public void testDatasetLevelToolConfigure() { + + // Delete all external tools before testing. + Response getTools = UtilIT.getExternalTools(); + getTools.prettyPrint(); + getTools.then().assertThat() + .statusCode(OK.getStatusCode()); + String body = getTools.getBody().asString(); + JsonReader bodyObject = Json.createReader(new StringReader(body)); + JsonArray tools = bodyObject.readObject().getJsonArray("data"); + for (int i = 0; i < tools.size(); i++) { + JsonObject tool = tools.getJsonObject(i); + int id = tool.getInt("id"); + Response deleteExternalTool = UtilIT.deleteExternalTool(id); + deleteExternalTool.prettyPrint(); + } + + Response createUser = UtilIT.createRandomUser(); + createUser.prettyPrint(); + createUser.then().assertThat() + .statusCode(OK.getStatusCode()); + String apiToken = UtilIT.getApiTokenFromResponse(createUser); + + Response createDataverseResponse = UtilIT.createRandomDataverse(apiToken); + createDataverseResponse.prettyPrint(); + createDataverseResponse.then().assertThat() + .statusCode(CREATED.getStatusCode()); + + String dataverseAlias = UtilIT.getAliasFromResponse(createDataverseResponse); + + Response createDataset = UtilIT.createRandomDatasetViaNativeApi(dataverseAlias, apiToken); + createDataset.prettyPrint(); + createDataset.then().assertThat() + .statusCode(CREATED.getStatusCode()); + + Integer datasetId = JsonPath.from(createDataset.getBody().asString()).getInt("data.id"); + String datasetPid = JsonPath.from(createDataset.getBody().asString()).getString("data.persistentId"); + + String toolManifest = """ +{ + "displayName": "Turbo Dataset Config", + "description": "Read/write access.", + "types": [ + "configure" + ], + "scope": "dataset", + "toolUrl": "http://datasettool1.com", + "toolParameters": { + "queryParameters": [ + { + "datasetPid": "{datasetPid}" + }, + { + "localeCode": "{localeCode}" + } + ] + } + } +"""; + + Response addExternalTool = UtilIT.addExternalTool(JsonUtil.getJsonObject(toolManifest)); + addExternalTool.prettyPrint(); + addExternalTool.then().assertThat() + .statusCode(OK.getStatusCode()) + .body("data.displayName", CoreMatchers.equalTo("Turbo Dataset Config")); + + Response getExternalToolsByDatasetId = UtilIT.getExternalToolsForDataset(datasetId.toString(), "configure", apiToken); + getExternalToolsByDatasetId.prettyPrint(); + getExternalToolsByDatasetId.then().assertThat() + .body("data[0].displayName", CoreMatchers.equalTo("Turbo Dataset Config")) + .body("data[0].scope", CoreMatchers.equalTo("dataset")) + .body("data[0].types[0]", CoreMatchers.equalTo("configure")) + .body("data[0].toolUrlWithQueryParams", CoreMatchers.equalTo("http://datasettool1.com?datasetPid=" + datasetPid)) + .statusCode(OK.getStatusCode()); + + } + @Test public void testAddFilelToolNoFileId() throws IOException { JsonObjectBuilder job = Json.createObjectBuilder(); diff --git a/src/test/java/edu/harvard/iq/dataverse/externaltools/ExternalToolHandlerTest.java b/src/test/java/edu/harvard/iq/dataverse/externaltools/ExternalToolHandlerTest.java index 39bf96210fc..ad2a24ecdb8 100644 --- a/src/test/java/edu/harvard/iq/dataverse/externaltools/ExternalToolHandlerTest.java +++ b/src/test/java/edu/harvard/iq/dataverse/externaltools/ExternalToolHandlerTest.java @@ -1,10 +1,12 @@ package edu.harvard.iq.dataverse.externaltools; +import edu.harvard.iq.dataverse.DOIServiceBean; import edu.harvard.iq.dataverse.DataFile; import edu.harvard.iq.dataverse.DataFileServiceBean; import edu.harvard.iq.dataverse.Dataset; import edu.harvard.iq.dataverse.DatasetVersion; import edu.harvard.iq.dataverse.FileMetadata; +import edu.harvard.iq.dataverse.GlobalId; import edu.harvard.iq.dataverse.authorization.users.ApiToken; import edu.harvard.iq.dataverse.authorization.users.AuthenticatedUser; import edu.harvard.iq.dataverse.settings.JvmSettings; @@ -15,6 +17,7 @@ import jakarta.json.Json; import jakarta.json.JsonObject; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -234,4 +237,43 @@ public void testGetToolUrlWithAllowedApiCalls() { assertTrue(signedUrl.contains("&token=")); System.out.println(JsonUtil.prettyPrint(jo)); } + + @Test + @JvmSetting(key = JvmSettings.SITE_URL, value = "https://librascholar.org") + public void testDatasetConfigureTool() { + List externalToolTypes = new ArrayList<>(); + var externalToolType = new ExternalToolType(); + externalToolType.setType(ExternalTool.Type.CONFIGURE); + externalToolTypes.add(externalToolType); + var scope = ExternalTool.Scope.DATASET; + String toolUrl = "http://example.com"; + var externalTool = new ExternalTool("displayName", "toolName", "description", externalToolTypes, scope, toolUrl, "{}", DataFileServiceBean.MIME_TYPE_TSV_ALT); + + externalTool.setToolParameters(Json.createObjectBuilder() + .add("queryParameters", Json.createArrayBuilder() + .add(Json.createObjectBuilder() + .add("siteUrl", "{siteUrl}") + ) + .add(Json.createObjectBuilder() + .add("datasetPid", "{datasetPid}") + ) + .add(Json.createObjectBuilder() + .add("localeCode", "{localeCode}") + ) + ) + .build().toString()); + + var dataset = new Dataset(); + dataset.setGlobalId(new GlobalId(DOIServiceBean.DOI_PROTOCOL, "10.5072", "ABC123", null, DOIServiceBean.DOI_RESOLVER_URL, null)); + ApiToken nullApiToken = null; + String nullLocaleCode = "en"; + var externalToolHandler = new ExternalToolHandler(externalTool, dataset, nullApiToken, nullLocaleCode); + System.out.println("tool: " + externalToolHandler.getToolUrlWithQueryParams()); + assertEquals("http://example.com?siteUrl=https://librascholar.org&datasetPid=doi:10.5072/ABC123&localeCode=en", externalToolHandler.getToolUrlWithQueryParams()); + assertFalse(externalToolHandler.getExternalTool().isExploreTool()); + assertEquals("configure", externalToolHandler.getExternalTool().getExternalToolTypes().get(0).getType().toString()); + assertEquals("dataset", externalToolHandler.getExternalTool().getScope().toString()); + + } + } From 258023e4fd75850da3dc6a7160c26ef8711da158 Mon Sep 17 00:00:00 2001 From: Philip Durbin Date: Mon, 18 Sep 2023 10:34:11 -0400 Subject: [PATCH 02/10] use cog icon to match file level #9589 --- src/main/webapp/dataset.xhtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/webapp/dataset.xhtml b/src/main/webapp/dataset.xhtml index 55bf113abec..b76b33a267c 100644 --- a/src/main/webapp/dataset.xhtml +++ b/src/main/webapp/dataset.xhtml @@ -454,7 +454,7 @@
  • - +
  • From b6e3613a4d3c3dc471aac0a2e9413d126a80afc0 Mon Sep 17 00:00:00 2001 From: Philip Durbin Date: Mon, 25 Sep 2023 14:46:13 -0400 Subject: [PATCH 03/10] add popup for dataset configure external tool #9589 --- .../java/edu/harvard/iq/dataverse/DatasetPage.java | 10 ++++++++++ src/main/webapp/dataset.xhtml | 10 ++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java b/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java index 78ccb5542ce..0ed33fd216c 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java +++ b/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java @@ -392,6 +392,8 @@ public void setShowIngestSuccess(boolean showIngestSuccess) { List fileQueryTools = new ArrayList<>(); private List datasetExploreTools; private List datasetConfigureTools; + // The selected dataset-level configure tool + private ExternalTool datasetConfigureTool; public Boolean isHasRsyncScript() { return hasRsyncScript; @@ -5578,6 +5580,14 @@ public List getDatasetConfigureTools() { return datasetConfigureTools; } + public ExternalTool getDatasetConfigureTool() { + return datasetConfigureTool; + } + + public void setDatasetConfigureTool(ExternalTool datasetConfigureTool) { + this.datasetConfigureTool = datasetConfigureTool; + } + Boolean thisLatestReleasedVersion = null; public boolean isThisLatestReleasedVersion() { diff --git a/src/main/webapp/dataset.xhtml b/src/main/webapp/dataset.xhtml index b76b33a267c..d7cc18e68a2 100644 --- a/src/main/webapp/dataset.xhtml +++ b/src/main/webapp/dataset.xhtml @@ -458,9 +458,9 @@
  • - + - +
  • @@ -1001,6 +1001,12 @@ + +

    + + +

    +

    From 89dfb012458a93ec563e9c81f9458c2919b23d51 Mon Sep 17 00:00:00 2001 From: Stephen Kraffmiller Date: Tue, 26 Sep 2023 10:57:23 -0400 Subject: [PATCH 04/10] #9589 fix update for dialog --- src/main/webapp/dataset.xhtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/webapp/dataset.xhtml b/src/main/webapp/dataset.xhtml index d7cc18e68a2..5d880e8108d 100644 --- a/src/main/webapp/dataset.xhtml +++ b/src/main/webapp/dataset.xhtml @@ -458,7 +458,7 @@

  • - +
  • From 9b4a4827a6173be91e6a8266d4ad12ad890e38b7 Mon Sep 17 00:00:00 2001 From: Philip Durbin Date: Tue, 26 Sep 2023 16:06:30 -0400 Subject: [PATCH 05/10] add links to dataset configure popup #9589 --- src/main/webapp/dataset.xhtml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/main/webapp/dataset.xhtml b/src/main/webapp/dataset.xhtml index 5d880e8108d..7cc6db65b2a 100644 --- a/src/main/webapp/dataset.xhtml +++ b/src/main/webapp/dataset.xhtml @@ -1004,8 +1004,15 @@

    -

    +
    + + + + +

    From 8a3d4c23c726e70210c4248b262fe030ac30ede3 Mon Sep 17 00:00:00 2001 From: Philip Durbin Date: Tue, 26 Sep 2023 16:07:11 -0400 Subject: [PATCH 06/10] better tool name in test, add URL to popup #9589 --- .../harvard/iq/dataverse/api/ExternalToolsIT.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/test/java/edu/harvard/iq/dataverse/api/ExternalToolsIT.java b/src/test/java/edu/harvard/iq/dataverse/api/ExternalToolsIT.java index a9f6055fc9e..67fffadb488 100644 --- a/src/test/java/edu/harvard/iq/dataverse/api/ExternalToolsIT.java +++ b/src/test/java/edu/harvard/iq/dataverse/api/ExternalToolsIT.java @@ -277,13 +277,13 @@ public void testDatasetLevelToolConfigure() { String toolManifest = """ { - "displayName": "Turbo Dataset Config", - "description": "Read/write access.", + "displayName": "Dataset Configurator", + "description": "Slices! Dices! More info.", "types": [ "configure" ], "scope": "dataset", - "toolUrl": "http://datasettool1.com", + "toolUrl": "https://datasetconfigurator.com", "toolParameters": { "queryParameters": [ { @@ -301,15 +301,15 @@ public void testDatasetLevelToolConfigure() { addExternalTool.prettyPrint(); addExternalTool.then().assertThat() .statusCode(OK.getStatusCode()) - .body("data.displayName", CoreMatchers.equalTo("Turbo Dataset Config")); + .body("data.displayName", CoreMatchers.equalTo("Dataset Configurator")); Response getExternalToolsByDatasetId = UtilIT.getExternalToolsForDataset(datasetId.toString(), "configure", apiToken); getExternalToolsByDatasetId.prettyPrint(); getExternalToolsByDatasetId.then().assertThat() - .body("data[0].displayName", CoreMatchers.equalTo("Turbo Dataset Config")) + .body("data[0].displayName", CoreMatchers.equalTo("Dataset Configurator")) .body("data[0].scope", CoreMatchers.equalTo("dataset")) .body("data[0].types[0]", CoreMatchers.equalTo("configure")) - .body("data[0].toolUrlWithQueryParams", CoreMatchers.equalTo("http://datasettool1.com?datasetPid=" + datasetPid)) + .body("data[0].toolUrlWithQueryParams", CoreMatchers.equalTo("https://datasetconfigurator.com?datasetPid=" + datasetPid)) .statusCode(OK.getStatusCode()); } From b76e7ee86e0f5e272c13dbc55166041ac6fa9e86 Mon Sep 17 00:00:00 2001 From: Philip Durbin Date: Tue, 26 Sep 2023 16:10:05 -0400 Subject: [PATCH 07/10] fix typo about popup in docs #9589 --- doc/sphinx-guides/source/api/external-tools.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/sphinx-guides/source/api/external-tools.rst b/doc/sphinx-guides/source/api/external-tools.rst index ed68bb09ee0..d12e4b17549 100644 --- a/doc/sphinx-guides/source/api/external-tools.rst +++ b/doc/sphinx-guides/source/api/external-tools.rst @@ -88,7 +88,7 @@ Terminology displayName The **name** of the tool in the Dataverse installation web interface. For example, "Data Explorer". - description The **description** of the tool, which appears in a popup (for configure tools only) so the user who clicked the tool can learn about the tool before being redirected the tool in a new tab in their browser. HTML is supported. + description The **description** of the tool, which appears in a popup (for configure tools only) so the user who clicked the tool can learn about the tool before being redirected to the tool in a new tab in their browser. HTML is supported. scope Whether the external tool appears and operates at the **file** level or the **dataset** level. Note that a file level tool much also specify the type of file it operates on (see "contentType" below). From 5840a068cc0947f2d90cf52e4d8c3e118fd23c0e Mon Sep 17 00:00:00 2001 From: Philip Durbin Date: Tue, 26 Sep 2023 16:12:50 -0400 Subject: [PATCH 08/10] example tool: open link in new tab #9589 --- src/test/java/edu/harvard/iq/dataverse/api/ExternalToolsIT.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/edu/harvard/iq/dataverse/api/ExternalToolsIT.java b/src/test/java/edu/harvard/iq/dataverse/api/ExternalToolsIT.java index 67fffadb488..022747a3cdc 100644 --- a/src/test/java/edu/harvard/iq/dataverse/api/ExternalToolsIT.java +++ b/src/test/java/edu/harvard/iq/dataverse/api/ExternalToolsIT.java @@ -278,7 +278,7 @@ public void testDatasetLevelToolConfigure() { String toolManifest = """ { "displayName": "Dataset Configurator", - "description": "Slices! Dices! More info.", + "description": "Slices! Dices! More info.", "types": [ "configure" ], From f9fba208541d752ac40d406e9a2fa835a9e256a0 Mon Sep 17 00:00:00 2001 From: Philip Durbin Date: Mon, 2 Oct 2023 09:58:18 -0400 Subject: [PATCH 09/10] clarify wording per code review #9589 --- doc/sphinx-guides/source/admin/external-tools.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/sphinx-guides/source/admin/external-tools.rst b/doc/sphinx-guides/source/admin/external-tools.rst index 68b5f493d49..346ca0b15ee 100644 --- a/doc/sphinx-guides/source/admin/external-tools.rst +++ b/doc/sphinx-guides/source/admin/external-tools.rst @@ -115,7 +115,7 @@ Dataset level explore tools allow the user to explore all the files in a dataset Dataset Level Configure Tools +++++++++++++++++++++++++++++ -Dataset level configure tools can be launched by users who have edit access to the dataset and are found under the "Edit Dataset" menu. +Dataset level configure tools can be launched by users who have edit access to the dataset. These tools are found under the "Edit Dataset" menu. Writing Your Own External Tool ------------------------------ From 7540fbf653f1c80e6fab965b36e6bc897bac2fac Mon Sep 17 00:00:00 2001 From: Philip Durbin Date: Mon, 2 Oct 2023 10:30:44 -0400 Subject: [PATCH 10/10] call configure method rather than explore #9589 --- src/main/webapp/dataset.xhtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/webapp/dataset.xhtml b/src/main/webapp/dataset.xhtml index 5bb6f66ed3e..1b1d77d3057 100644 --- a/src/main/webapp/dataset.xhtml +++ b/src/main/webapp/dataset.xhtml @@ -1008,7 +1008,7 @@

    - +