Skip to content

Conversation

@kevinkim-ogp
Copy link
Contributor

@kevinkim-ogp kevinkim-ogp commented Jun 19, 2025

TL;DR

This PR adds a "Learn how to use this action" infobox to the editor right drawer that appears when an action has learning content available. The infobox shows a clickable link that opens the announcement modal with content specific to that action.

Note to reviewer: content in the modal may change, this is the first-cut of the for-each learning content.

What changed?

  • Refactored announcement modal to support different content types based on a content key
  • Added content for teaching users about for-each

How to test?

  • Create a for-each action and click on 'Learn how to use this action'
  • Ensure the ui-revamp announcement modal still works
    • Delete the announcement-modal-last-opened key from local storage
    • Refresh the page to see the modal

Screenshots

Learn for-each

Screen Recording 2025-06-19 at 11.09.45 AM.mov (uploaded via Graphite)

Copy link
Contributor Author

kevinkim-ogp commented Jun 19, 2025

@kevinkim-ogp kevinkim-ogp changed the title feat: learn more infobox [FOR-EACH-10]: Learning content for for-each Jun 19, 2025
@datadog-opengovsg
Copy link

datadog-opengovsg bot commented Jun 19, 2025

Datadog Report

Branch report: feat/learn-more-infobox
Commit report: 98fd1ae
Test service: plumber

✅ 0 Failed, 993 Passed, 0 Skipped, 2m 34.68s Total Time
⬆️ Test Sessions change in coverage: 1 increased (+0.75%)

@kevinkim-ogp kevinkim-ogp marked this pull request as ready for review June 19, 2025 03:10
@kevinkim-ogp kevinkim-ogp requested a review from a team as a code owner June 19, 2025 03:10
@kevinkim-ogp kevinkim-ogp force-pushed the chore/for-each/template branch from 1b41b7b to ca52dd1 Compare June 22, 2025 08:24
@kevinkim-ogp kevinkim-ogp force-pushed the feat/learn-more-infobox branch from a66ac22 to a10a381 Compare June 22, 2025 08:24
@kevinkim-ogp kevinkim-ogp force-pushed the chore/for-each/template branch from ca52dd1 to 6ba3c01 Compare June 24, 2025 00:10
@kevinkim-ogp kevinkim-ogp force-pushed the feat/learn-more-infobox branch 2 times, most recently from b755452 to 8b614e1 Compare June 24, 2025 03:52
@kevinkim-ogp kevinkim-ogp force-pushed the chore/for-each/template branch from 6ba3c01 to 6cbb9a2 Compare June 24, 2025 03:52
@kevinkim-ogp kevinkim-ogp mentioned this pull request Jun 24, 2025
14 tasks
### TL;DR

Added a new "Find Multiple Rows" action to the Tiles app that allows users to retrieve multiple rows from a tile based on specified filters.

This is a prerequisite for for-each.

### What changed?

- Created a new `findMultipleRows` action that retrieves multiple rows from a tile based on filter conditions
- Implemented permission checks to ensure only owners and editors can access the data
- Added support for sorting results in ascending or descending order
- Implemented scan limit functionality to control the number of rows returned
- Created comprehensive tests to verify the action's functionality
- Added appropriate error handling for invalid filters and deleted tiles
- Integrated the new action with the existing Tiles app

### How to test?

1. Create a new action and select the "Find multiple rows" event from the Tiles app
2. Select a tile and configure filter conditions to match the rows you want to retrieve
3. Choose the order of results (ascending or descending)
4. Test the step and verify that the correct rows are returned


### Note to reviewers
This is meant to be the backend implementation of the findMultipleRows action, the data-out metadata will be updated again.

Feature flag has been added on LaunchDarkly to allow for progressive rollout.
### TL;DR
* Added a new "Get Multiple Rows" action to the M365 Excel app that allows users to retrieve multiple rows from a excel table based on the specified lookup column and value.
* Cell values for each column will be combined into a single variable under that column

This is a prerequisite for for-each.

#### Note to reviewers
* This is meant to be the backend implementation of getting rows, the data-out metadata will be updated again.
* Feature flag has been added on LaunchDarkly to allow for progressive rollout.
* There will be a PR created below this to display the find multiple row results in a table

### What changed?
* Created a new getTableRows action that retrieves multiple rows from a M365 Excel table based on a specified lookup column and value
*  Only the first 500 rows that meet the condition will be returned

### How to test?
1. Create a new step with M365 Excel app and select the 'Get table rows' event.
2. Select an excel file, table, and set the lookup column and value
3. Test the step and verify that the correct rows are returned

