@@ -33,7 +33,7 @@ export const getCollectionData = async (
3333 b . value && b . value . properties && b . value . parent_id === collection . value . id
3434 ) ;
3535
36- type Row = { id : string ; [ key : string ] : RowContentType } ;
36+ type Row = { id : string ; [ key : string ] : RowContentType } ;
3737
3838 const rows : Row [ ] = [ ] ;
3939
@@ -56,6 +56,9 @@ export const getCollectionData = async (
5656
5757 const name : String = collection . value . name . join ( '' )
5858
59+
60+
61+
5962 return { rows, schema : collectionRows , name } ;
6063} ;
6164
@@ -64,6 +67,14 @@ export const getCollectionData = async (
6467
6568
6669
70+
71+
72+
73+
74+
75+
76+
77+
6778export async function collectionRoute ( req : HandlerRequest ) {
6879 const pageId = parsePageId ( req . params . pageId ) ;
6980 const page = await fetchPageById ( pageId ! , req . notionToken ) ;
@@ -81,6 +92,8 @@ export async function collectionRoute(req: HandlerRequest) {
8192
8293 const views : any [ ] = [ ]
8394
95+
96+
8497 const collectionView : {
8598 value : { id : CollectionType [ "value" ] [ "id" ] } ;
8699 } = Object . keys ( page . recordMap . collection_view ) . map ( ( k ) => {
@@ -100,9 +113,127 @@ export async function collectionRoute(req: HandlerRequest) {
100113
101114 // clean up the table order
102115 const tableProps = views [ 0 ] . format . table_properties
103- tableProps . map ( ( tableCol , i ) => {
104- tableProps [ i ] = { ...tableProps [ i ] , ...tableData . schema [ tableCol [ 'property' ] ] }
105- } )
116+ if ( tableProps ) { // only table views have tableProps; galleries etc. don't
117+ tableProps . map ( ( tableCol :any , i :any ) => {
118+ tableProps [ i ] = { ...tableProps [ i ] , ...tableData . schema [ tableCol [ 'property' ] ] }
119+ } )
120+ }
121+
122+ let query_filter = views [ 0 ] [ 'query2' ] ? views [ 0 ] [ 'query2' ] . filter : undefined
123+ let query_sort = views [ 0 ] [ 'query2' ] ? views [ 0 ] [ 'query2' ] . sort : undefined
124+
125+
126+
127+
128+
129+
130+
131+ // filters result array in place
132+ const _filter = ( { filter, property} : { filter :any , property :any } ) => {
133+ if ( ! filter )
134+ return
135+
136+ // property = column name
137+ let _op = filter . operator // "string_contains" etc.
138+ let _type = filter . value && filter . value . type // "exact"
139+ let _text = filter . value && filter . value . value // text matching against; "filter text"
140+ let column = tableProps . find ( c => c . property == property )
141+
142+ switch ( _op ) {
143+ case 'string_contains' :
144+ tableData . rows = tableData . rows . filter ( ( row :any ) => row [ column . name ] && row [ column . name ] . includes ( _text ) )
145+ break ;
146+ case 'string_is' :
147+ tableData . rows = tableData . rows . filter ( ( row :any ) => row [ column . name ] == _text )
148+ break ;
149+ case 'string_does_not_contain' :
150+ tableData . rows = tableData . rows . filter ( ( row :any ) => row [ column . name ] && ! row [ column . name ] . includes ( _text ) )
151+ break ;
152+ case 'string_starts_with' :
153+ tableData . rows = tableData . rows . filter ( ( row :any ) => row [ column . name ] && row [ column . name ] . startsWith ( _text ) )
154+ break ;
155+ case 'string_ends_with' :
156+ tableData . rows = tableData . rows . filter ( ( row :any ) => row [ column . name ] && row [ column . name ] . endsWith ( _text ) )
157+ break ;
158+ case 'is_empty' :
159+ tableData . rows = tableData . rows . filter ( ( row :any ) => row [ column . name ] && ( ! row [ column . name ] || row [ column . name ] == '' ) )
160+ break ;
161+ case 'is_not_empty' :
162+ tableData . rows = tableData . rows . filter ( ( row :any ) => row [ column . name ] && row [ column . name ] !== '' )
163+ break ;
164+ case 'enum_is_not' :
165+ tableData . rows = tableData . rows . filter ( ( row :any ) => row [ column . name ] !== _text )
166+ break ;
167+ case 'enum_is' :
168+ tableData . rows = tableData . rows . filter ( ( row :any ) => row [ column . name ] == _text )
169+ break ;
170+ case 'enum_contains' :
171+ tableData . rows = tableData . rows . filter ( ( row :any ) => row [ column . name ] && row [ column . name ] . includes ( _text ) )
172+ break ;
173+ case 'enum_does_not_contain' :
174+ tableData . rows = tableData . rows . filter ( row => {
175+ return ! row [ column . name ] || ( ! row [ column . name ] . includes ( _text ) )
176+ } )
177+ break ;
178+ }
179+ }
180+
181+
182+
183+
184+ if ( query_filter && query_filter . filters && query_filter . filters . length > 0 ) {
185+ let op = query_filter . operator
186+
187+ query_filter . filters . map ( ( filter :any ) => {
188+ _filter ( filter )
189+ } )
190+ }
191+
192+
193+
194+
195+
196+
197+
198+
199+ // return sorted data
200+ // NOTE: sorting by A-Z doesn't always return the same results as Notion, since we're not sorting by block ID's position, just a-z
201+ if ( query_sort && query_sort . length > 0 ) {
202+ query_sort . map ( ( qsort :any ) => {
203+ let column = tableProps . find ( ( c :any ) => c . property == qsort . property )
204+ if ( column . type == 'multi_select' || column . type == 'select' ) { // sort by column options array rank of first item, rather than a-z
205+ if ( qsort . direction == 'ascending' ) {
206+ tableData . rows = tableData . rows . sort ( ( a :any , b :any ) => { // get the column ranks by matching against the value and getting their index, then sorting by col index
207+ let _a = column . options . findIndex ( ( e :any ) => e . value == a [ column . name ] [ 0 ] )
208+ let _b = column . options . findIndex ( ( e :any ) => e . value == b [ column . name ] [ 0 ] )
209+ return _a < _b ? - 1 : 1
210+ } )
211+ }
212+ else {
213+ tableData . rows = tableData . rows . sort ( ( a :any , b :any ) => { // get the column ranks by matching against the value and getting their index, then sorting by col index
214+ let _a = column . options . findIndex ( ( e :any ) => e . value == a [ column . name ] [ 0 ] )
215+ let _b = column . options . findIndex ( ( e :any ) => e . value == b [ column . name ] [ 0 ] )
216+ return _a > _b ? - 1 : 1
217+ } )
218+ }
219+ } else {
220+ if ( qsort . direction == 'ascending' ) {
221+ // tableData.rows = tableData.rows.sort((a,b) => {console.log('>>',a[column.name],b[column.name], a[column.name] < b[column.name]); return a[column.name] < b[column.name] ? -1 : 1})
222+ tableData . rows = tableData . rows . sort ( ( a , b ) => a [ column . name ] > b [ column . name ] ? 1 : - 1 )
223+ } else
224+ tableData . rows = tableData . rows . sort ( ( a , b ) => a [ column . name ] < b [ column . name ] ? 1 : - 1 )
225+ }
226+ } )
227+ }
106228
107- return createResponse ( { ...tableData , columns : tableProps , sort : views [ 0 ] . page_sort , collection : collection } ) ;
229+
230+ return createResponse ( {
231+ ...tableData ,
232+ columns : tableProps ,
233+ collection : collection ,
234+ sort : views [ 0 ] . page_sort ,
235+ query_filter,
236+ query_sort,
237+ views,
238+ } ) ;
108239}
0 commit comments