@@ -21,7 +21,7 @@ import SequelizeRepository from '@/database/repositories/sequelizeRepository'
2121
2222import { IServiceOptions } from '../IServiceOptions'
2323
24- type IOrganizationSummary = Pick < IOrganization , 'id' | 'displayName' | 'logo' >
24+ type IOrganizationSummary = Pick < IOrganization , 'id' | 'displayName' | 'logo' | 'createdAt' >
2525
2626export default class MemberOrganizationsService extends LoggerBase {
2727 options : IServiceOptions
@@ -64,7 +64,12 @@ export default class MemberOrganizationsService extends LoggerBase {
6464 in : orgIds ,
6565 } ,
6666 } ,
67- fields : [ OrganizationField . ID , OrganizationField . DISPLAY_NAME , OrganizationField . LOGO ] ,
67+ fields : [
68+ OrganizationField . ID ,
69+ OrganizationField . DISPLAY_NAME ,
70+ OrganizationField . LOGO ,
71+ OrganizationField . CREATED_AT ,
72+ ] ,
6873 } )
6974 }
7075
@@ -84,15 +89,64 @@ export default class MemberOrganizationsService extends LoggerBase {
8489 { } ,
8590 )
8691
87- // Format the results
88- return memberOrganizations . map ( ( mo ) => ( {
89- ...( orgByid [ mo . organizationId ] || { } ) ,
90- id : mo . organizationId ,
91- memberOrganizations : {
92- ...mo ,
93- affiliationOverride : affiliationOverrides . find ( ( ao ) => ao . memberOrganizationId === mo . id ) ,
94- } ,
95- } ) )
92+ // Format the results and order by dateStart and dateEnd
93+ const allOrganizations = memberOrganizations
94+ . filter ( ( mo ) => orgByid [ mo . organizationId ] ) // Only include non-deleted organizations
95+ . map ( ( mo ) => ( {
96+ ...( orgByid [ mo . organizationId ] || { } ) ,
97+ id : mo . organizationId ,
98+ memberOrganizations : {
99+ ...mo ,
100+ affiliationOverride : affiliationOverrides . find ( ( ao ) => ao . memberOrganizationId === mo . id ) ,
101+ } ,
102+ } ) )
103+ . sort ( ( a , b ) => {
104+ if ( ! a || ! b ) {
105+ return 0
106+ }
107+
108+ // Sort by dateStart (newest first), then by dateEnd (active first - null dateEnd comes first)
109+ const aDateStart = a . memberOrganizations . dateStart
110+ ? new Date ( a . memberOrganizations . dateStart ) . getTime ( )
111+ : 0
112+ const bDateStart = b . memberOrganizations . dateStart
113+ ? new Date ( b . memberOrganizations . dateStart ) . getTime ( )
114+ : 0
115+
116+ if ( aDateStart !== bDateStart ) {
117+ return bDateStart - aDateStart // Newest dateStart first
118+ }
119+
120+ // If dateStart is the same, prioritize active memberships (null dateEnd)
121+ const aDateEnd = a . memberOrganizations . dateEnd
122+ const bDateEnd = b . memberOrganizations . dateEnd
123+
124+ if ( ! aDateEnd && bDateEnd ) return - 1 // a is active, b is not
125+ if ( aDateEnd && ! bDateEnd ) return 1 // b is active, a is not
126+
127+ // Both have null dateEnd and dateStart - sort by createdAt, then alphabetically
128+ if ( ! aDateEnd && ! bDateEnd && aDateStart === 0 && bDateStart === 0 ) {
129+ // First try to sort by createdAt
130+ const aCreatedAt = a . createdAt ? new Date ( a . createdAt ) . getTime ( ) : 0
131+ const bCreatedAt = b . createdAt ? new Date ( b . createdAt ) . getTime ( ) : 0
132+
133+ if ( aCreatedAt !== bCreatedAt ) {
134+ return bCreatedAt - aCreatedAt // Newest createdAt first
135+ }
136+
137+ // If createdAt is also the same, sort alphabetically by displayName
138+ const aName = ( a . displayName || '' ) . toLowerCase ( )
139+ const bName = ( b . displayName || '' ) . toLowerCase ( )
140+ return aName . localeCompare ( bName )
141+ }
142+
143+ if ( ! aDateEnd && ! bDateEnd ) return 0 // both are active with same dateStart
144+
145+ // Both have dateEnd, sort by dateEnd (newest first)
146+ return new Date ( bDateEnd ) . getTime ( ) - new Date ( aDateEnd ) . getTime ( )
147+ } )
148+
149+ return allOrganizations
96150 }
97151
98152 // Member organization creation
0 commit comments