@@ -7,6 +7,12 @@ import {
77 mapToMap ,
88 randomString ,
99} from '@togglecorp/fujs' ;
10+ import { type CellRichTextValue } from 'exceljs' ;
11+
12+ import {
13+ type ParsePlugin ,
14+ parsePseudoHtml ,
15+ } from '#utils/richText' ;
1016
1117type ValidationType = string | number | boolean | 'textArea' ;
1218type TypeToLiteral < T extends ValidationType > = T extends string
@@ -56,6 +62,7 @@ interface ListField<
5662 // TODO: Make this more strict
5763 optionsKey : keyof OPTIONS_MAPPING ;
5864 keyFieldName ?: string ;
65+ hiddenLabel ?: boolean ;
5966 children : TemplateSchema <
6067 VALUE ,
6168 OPTIONS_MAPPING
@@ -75,6 +82,7 @@ interface ObjectField<VALUE, OPTIONS_MAPPING extends TemplateFieldOptionsMapping
7582export interface TemplateOptionItem < T extends ValidationType > {
7683 key : T ;
7784 label : string ;
85+ description ?: string ;
7886}
7987
8088export interface TemplateFieldOptionsMapping {
@@ -98,23 +106,26 @@ export type TemplateSchema<
98106 | SelectField < ExtractValidation < VALUE > , OPTIONS_MAPPING > )
99107 ) ;
100108
109+ // NOTE: Not adding richtext support on heading
101110interface HeadingTemplateField {
102111 type : 'heading' ;
103112 name : string | number | boolean ;
104113 label : string ;
105114 outlineLevel : number ;
106115 description ?: string ;
116+ context : { field : string , key : string } [ ] ,
107117}
108118
109119type ObjectKey = string | number | symbol ;
110120
111121type InputTemplateField = {
112122 type : 'input' ;
113123 name : string | number | boolean ;
114- label : string ;
124+ label : string | CellRichTextValue ;
115125 outlineLevel : number ;
116- description ?: string ;
126+ description ?: string | CellRichTextValue ;
117127 headingBefore ?: string ;
128+ context : { field : string , key : string } [ ] ,
118129} & ( {
119130 dataValidation : 'list' ;
120131 optionsKey : ObjectKey ;
@@ -136,7 +147,30 @@ export function getCombinedKey(
136147
137148export type TemplateField = HeadingTemplateField | InputTemplateField ;
138149
139- // TODO: add test
150+ function createInsPlugin (
151+ optionsMap : TemplateFieldOptionsMapping ,
152+ context : { field : string , key : string } [ ] ,
153+ ) : ParsePlugin {
154+ return {
155+ tag : 'ins' ,
156+ transformer : ( token , richText ) => {
157+ const [ optionField , valueField ] = token . split ( '.' ) ;
158+ const currOptions = context ?. find ( ( item ) => item . field === optionField ) ;
159+ const selectedOption = currOptions
160+ ? optionsMap ?. [ optionField ] ?. find (
161+ ( option ) => String ( option . key ) === currOptions ?. key ,
162+ )
163+ : undefined ;
164+
165+ return {
166+ ...richText ,
167+ // FIXME: Need to add mechanism to identify if we have error for mapping
168+ text : selectedOption ?. [ valueField as 'description' ] ?? '' ,
169+ } ;
170+ } ,
171+ } ;
172+ }
173+
140174export function createImportTemplate <
141175 TEMPLATE_SCHEMA ,
142176 OPTIONS_MAPPING extends TemplateFieldOptionsMapping
@@ -145,6 +179,7 @@ export function createImportTemplate<
145179 optionsMap : OPTIONS_MAPPING ,
146180 fieldName : string | undefined = undefined ,
147181 outlineLevel = - 1 ,
182+ context : { field : string , key : string } [ ] = [ ] ,
148183) : TemplateField [ ] {
149184 if ( schema . type === 'object' ) {
150185 return [
@@ -158,6 +193,7 @@ export function createImportTemplate<
158193 optionsMap ,
159194 getCombinedKey ( key , fieldName ) ,
160195 outlineLevel + 1 ,
196+ context ,
161197 ) ;
162198
163199 return newFields ;
@@ -177,22 +213,26 @@ export function createImportTemplate<
177213 if ( isDefined ( schema . headingBefore ) ) {
178214 fields . push ( {
179215 type : 'heading' ,
180- name : getCombinedKey ( 'headingBefore ' , fieldName ) ,
216+ name : getCombinedKey ( 'heading_before ' , fieldName ) ,
181217 label : schema . headingBefore ,
182218 outlineLevel,
219+ context,
183220 } satisfies HeadingTemplateField ) ;
184221 }
185222
223+ const insPlugin = createInsPlugin ( optionsMap , context ) ;
224+
186225 if ( schema . type === 'input' ) {
187226 const field = {
188227 type : 'input' ,
189228 name : fieldName ,
190- label : schema . label ,
191- description : schema . description ,
229+ label : parsePseudoHtml ( schema . label , [ insPlugin ] ) ,
230+ description : parsePseudoHtml ( schema . description , [ insPlugin ] ) ,
192231 dataValidation : ( schema . validation === 'number' || schema . validation === 'date' || schema . validation === 'integer' || schema . validation === 'textArea' )
193232 ? schema . validation
194233 : undefined ,
195234 outlineLevel,
235+ context,
196236 } satisfies InputTemplateField ;
197237
198238 fields . push ( field ) ;
@@ -203,11 +243,12 @@ export function createImportTemplate<
203243 const field = {
204244 type : 'input' ,
205245 name : fieldName ,
206- label : schema . label ,
207- description : schema . description ,
246+ label : parsePseudoHtml ( schema . label , [ insPlugin ] ) ,
247+ description : parsePseudoHtml ( schema . description , [ insPlugin ] ) ,
208248 outlineLevel,
209249 dataValidation : 'list' ,
210250 optionsKey : schema . optionsKey ,
251+ context,
211252 } satisfies InputTemplateField ;
212253
213254 fields . push ( field ) ;
@@ -220,28 +261,29 @@ export function createImportTemplate<
220261 label : schema . label ,
221262 description : schema . description ,
222263 outlineLevel,
264+ context,
223265 } satisfies HeadingTemplateField ;
224266
225- // fields.push(headingField);
226267 const options = optionsMap [ schema . optionsKey ] ;
227268
228269 const optionFields = options . flatMap ( ( option ) => {
229270 const subHeadingField = {
230271 type : 'heading' ,
231- // name: option.key,
232272 name : getCombinedKey ( option . key , fieldName ) ,
233273 label : option . label ,
234274 outlineLevel : outlineLevel + 1 ,
235- // description: schema.description ,
275+ context ,
236276 } satisfies HeadingTemplateField ;
237277
278+ const combinedKey = getCombinedKey ( option . key , fieldName ) ;
238279 // eslint-disable-next-line @typescript-eslint/no-explicit-any
239280 const newFields = createImportTemplate < any , OPTIONS_MAPPING > (
240281 schema . children ,
241282 optionsMap ,
242283 // undefined,
243- getCombinedKey ( option . key , fieldName ) ,
284+ combinedKey ,
244285 outlineLevel + 1 ,
286+ [ ...context , { field : String ( schema . optionsKey ) , key : String ( option . key ) } ] ,
245287 ) ;
246288
247289 return [
@@ -252,16 +294,15 @@ export function createImportTemplate<
252294
253295 return [
254296 ...fields ,
255- headingField ,
297+ ! schema . hiddenLabel ? headingField : undefined ,
256298 ...optionFields ,
257- ] ;
299+ ] . filter ( isDefined ) ;
258300}
259301
260302function addClientId ( item : object ) : object {
261303 return { ...item , clientId : randomString ( ) } ;
262304}
263305
264- // TODO: add test
265306export function getValueFromImportTemplate <
266307 TEMPLATE_SCHEMA ,
267308 OPTIONS_MAPPING extends TemplateFieldOptionsMapping ,
@@ -348,6 +389,7 @@ export function getValueFromImportTemplate<
348389 return listValue ;
349390}
350391
392+ /*
351393type TemplateName = 'dref-application' | 'dref-operational-update' | 'dref-final-report';
352394
353395export interface ImportTemplateDescription<FormFields> {
@@ -359,7 +401,6 @@ export interface ImportTemplateDescription<FormFields> {
359401 fieldNameToTabNameMap: Record<string, string>,
360402}
361403
362- /*
363404function isValidTemplate(templateName: unknown): templateName is TemplateName {
364405 const templateNameMap: Record<TemplateName, boolean> = {
365406 'dref-application': true,
0 commit comments