)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":4146,"name":"Clark Boylan","email":"cboylan@sapwetik.org","username":"cboylan"},"change_message_id":"2dde72f261e0eb54be3b35413aa5ad21a58f95e5","unresolved":true,"context_lines":[{"line_number":20,"context_line":"documentation to be published in two different pipelines simultaneously,"},{"line_number":21,"context_line":"and jobs in those pipelines may be interacting with (perhaps waiting"},{"line_number":22,"context_line":"for a semaphore, or simply racing!) periodic deployment jobs in"},{"line_number":23,"context_line":"a periodic pipeline."},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"To address this use case it would be useful to see the actual contents"},{"line_number":26,"context_line":"of multiple pipelines on a single page.  These should be filterable"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":2,"id":"d214f5c0_3e349011","line":23,"updated":"2024-07-23 16:31:37.000000000","message":"It is also useful for common development tasks. Many of our (OpenDev) users use the existing change filter on the status page to track their changes as they move from pipeline to pipeline or enqueue to multiple pipelines.\n\nFor example we have a check arm64 pipeline that runs concurrently with check. You may be interested in results from both at the same time. Similarly you may be interested in experimental pipeline results concurrently to check/gate. Then as corvus mentions there are post merge actions that may diverge into different pipelines as well.\n\nAll that to say I think being able to see changes and projects across multiple pipelines at the same time is a very useful thing and it has a number of applications.","commit_id":"4d71b790cb210f313bc21b433eec572590bd3990"},{"author":{"_account_id":1,"name":"James E. Blair","email":"jim@acmegating.com","username":"corvus"},"change_message_id":"9d9022a05fcd41404dae057f73e714670e0c3428","unresolved":false,"context_lines":[{"line_number":20,"context_line":"documentation to be published in two different pipelines simultaneously,"},{"line_number":21,"context_line":"and jobs in those pipelines may be interacting with (perhaps waiting"},{"line_number":22,"context_line":"for a semaphore, or simply racing!) periodic deployment jobs in"},{"line_number":23,"context_line":"a periodic pipeline."},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"To address this use case it would be useful to see the actual contents"},{"line_number":26,"context_line":"of multiple pipelines on a single page.  These should be filterable"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":2,"id":"1c3a7060_aecd8189","line":23,"in_reply_to":"d214f5c0_3e349011","updated":"2024-09-09 22:45:31.000000000","message":"This is an endorsement of this change (or similar) (thanks!) which is now firmly ensconced in the stack, so I think we can consider it resolved.","commit_id":"4d71b790cb210f313bc21b433eec572590bd3990"}],"web/src/containers/status/PipelineSummary.jsx":[{"author":{"_account_id":27952,"name":"Felix Edel","email":"felix.edel@bmw.de","username":"felix.schmidt"},"change_message_id":"720df75c86fcb3ab9c2667a0cab438904ba3e801","unresolved":true,"context_lines":[{"line_number":71,"context_line":""},{"line_number":72,"context_line":"function QueueCard({pipeline, queue, expanded}) {"},{"line_number":73,"context_line":"  const [isQueueExpanded, setIsQueueExpanded] \u003d useState(undefined)"},{"line_number":74,"context_line":"  const [areAllQueuesExpanded, setAreAllQueuesExpanded] \u003d useState(undefined)"},{"line_number":75,"context_line":""},{"line_number":76,"context_line":"  // If the pipeline toggle is changed, update the queue toggles to match."},{"line_number":77,"context_line":"  if (expanded !\u003d\u003d areAllQueuesExpanded) {"}],"source_content_type":"text/jsx","patch_set":5,"id":"55e20925_b8da3325","line":74,"updated":"2024-08-08 05:18:18.000000000","message":"I think the `QueueCard` (visualizing a single queue) should only take care about the state for a single queue. The `areAllQueuesExpanded` state should be lifted to a higher component (`PipelineSummary` is the right one, I think) and be passed down as property to the `QueueCard`. We could then use the value provided by this property directly as default value for the `isQueueExpanded` state. This way we could also avoid the code in lines 76-80 (which tries to match the different states).\n\nSomething like this:\n\n```\nfunction QueueCard({pipeline, queue, allQueuesExpanded}) {\n  const [isQueueExpanded, setIsQueueExpanded] \u003d useState(allQueuesExpanded)\n  \n  const onQueueToggle \u003d () \u003d\u003e {\n  ...\n```","commit_id":"6c3e9607c77e29df33e21b9deca3f1821530af33"},{"author":{"_account_id":27952,"name":"Felix Edel","email":"felix.edel@bmw.de","username":"felix.schmidt"},"change_message_id":"3524c02acdb03fa0a20e12274000d3152c1c18b5","unresolved":false,"context_lines":[{"line_number":71,"context_line":""},{"line_number":72,"context_line":"function QueueCard({pipeline, queue, expanded}) {"},{"line_number":73,"context_line":"  const [isQueueExpanded, setIsQueueExpanded] \u003d useState(undefined)"},{"line_number":74,"context_line":"  const [areAllQueuesExpanded, setAreAllQueuesExpanded] \u003d useState(undefined)"},{"line_number":75,"context_line":""},{"line_number":76,"context_line":"  // If the pipeline toggle is changed, update the queue toggles to match."},{"line_number":77,"context_line":"  if (expanded !\u003d\u003d areAllQueuesExpanded) {"}],"source_content_type":"text/jsx","patch_set":5,"id":"b0a10d5f_0ed69329","line":74,"in_reply_to":"0634a855_d57cddd8","updated":"2024-08-08 15:11:38.000000000","message":"Thanks for the explanation. That sounds indeed unintuitive. I find the current behaviour very intuitive and I thought the default react behaviour should work the same. I also thought that the state is recreated if it\u0027s passed as a property - as the property changed and the component is re-rendered. Somehow it feels wrong if react re-renders the component with new props but keeps the old state. I\u0027ll have another look at this tomorrow.","commit_id":"6c3e9607c77e29df33e21b9deca3f1821530af33"},{"author":{"_account_id":1,"name":"James E. Blair","email":"jim@acmegating.com","username":"corvus"},"change_message_id":"cede17ffa324975493de785c4cc0d473b1886de6","unresolved":false,"context_lines":[{"line_number":71,"context_line":""},{"line_number":72,"context_line":"function QueueCard({pipeline, queue, expanded}) {"},{"line_number":73,"context_line":"  const [isQueueExpanded, setIsQueueExpanded] \u003d useState(undefined)"},{"line_number":74,"context_line":"  const [areAllQueuesExpanded, setAreAllQueuesExpanded] \u003d useState(undefined)"},{"line_number":75,"context_line":""},{"line_number":76,"context_line":"  // If the pipeline toggle is changed, update the queue toggles to match."},{"line_number":77,"context_line":"  if (expanded !\u003d\u003d areAllQueuesExpanded) {"}],"source_content_type":"text/jsx","patch_set":5,"id":"0634a855_d57cddd8","line":74,"in_reply_to":"55e20925_b8da3325","updated":"2024-08-08 14:43:46.000000000","message":"I would have liked to do that too, but the way react useState works produces unintuitive behavior.\n\nWe don\u0027t get a new state closure when we pass in a different property value to QueueCard.  That means that the default initialization behavior only works the first time.  And that means that if you click on the outer carat to expand all the queues, the queues themselves don\u0027t update.\n\nSo this code is my closest approximation of that.  It does indeed maintain the \"canonical\" state of the outer carat in the PipelineSummary, and it then passes that into the QueueCard which uses it as a default.  The way it accomplishes that is by treating any change in value of the outer state as an instruction to copy that to its own state (and that includes initialization), but otherwise, letting its own state change independently.\n\nI chose \"expanded\" as a property name to indicate that the caller wanted to express an initial state, but I\u0027m happy to change the property name to allQueuesExpanded to make that more clear.","commit_id":"6c3e9607c77e29df33e21b9deca3f1821530af33"},{"author":{"_account_id":27952,"name":"Felix Edel","email":"felix.edel@bmw.de","username":"felix.schmidt"},"change_message_id":"720df75c86fcb3ab9c2667a0cab438904ba3e801","unresolved":true,"context_lines":[{"line_number":178,"context_line":""},{"line_number":179,"context_line":"  const pipelineType \u003d pipeline.manager || \u0027unknown\u0027"},{"line_number":180,"context_line":"  const itemCount \u003d pipeline._count"},{"line_number":181,"context_line":"  const [isQueueExpanded, setIsQueueExpanded] \u003d useState(false)"},{"line_number":182,"context_line":"  const onQueueToggle \u003d () \u003d\u003e {"},{"line_number":183,"context_line":"    setIsQueueExpanded(!isQueueExpanded)"},{"line_number":184,"context_line":"  }"}],"source_content_type":"text/jsx","patch_set":5,"id":"c4e20ded_15bea1f5","line":181,"updated":"2024-08-08 05:18:18.000000000","message":"In combination with my comment above, we should rename this to `areAllQueuesExpanded` to make the difference clear.","commit_id":"6c3e9607c77e29df33e21b9deca3f1821530af33"},{"author":{"_account_id":1,"name":"James E. Blair","email":"jim@acmegating.com","username":"corvus"},"change_message_id":"cede17ffa324975493de785c4cc0d473b1886de6","unresolved":false,"context_lines":[{"line_number":178,"context_line":""},{"line_number":179,"context_line":"  const pipelineType \u003d pipeline.manager || \u0027unknown\u0027"},{"line_number":180,"context_line":"  const itemCount \u003d pipeline._count"},{"line_number":181,"context_line":"  const [isQueueExpanded, setIsQueueExpanded] \u003d useState(false)"},{"line_number":182,"context_line":"  const onQueueToggle \u003d () \u003d\u003e {"},{"line_number":183,"context_line":"    setIsQueueExpanded(!isQueueExpanded)"},{"line_number":184,"context_line":"  }"}],"source_content_type":"text/jsx","patch_set":5,"id":"abe2dda1_2fc84b78","line":181,"in_reply_to":"c4e20ded_15bea1f5","updated":"2024-08-08 14:43:46.000000000","message":"WFM.","commit_id":"6c3e9607c77e29df33e21b9deca3f1821530af33"}]}
