mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	feat: add milestones to search results (#9739)
This commit is contained in:
		
							parent
							
								
									49a1dac2c9
								
							
						
					
					
						commit
						8f117ac18e
					
				| @ -76,6 +76,13 @@ class FeatureSearchStore implements IFeatureSearchStore { | ||||
|             yes: Number(r.yes) || 0, | ||||
|             no: Number(r.no) || 0, | ||||
|             changeRequestIds: r.change_request_ids ?? [], | ||||
|             ...(r.milestone_name | ||||
|                 ? { | ||||
|                       milestoneName: r.milestone_name, | ||||
|                       milestoneOrder: r.milestone_order, | ||||
|                       totalMilestones: Number(r.total_milestones || 0), | ||||
|                   } | ||||
|                 : {}), | ||||
|         }; | ||||
|     } | ||||
| 
 | ||||
| @ -371,6 +378,53 @@ class FeatureSearchStore implements IFeatureSearchStore { | ||||
|                     }, | ||||
|                 ) | ||||
|                 .select('feature_cr.change_request_ids'); | ||||
| 
 | ||||
|             finalQuery | ||||
|                 .leftJoin( | ||||
|                     this.db | ||||
|                         .with('total_milestones', (qb) => { | ||||
|                             qb.select('release_plan_definition_id') | ||||
|                                 .count('* as total_milestones') | ||||
|                                 .from('milestones') | ||||
|                                 .groupBy('release_plan_definition_id'); | ||||
|                         }) | ||||
|                         .select([ | ||||
|                             'rpd.feature_name', | ||||
|                             'rpd.environment', | ||||
|                             'active_milestone.sort_order AS milestone_order', | ||||
|                             'total_milestones.total_milestones', | ||||
|                             'active_milestone.name AS milestone_name', | ||||
|                         ]) | ||||
|                         .from('release_plan_definitions AS rpd') | ||||
|                         .join( | ||||
|                             'total_milestones', | ||||
|                             'total_milestones.release_plan_definition_id', | ||||
|                             'rpd.id', | ||||
|                         ) | ||||
|                         .join( | ||||
|                             'milestones AS active_milestone', | ||||
|                             'active_milestone.id', | ||||
|                             'rpd.active_milestone_id', | ||||
|                         ) | ||||
|                         .where('rpd.discriminator', 'plan') | ||||
|                         .as('feature_release_plan'), | ||||
|                     function () { | ||||
|                         this.on( | ||||
|                             'feature_release_plan.feature_name', | ||||
|                             '=', | ||||
|                             'ranked_features.feature_name', | ||||
|                         ).andOn( | ||||
|                             'feature_release_plan.environment', | ||||
|                             '=', | ||||
|                             'ranked_features.environment', | ||||
|                         ); | ||||
|                     }, | ||||
|                 ) | ||||
|                 .select([ | ||||
|                     'feature_release_plan.milestone_name', | ||||
|                     'feature_release_plan.milestone_order', | ||||
|                     'feature_release_plan.total_milestones', | ||||
|                 ]); | ||||
|         } | ||||
|         this.queryExtraData(finalQuery); | ||||
|         const rows = await finalQuery; | ||||
|  | ||||
| @ -1425,3 +1425,93 @@ test('should return change request ids per environment', async () => { | ||||
|         ], | ||||
|     }); | ||||
| }); | ||||
| 
 | ||||
| const createReleasePlan = async ({ | ||||
|     feature, | ||||
|     environment, | ||||
|     planId, | ||||
| }: { feature: string; environment: string; planId: string }) => { | ||||
|     await db.rawDatabase('release_plan_definitions').insert({ | ||||
|         id: planId, | ||||
|         discriminator: 'plan', | ||||
|         name: 'plan', | ||||
|         feature_name: feature, | ||||
|         environment: environment, | ||||
|         created_by_user_id: 1, | ||||
|     }); | ||||
| }; | ||||
| 
 | ||||