### Screenshots

![Screenshot 2025-04-15 at 2.55.18 PM.png](https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/Wrwhm8Mmhv1Z2GwlSb7V/568e961d-cb5d-4c20-9a9d-314af6320f56.png)

![Screenshot 2025-04-15 at 2.55.27 PM.png](https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/Wrwhm8Mmhv1Z2GwlSb7V/4e89363b-bd52-4c9d-ab85-477c8bb2989c.png)
Adds a table view for displaying multiple rows in test steps for both Tiles and M365 Excel apps.

The find multiple row action is hidden by a LaunchDarkly flag. It will be made available together with the for-each release.

- Added a modal with a table view for displaying multiple rows in test steps
- Test step displays "Number of rows found" and "List of row(s) found"
- Preserved column order from when displaying results
- Improved styling to match the Tiles table design

NA

[Screen Recording 2025-04-15 at 2.53.00 PM.mov <span class="graphite__hidden">(uploaded via Graphite)</span> <img class="graphite__hidden" src="https://app.graphite.dev/api/v1/graphite/video/thumbnail/Wrwhm8Mmhv1Z2GwlSb7V/31e259a1-9416-4664-808a-74103865e704.mov" />](https://app.graphite.dev/media/video/Wrwhm8Mmhv1Z2GwlSb7V/31e259a1-9416-4664-808a-74103865e704.mov)

[Screen Recording 2025-04-15 at 2.53.33 PM.mov <span class="graphite__hidden">(uploaded via Graphite)</span> <img class="graphite__hidden" src="https://app.graphite.dev/api/v1/graphite/video/thumbnail/Wrwhm8Mmhv1Z2GwlSb7V/bd0edfa3-2a95-4679-875e-17c47b66f787.mov" />](https://app.graphite.dev/media/video/Wrwhm8Mmhv1Z2GwlSb7V/bd0edfa3-2a95-4679-875e-17c47b66f787.mov)
…1023)

## TL;DR
Refactored to dynamically obtain column values for the `findMultipleRow` action instead of storing them in the execution step’s `dataOut`, to avoid duplicate data — since the values are already stored in the row data.

**Note to reviewers**
The modal that displays the list of rows in table format will be updated in a subsequent PR. As of now, the test result can still be verified in the output after testing the step.

## What changed?
* Restructured the output format from `rows.rowData` to `data.rows` for better semantic clarity
* Removed unnecessary consolidated column metadata as it is already available within the `data`
* Added explicit value paths (`data.rows.*.data.<columnId>`) to column definitions for dynamic data access
* Changed the type in metadata from 'array' to 'multiple-row-object' to better represent the data structure

## How to test?
Set up the find multiple row action and test the following:
- [ ] Number of rows returned is correct
- [ ] Test result shows the correct number of columns with:
  - `id`: Tile column id (uuid)
  - `name`: Tile column name
  - `value`: step variable-like string in this format `data.rows.*.data.<columnId>`


## Screenshots

![Screenshot 2025-06-02 at 9.23.58 AM.png](https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/Wrwhm8Mmhv1Z2GwlSb7V/01985352-322b-4bf7-ad38-ccc8c48be2b1.png)

![Screenshot 2025-06-02 at 9.25.16 AM.png](https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/Wrwhm8Mmhv1Z2GwlSb7V/87fc45fe-9956-4d6e-91b2-ea4829ef69dc.png)

![Screenshot 2025-06-02 at 9.25.30 AM.png](https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/Wrwhm8Mmhv1Z2GwlSb7V/20135570-2cc1-453e-b21c-e2e25338ab49.png)
…1025)

## TL;DR
Refactored to dynamically obtain column values for the `getTableRows` action instead of storing them in the execution step’s `dataOut`, to avoid duplicate data — since the values are already stored in the row data.

**Note to reviewers**
The modal that displays the list of rows in table format will be updated in a subsequent PR. As of now, the test result can still be verified in the output after testing the step.

## What changed?
* Restructured output to align with Tiles multiple row output:
  * `rows.rowData` to `data.rows` for better semantic clarity\
  * Removed unnecessary consolidated column metadata as it is already available within the `data`
  * Removed unnecessary `tableRowIndex` and `sheetRowNumber`
* Added explicit value paths (`data.rows.*.data.<hex-encoded-column-name>`) to column definitions for dynamic data access
* Changed the type in metadata from 'array' to 'multiple-row-object' to better represent the data structure

