11import { DraftChangeHandler , OperationTriggerHandler , PendingRowsChangeHandler , PermissionRowsChangeHandler , PerTabFieldState , ResolverTitleChangeHandler } from "../app" ;
22import { MaterialSymbol } from "../material-symbol" ;
3- import { AdminRecordStore , FieldDefinition , FieldType , IdString , KeyString , PermissionRow , WikiAdminRecord , WritablePrefixRow } from "./tabs" ;
3+ import { AdminRecordStore , FieldDefinition , FieldType , IdString , PermissionRow , WikiAdminRecord , WritablePrefixRow } from "./tabs" ;
44import { definitely , is } from "./utils" ;
55import warningIcon from "@material-symbols/svg-400/outlined/warning.svg" ;
66import { findTemplateRecordForWikiRecord , jsonReviver } from "./store" ;
@@ -55,25 +55,25 @@ function buildEffectivePrefixObject(writablePrefixBags: (readonly WritablePrefix
5555 }
5656 }
5757 return Object . entries ( result )
58- . map ( ( [ prefix , bagName ] ) => ( { prefix, bagName : new KeyString ( bagName ) } ) )
58+ . map ( ( [ prefix , bagName ] ) => ( { prefix, bagName } ) )
5959 . sort ( ( a , b ) => b . prefix . length - a . prefix . length ) ;
6060}
6161
6262
6363function getLookupOptions ( fieldKey : string , itemsByTab : AdminRecordStore ) : string [ ] {
6464 if ( fieldKey === "readonlyBags" || fieldKey === "writablePrefixBags" ) {
65- return Array . from ( new Set ( itemsByTab . bags . map ( ( item ) => item . name . toString ( ) ) . filter ( Boolean ) ) ) ;
65+ return Array . from ( new Set ( itemsByTab . bags . map ( ( item ) => item . name ) . filter ( Boolean ) ) ) ;
6666 }
6767 if ( fieldKey === "plugins" ) {
68- return Array . from ( new Set ( itemsByTab . plugins . map ( ( item ) => item . name . toString ( ) ) . filter ( Boolean ) ) ) ;
68+ return Array . from ( new Set ( itemsByTab . plugins . map ( ( item ) => item . name ) . filter ( Boolean ) ) ) ;
6969 }
7070 if ( fieldKey === "userRoles" ) {
71- return Array . from ( new Set ( itemsByTab . roles . map ( ( item ) => item . name . toString ( ) ) . filter ( Boolean ) ) ) ;
71+ return Array . from ( new Set ( itemsByTab . roles . map ( ( item ) => item . name ) . filter ( Boolean ) ) ) ;
7272 }
7373 if ( fieldKey === "permissions" || fieldKey === "recipePermissions" ) {
7474 return Array . from ( new Set ( [
75- ...itemsByTab . bags . flatMap ( ( item ) => item . bagPermissions . map ( ( row ) => row . role . toString ( ) ) ) ,
76- ...itemsByTab . wikis . flatMap ( ( item ) => item . recipePermissions . map ( ( row ) => row . role . toString ( ) ) ) ,
75+ ...itemsByTab . bags . flatMap ( ( item ) => item . bagPermissions . map ( ( row ) => row . role ) ) ,
76+ ...itemsByTab . wikis . flatMap ( ( item ) => item . recipePermissions . map ( ( row ) => row . role ) ) ,
7777 ] . filter ( Boolean ) ) ) ;
7878 }
7979 return [ ] ;
@@ -82,7 +82,7 @@ function getLookupOptions(fieldKey: string, itemsByTab: AdminRecordStore): strin
8282export function formatFieldValue ( value : any ) : string {
8383 if ( typeof value === "string"
8484 || value instanceof IdString
85- || value instanceof KeyString )
85+ )
8686 return value . trim ( ) || "—" ;
8787 if ( Array . isArray ( value ) ) {
8888 if ( ! value . length ) return "—" ;
@@ -186,7 +186,7 @@ function renderTableField(ctx: ReadonlyFieldContext) {
186186function renderLinesList ( value : readonly string [ ] , key : string , itemsByTab ?: AdminRecordStore ) {
187187 const missingCheck =
188188 itemsByTab ?
189- ( key === "effectiveReadonlyBags" || key === "readonlyBags" ) ? new Set ( Array . from ( itemsByTab . availableBagNames , e => e . toString ( ) ) ) :
189+ ( key === "effectiveReadonlyBags" || key === "readonlyBags" ) ? new Set ( Array . from ( itemsByTab . availableBagNames ) ) :
190190 ( key === "effectivePluginSet" || key === "plugins" ) ? itemsByTab . availablePluginNames :
191191 null : null ;
192192 const lines = value . map ( line => ( { line, missing : missingCheck && ! missingCheck . has ( line ) , } ) ) ;
@@ -320,7 +320,7 @@ function renderSearchMultiselectFieldEditor(ctx: FieldEditorContext<any>) {
320320 < div class = "field-callout" >
321321 < p > Readonly bags from template</ p >
322322 < ul class = "value-list" >
323- { templateReadonlyBagLines . length ? templateReadonlyBagLines . map ( ( bag ) => < li > { bag . toString ( ) } </ li > ) : < li > No template readonly bags</ li > }
323+ { templateReadonlyBagLines . length ? templateReadonlyBagLines . map ( ( bag ) => < li > { bag } </ li > ) : < li > No template readonly bags</ li > }
324324 </ ul >
325325 </ div >
326326 ) : null }
@@ -337,16 +337,33 @@ function renderSearchMultiselectFieldEditor(ctx: FieldEditorContext<any>) {
337337 ) ;
338338}
339339
340- function renderPermissionTableFieldEditor ( ctx : FieldEditorContext < any > ) {
340+ function renderPermissionTableFieldViewer ( ctx : ReadonlyFieldContext < readonly PermissionRow [ ] > ) {
341+ const permissionRows = ctx . value ;
342+ if ( ! permissionRows . length ) {
343+ return < div class = "field-callout" > < p > No permissions assigned.</ p > </ div > ;
344+ }
345+ return < table class = "value-table" >
346+ { permissionRows . map ( ( row ) => (
347+ < tr >
348+ < td > { row . role || "—" } </ td >
349+ < td > < span class = "pill-value pill-value-small" > { formatPermissionLevel ( row . level ) } </ span > </ td >
350+ </ tr >
351+ ) ) }
352+ </ table > ;
353+ }
354+
355+ function renderPermissionTableFieldEditor ( ctx : FieldEditorContext < readonly PermissionRow [ ] > ) {
341356 const { field, disabled, fieldState, itemsByTab, inputId, onDraftChange, onTransientPermissionRowsChange } = ctx ;
342- definitely < readonly PermissionRow [ ] > ( ctx . value ) ;
357+ if ( field . mode === "server" || field . mode === "" ) {
358+ return renderPermissionTableFieldViewer ( ctx ) ;
359+ }
343360 const permissionRows = ctx . value ;
344361 const lookupOptions = getLookupOptions ( field . key , itemsByTab ) ;
345362 const availableLevels = getPermissionLevelsForField ( field . key ) ;
346363 const transientPermissionRows = fieldState . transientPermissionRows [ field . key ] ?? [ ] ;
347364 const displayedPermissionRows = permissionRows . length || transientPermissionRows . length
348365 ? [ ...permissionRows , ...transientPermissionRows ]
349- : [ { role : new KeyString ( "" ) , level : availableLevels [ 0 ] as PermissionLevel } ] ;
366+ : [ { role : "" , level : availableLevels [ 0 ] as PermissionLevel } ] ;
350367
351368 const persistPermissionRows = ( rows : PermissionRow [ ] ) => {
352369 const persistedRows = rows . filter ( ( row ) => row . role . trim ( ) ) ;
@@ -361,13 +378,13 @@ function renderPermissionTableFieldEditor(ctx: FieldEditorContext<any>) {
361378 < div key = { `${ field . key } -permission-${ index } ` } class = "row-editor-row row-editor-row-wide row-editor-row-permission" >
362379 { renderSearchableInput ( {
363380 id : `${ inputId } -${ index } -role` ,
364- currentValue : row . role . toString ( ) ,
381+ currentValue : row . role ,
365382 placeholder : "Role" ,
366383 options : lookupOptions ,
367384 disabled : ctx . disabled ,
368385 onInput : ( nextValue ) => {
369386 const nextRows = [ ...displayedPermissionRows ] ;
370- nextRows [ index ] = { ...row , role : new KeyString ( nextValue ) } ;
387+ nextRows [ index ] = { ...row , role : nextValue } ;
371388 persistPermissionRows ( nextRows ) ;
372389 } ,
373390 } ) }
@@ -388,7 +405,7 @@ function renderPermissionTableFieldEditor(ctx: FieldEditorContext<any>) {
388405 ) ) }
389406 < button type = "button" class = "ghost-button" disabled = { disabled } onclick = { ( ) =>
390407 onTransientPermissionRowsChange ( field . key , [ ...transientPermissionRows , {
391- role : new KeyString ( "" ) , level : availableLevels [ 0 ] as PermissionLevel
408+ role : "" , level : availableLevels [ 0 ] as PermissionLevel
392409 } ] ) } > Add permission</ button >
393410 </ div >
394411 ) ;
@@ -405,7 +422,7 @@ function renderPrefixMappingRows(displayedMappingRows: readonly WritablePrefixRo
405422 { displayedMappingRows . map ( ( row ) => (
406423 < tr >
407424 < td > { row . prefix ? < code > { '"' + row . prefix + '"' } </ code > : defaultPrefixPill } </ td >
408- < td > { row . bagName . toString ( ) } </ td >
425+ < td > { row . bagName } </ td >
409426 </ tr >
410427 ) ) }
411428 </ table > ;
@@ -416,7 +433,7 @@ function renderPrefixTableFieldSidebar(ctx: ReadonlyFieldContext<any>): JSX.Node
416433 return < dl class = "prefix-bag-sidebar" >
417434 { ctx . value . map ( ( entry ) => < >
418435 < dt class = "prefix-bag-sidebar-term" > { entry . prefix ? < span class = "prefix-bag-sidebar-prefix" > "{ entry . prefix } "</ span > : defaultPrefixPill } </ dt >
419- < dd class = "prefix-bag-sidebar-value" > { entry . bagName . toString ( ) } </ dd >
436+ < dd class = "prefix-bag-sidebar-value" > { entry . bagName } </ dd >
420437 </ > ) }
421438 </ dl > ;
422439}
@@ -429,8 +446,8 @@ function renderPrefixTableFieldEditor(ctx: FieldEditorContext<any>) {
429446 const pendingRowCount = fieldState . pendingRows [ field . key ] ?? 0 ;
430447 const lookupOptions = getLookupOptions ( field . key , itemsByTab ) ;
431448 const displayedMappingRows = mappingRows . length
432- ? [ ...mappingRows , ...Array . from ( { length : pendingRowCount } , ( ) => ( { prefix : "" , bagName : new KeyString ( "" ) } ) ) ]
433- : [ { prefix : "" , bagName : new KeyString ( "" ) } , ...Array . from ( { length : pendingRowCount } , ( ) => ( { prefix : "" , bagName : new KeyString ( "" ) } ) ) ] ;
449+ ? [ ...mappingRows , ...Array . from ( { length : pendingRowCount } , ( ) => ( { prefix : "" , bagName : "" } ) ) ]
450+ : [ { prefix : "" , bagName : "" } , ...Array . from ( { length : pendingRowCount } , ( ) => ( { prefix : "" , bagName : "" } ) ) ] ;
434451 const templateRecord = is < WikiAdminRecord > ( fieldState . draft , fieldState . tabId === "wikis" )
435452 ? findTemplateRecordForWikiRecord ( fieldState . draft , itemsByTab ) : undefined ;
436453 const inheritedRoutingRows = fieldState . tabId === "wikis" && templateRecord ? templateRecord . writablePrefixBags : [ ] ;
@@ -468,7 +485,7 @@ function renderPrefixTableFieldEditor(ctx: FieldEditorContext<any>) {
468485 </ div >
469486 { renderSearchableInput ( {
470487 id : `${ inputId } -${ index } -target` ,
471- currentValue : row . bagName . toString ( ) ,
488+ currentValue : row . bagName ,
472489 placeholder : "Target bag" ,
473490 options : lookupOptions ,
474491 disabled : ctx . disabled ,
@@ -525,7 +542,7 @@ function renderAutocompleteFieldEditor(ctx: FieldEditorContext<any>) {
525542 } }
526543 />
527544 < datalist id = { datalistId } >
528- { Array . from ( optionMap . keys ( ) , ( option ) => < option value = { option . toString ( ) } /> ) }
545+ { Array . from ( optionMap . keys ( ) , ( option ) => < option value = { option } /> ) }
529546 </ datalist >
530547 </ >
531548 ) ;
@@ -539,7 +556,7 @@ function computeResolverPreview(draft: WikiAdminRecord, title: string) {
539556 : undefined ;
540557 return {
541558 title : normalizedTitle ,
542- writeTo : writeTarget ?. bagName . toString ( ) ?? "No writable target" ,
559+ writeTo : writeTarget ?. bagName ?? "No writable target" ,
543560 matchedPrefix : writeTarget ? ( writeTarget . prefix || "default" ) : "none" ,
544561 } ;
545562}
@@ -641,7 +658,7 @@ export const fieldTypeRenderSidebars = {
641658 "enter-password" : ( ) => null ,
642659 "confirm-password" : ( ) => null ,
643660 "search-multiselect" : renderSearchMultiselectFieldSidebar ,
644- "permission-table" : ( ) => null ,
661+ "permission-table" : renderPermissionTableFieldViewer ,
645662 "prefix-table" : renderPrefixTableFieldSidebar ,
646663 "select" : ( ) => null ,
647664 "search" : renderAutocompleteFieldSidebar ,
0 commit comments