| const createMilestone = async ({ | ||||
|     id, | ||||
|     name, | ||||
|     order, | ||||
|     planId, | ||||
| }: { id: string; name: string; order: number; planId: string }) => { | ||||
|     await db.rawDatabase('milestones').insert({ | ||||
|         id, | ||||
|         name, | ||||
|         sort_order: order, | ||||
|         release_plan_definition_id: planId, | ||||
|     }); | ||||
| }; | ||||
| 
 | ||||
| const activateMilestone = async ({ | ||||
|     planId, | ||||
|     milestoneId, | ||||
| }: { planId: string; milestoneId: string }) => { | ||||
|     await db | ||||
|         .rawDatabase('release_plan_definitions') | ||||
|         .update({ active_milestone_id: milestoneId }) | ||||
|         .where('id', planId); | ||||
| }; | ||||
| 
 | ||||
| test('should return release plan milestones', async () => { | ||||
|     await app.createFeature('my_feature_a'); | ||||
| 
 | ||||
|     await createReleasePlan({ | ||||
|         feature: 'my_feature_a', | ||||
|         environment: 'development', | ||||
|         planId: 'plan0', | ||||
|     }); | ||||
|     await createMilestone({ | ||||
|         id: 'milestone0', | ||||
|         name: 'Milestone 1', | ||||
|         order: 0, | ||||
|         planId: 'plan0', | ||||
|     }); | ||||
|     await createMilestone({ | ||||
|         id: 'milestone1', | ||||
|         name: 'Milestone 2', | ||||
|         order: 1, | ||||
|         planId: 'plan0', | ||||
|     }); | ||||
|     await createMilestone({ | ||||
|         id: 'milestone3', | ||||
|         name: 'Milestone 3', | ||||
|         order: 2, | ||||
|         planId: 'plan0', | ||||
|     }); | ||||
|     await activateMilestone({ planId: 'plan0', milestoneId: 'milestone1' }); | ||||
| 
 | ||||
|     const { body } = await searchFeatures({}); | ||||
| 
 | ||||
|     expect(body).toMatchObject({ | ||||
|         features: [ | ||||
|             { | ||||
|                 name: 'my_feature_a', | ||||
|                 environments: [ | ||||
|                     { name: 'default' }, | ||||
|                     { | ||||
|                         name: 'development', | ||||
|                         totalMilestones: 3, | ||||
|                         milestoneName: 'Milestone 2', | ||||
|                         milestoneOrder: 1, | ||||
|                     }, | ||||
|                     { name: 'production' }, | ||||
|                 ], | ||||
|             }, | ||||
|         ], | ||||
|     }); | ||||
|     expect(body.features[0].environments[0].milestoneName).toBeUndefined(); | ||||
|     expect(body.features[0].environments[2].milestoneName).toBeUndefined(); | ||||
| }); | ||||
|  | ||||
| @ -71,6 +71,24 @@ export const featureEnvironmentSchema = { | ||||
|             description: | ||||
|                 'Experimental. A list of change request identifiers for actionable change requests that are not Cancelled, Rejected or Approved.', | ||||
|         }, | ||||
|         milestoneName: { | ||||
|             type: 'string', | ||||
|             example: 'Phase One', | ||||
|             description: | ||||
|                 'Experimental: The name of the currently active release plan milestone', | ||||
|         }, | ||||
|         milestoneOrder: { | ||||
|             type: 'number', | ||||
|             example: 0, | ||||
|             description: | ||||
|                 'Experimental: The zero-indexed order of currently active milestone in the list of all release plan milestones', | ||||
|         }, | ||||
|         totalMilestones: { | ||||
|             type: 'number', | ||||
|             example: 0, | ||||
|             description: | ||||
|                 'Experimental: The total number of milestones in the feature environment release plan', | ||||
|         }, | ||||
|         lastSeenAt: { | ||||
|             type: 'string', | ||||
|             format: 'date-time', | ||||
|  | ||||
| @ -60,6 +60,7 @@ process.nextTick(async () => { | ||||
|                         tagTypeColor: true, | ||||
|                         newStrategyDropdown: true, | ||||
|                         addEditStrategy: true, | ||||
|                         flagsOverviewSearch: true, | ||||
|                     }, | ||||
|                 }, | ||||
|                 authentication: { | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user