## How to test?
Set up the find table rows action and test the following:
- [ ] Number of rows returned is correct
- [ ] Test result shows the correct number of columns with:
  - `id`: Tile column id (uuid)
  - `name`: Tile column name
  - `value`: step variable-like string in this format `data.rows.*.data.<hex-encoded-column-name>`


## Screenshots

![Screenshot 2025-06-02 at 9.47.25 AM.png](https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/Wrwhm8Mmhv1Z2GwlSb7V/03295d11-07dc-47dd-8e91-2f764d210330.png)

![Screenshot 2025-06-02 at 9.47.36 AM.png](https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/Wrwhm8Mmhv1Z2GwlSb7V/45d33307-5712-4da2-af52-ee77c789b5b9.png)

![Screenshot 2025-06-02 at 9.47.43 AM.png](https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/Wrwhm8Mmhv1Z2GwlSb7V/0b208bd5-5ad4-4359-a67c-e7337acb2c12.png)
@kevinkim-ogp kevinkim-ogp force-pushed the fix/for-each/handle-zero-values branch from f3f0cd5 to e854fc7 Compare July 14, 2025 09:20
@kevinkim-ogp kevinkim-ogp force-pushed the feat/learn-more-infobox branch from 22b6d78 to e023cd5 Compare July 14, 2025 09:21
### TL;DR
This PR adds a "New" badge to actions marked with `isNew: true` and ensures they appear at the top of their respective app sections in the UI. 

### What changed?
- Added `isNew` property to the GraphQL schema for both Action and Trigger types
- Created a reusable `NewBadge` component to display the "New" badge consistently
- Modified the app sorting logic to prioritise actions with `isNew: true` within each app
- Added the `isNew: true` flag to several actions:
  - "Find table rows" in Excel
  - "Find multiple rows" in Tiles
  - "For each" in Toolbox
- Updated the UI components to display the "New" badge next to actions and triggers when applicable

### Screenshots
- For each action
![Screenshot 2025-07-09 at 7.30.28 PM.png](https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/Wrwhm8Mmhv1Z2GwlSb7V/57b7c962-cd09-4f4a-900a-139c3381ed4e.png)

- Find multiple rows action

![Screenshot 2025-07-09 at 7.32.03 PM.png](https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/Wrwhm8Mmhv1Z2GwlSb7V/3b2c4843-209a-4b16-a3f4-d1519450339a.png)

![Screenshot 2025-07-09 at 7.32.42 PM.png](https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/Wrwhm8Mmhv1Z2GwlSb7V/cdf051b1-e9b6-4054-9feb-d2da8483f6c2.png)
@kevinkim-ogp kevinkim-ogp force-pushed the fix/for-each/handle-zero-values branch from e854fc7 to 5eba251 Compare July 14, 2025 09:29
@kevinkim-ogp kevinkim-ogp force-pushed the feat/learn-more-infobox branch from e023cd5 to 358b7b4 Compare July 14, 2025 09:29
@kevinkim-ogp kevinkim-ogp marked this pull request as draft July 14, 2025 09:56
### TL;DR
Added a new 'partial-success' status for For Each iterations to better represent scenarios where steps complete with non-critical errors. This also makes it easier for users to filter iterations for retry on the Executions page.
_Partial successes are most likely to occur in Email by Postman actions where recipient emails are blacklisted._

### What changed?

- Added a new 'partial-success' status type to the execution step model
- Updated the frontend to display and filter partial success states
- Added a partial success icon and updated the GroupStatusFilter component to include the new status
- Modified the iteration status detection logic to identify partial success when a step has errorDetails but still completes

### How to test?
1. Create a Pipe with a ForEach step that includes an action that might result in partial success (e.g., email sending with some blacklisted recipients - `[email protected]`)
2. Execute the workflow and observe the partial success status in the execution page

- [ ] Execution should still be a success
- [ ] For each step should show as partial success
- [ ] Iteration selector should show the correct iteration with the partial success state
- [ ] Status filters should filter the different status correctly


### Screenshots

[Screen Recording 2025-07-09 at 11.14.01 PM.mov <span class="graphite__hidden">(uploaded via Graphite)</span> <img class="graphite__hidden" src="https://app.graphite.dev/api/v1/graphite/video/thumbnail/Wrwhm8Mmhv1Z2GwlSb7V/35adf176-1bb6-45eb-892b-a798b93f4780.mov" />](https://app.graphite.dev/media/video/Wrwhm8Mmhv1Z2GwlSb7V/35adf176-1bb6-45eb-892b-a798b93f4780.mov)
@kevinkim-ogp kevinkim-ogp force-pushed the fix/for-each/handle-zero-values branch from 5eba251 to b7afc52 Compare July 14, 2025 10:56
@kevinkim-ogp kevinkim-ogp force-pushed the feat/learn-more-infobox branch from 358b7b4 to 4aead77 Compare July 14, 2025 10:56
### TL;DR
Allows users to replace variables in single-select mode by clicking on a variable in the input and selecting a new one from the suggestions popover.


### How to test?
- [ ] Single select inputs (For-each item)
  - [ ] Can select variable in empty input
  - [ ] Can delete variable and select a new variable
  - [ ] Can select variable and replace with another variable from the suggestions popover

- [ ] All other inputs
  - [ ] Can still select multiple variables and type freely in them
  - [ ] Can select variable and replace with another variable from the suggestions popover

### Screenshots

[Screen Recording 2025-07-09 at 10.59.31 PM.mov <span class="graphite__hidden">(uploaded via Graphite)</span> <img class="graphite__hidden" src="https://app.graphite.dev/api/v1/graphite/video/thumbnail/Wrwhm8Mmhv1Z2GwlSb7V/14695cf9-0766-49d4-b236-c275dc4856a3.mov" />](https://app.graphite.dev/media/video/Wrwhm8Mmhv1Z2GwlSb7V/14695cf9-0766-49d4-b236-c275dc4856a3.mov)

### Why make this change?
Previously, users could replace variables by clicking on them and selecting a new one from the suggestions popover. This change prevents a regression and restores that expected behaviour.
@kevinkim-ogp kevinkim-ogp force-pushed the fix/for-each/handle-zero-values branch 2 times, most recently from 1327fb0 to 41cd5a8 Compare July 14, 2025 11:00
@kevinkim-ogp kevinkim-ogp force-pushed the feat/learn-more-infobox branch from 4aead77 to 4f13744 Compare July 14, 2025 11:00
@kevinkim-ogp kevinkim-ogp changed the base branch from fix/for-each/handle-zero-values to graphite-base/1066 July 14, 2025 11:01
### TL;DR
Fixed inconsistent handling of empty values in For Each action, which caused issues when cell values were `0` by standardising how empty values and string conversions are managed.

### What changed?

- Modified `getDataOutMetadata.ts` to consistently convert displayed values to strings using `String()` instead of relying on implicit conversion
- Changed empty value representation from space character (`' '`) to empty string (`''`) in tests and implementation so that checking against step parameters against test executions yielded accurate results of whether that was the latest test
- Fixed the fallback logic in `computeForEachParameters.ts` to use nullish coalescing (`??`) instead of logical OR (`||`) to properly handle falsy values like `0` or `false`
- Simplified the variable value selection in `RichTextEditor` component using nullish coalescing

### How to test?

1. Create a Pipe with a For Each action
2. Test with various data types including empty values, zeros, and boolean values

- [ ] Variable pills should show `0`
- [ ] Variable should show `false`
- [ ] Variable with empty displayedValue should be an empty variable pill with dotted outline


### Screenshots
#### Before

![Screenshot 2025-07-10 at 9.47.09 PM.png](https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/Wrwhm8Mmhv1Z2GwlSb7V/8404508c-85ee-43ec-a6f1-ca8357ea45a5.png)

#### After

![Screenshot 2025-07-10 at 9.54.31 PM.png](https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/Wrwhm8Mmhv1Z2GwlSb7V/d57d32a2-4cd8-4140-bb64-424b1f5a810e.png)

### Why make this change?

This change ensures consistent handling of empty and falsy values throughout the For Each action. The previous implementation had inconsistencies where empty values were sometimes represented as spaces and numeric values weren't properly converted to strings. Using nullish coalescing instead of logical OR prevents valid falsy values (like 0 or false) from being incorrectly replaced with empty strings.
@kevinkim-ogp kevinkim-ogp force-pushed the feat/learn-more-infobox branch from 4f13744 to a3b41b4 Compare July 14, 2025 11:02
@graphite-app graphite-app bot changed the base branch from graphite-base/1066 to trunk/for-each July 14, 2025 11:02
@kevinkim-ogp kevinkim-ogp force-pushed the feat/learn-more-infobox branch from a3b41b4 to 98fd1ae Compare July 14, 2025 11:02
Base automatically changed from trunk/for-each to develop-v2 July 17, 2025 08:53
@kevinkim-ogp
Copy link
Contributor Author

no longer required, a separate PR has been raised to open a link to the guide instead of showing the learning content directly in the editor

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants