Page Menu
Home
Sealhub
Search
Configure Global Search
Log In
Files
F996528
array.ts
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
5 KB
Referenced Files
None
Subscribers
None
array.ts
View Options
/* eslint-disable @typescript-eslint/no-explicit-any */
import
Router
from
"@koa/router"
;
import
{
hasShape
,
predicates
}
from
"@sealcode/ts-predicates"
;
import
{
Context
}
from
"koa"
;
import
qs
from
"qs"
;
import
{
Field
,
FieldsetOutput
}
from
"sealious"
;
import
{
tempstream
}
from
"tempstream"
;
import
{
FormField
}
from
"../fields/field.js"
;
import
{
SimpleFormField
}
from
"../fields/simple-form-field.js"
;
import
{
StructuredArrayField
}
from
"../fields/structured-array.js"
;
import
{
FormDataValue
}
from
"../form-types.js"
;
import
{
Derived
}
from
"./derived.js"
;
import
{
FormControl
,
FormControlContext
}
from
"./form-control.js"
;
import
{
FormFieldControl
}
from
"./form-field-control.js"
;
export
type
UnboundControlStorage
<
F
extends
{
new
(...
args
:
any
)
:
FormFieldControl
}
=
{
new
(...
args
:
any
)
:
FormFieldControl
;
}
>
=
[
F
,
string
,
ConstructorParameters
<
F
>
];
export
function
UnboundControl
<
F
extends
{
new
(...
args
:
any
)
:
FormFieldControl
}
>
(
controlClass
:
F
,
arbitrary_field_name
:
string
,
params
:
ConstructorParameters
<
F
>
[
"1"
]
)
:
UnboundControlStorage
{
return
[
controlClass
,
arbitrary_field_name
,
params
];
}
export
class
StructuredArray
<
Subfields
extends
Record
<
string
,
Field
>
>
extends
FormFieldControl
{
constructor
(
public
field
:
StructuredArrayField
<
Subfields
>
,
public
item_controls
:
Array
<
FormControl
|
UnboundControlStorage
>
)
{
super
([
field
]);
}
getFrameID
()
{
return
`array-frame-
${
this
.
field
.
name
}
`
;
}
getInnerFormID
()
{
return
this
.
getFrameID
()
+
"-form"
;
}
getActionURL
(
form_id
?:
string
,
action
?:
Record
<
string
,
unknown
>
)
{
return
`
${
this
.
getFrameID
()
}${
form_id
||
action
?
"?"
:
""
}${
qs
.
stringify
({
form_id
,
action
}
)}`
;
}
async
getDefaultItemBody
()
{
return
{};
}
makeSubfield
(
_field_name
:
string
)
:
FormField
{
return
new
SimpleFormField
(
false
);
}
async
renderItemControl
(
ctx
:
Context
,
form_id
:
string
,
control
:
FormControl
|
UnboundControlStorage
,
item
:
FieldsetOutput
<
Subfields
>
,
index
:
number
)
{
const
fctx
=
{
ctx
,
data
:
{},
messages
:
[],
field_name_prefix
:
""
,
form_id
,
validate
:
false
,
};
if
(
Array
.
isArray
(
control
))
{
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const
[
constructor
,
field_name
,
params
]
=
control
;
const
field
=
this
.
makeSubfield
(
field_name
);
if
(
!
field
)
{
console
.
warn
(
`makeSubfield returned null for field
${
field_name
}
`
);
return
""
;
}
await
field
.
init
(
`
${
this
.
field
.
name
}
[data][
${
index
}
][
${
field_name
}
]`
);
const
hidden_shadow
=
new
Derived
(
[
field
],
async
(
values
,
{
inner_form_id
,
field_name
}
)
=>
/* HTML */
`<input
name="
${
field_name
}
"
type="hidden"
value="
${
values
[
field_name
]
||
""
}
"
form="
${
inner_form_id
}
"
/>`
,
async
()
=>
({
inner_form_id
:
this
.
getInnerFormID
(),
field_name
:
field
.
name
,
})
);
return
tempstream
`
${
new
constructor
(
field
,
params
).
render
({
...
fctx
,
data
:
{
[
field
.
name
]
:
item
[
field_name
]
as
FormDataValue
}
,
})}
${
hidden_shadow
.
render
({
...
fctx
,
data
:
{
[
field
.
name
]
:
item
[
field_name
]
as
FormDataValue
}
,
form_id: this.getInnerFormID(),
})}`
;
}
else
{
return
control
.
render
(
fctx
);
}
}
async
renderItem
(
ctx
:
Context
,
form_id
:
string
,
item
:
FieldsetOutput
<
Subfields
>
,
index
:
number
)
{
return
tempstream
/* HTML */
`<div>
${
this
.
item_controls
.
map
((
control
)
=>
this
.
renderItemControl
(
ctx
,
form_id
,
control
,
item
,
index
)
)
}
<input
type="submit"
value="remove"
form="
${
this
.
getInnerFormID
()
}
"
formaction="
${
this
.
getActionURL
(
form_id
,
{
remove
:
index
,
}
)}"
/>
</div>`
;
}
async
getItems
(
ctx
:
Context
,
raw_values
:
Record
<
string
,
FormDataValue
>
)
{
return
(
await
this
.
field
.
getValue
(
ctx
,
raw_values
)).
parsed
as
Promise
<
FieldsetOutput
<
Subfields
>
[]
>
;
}
async
_render
(
ctx
:
Context
,
form_id
:
string
,
raw_values
:
Record
<
string
,
FormDataValue
>
)
{
const
items
=
await
this
.
getItems
(
ctx
,
raw_values
);
return
tempstream
/* HTML */
`<turbo-frame id="
${
this
.
getFrameID
()
}
">
Reverse Single Reference
${
items
.
map
((
item
,
index
)
=>
this
.
renderItem
(
ctx
,
form_id
,
item
,
index
)
)
}
<form id="
${
this
.
getInnerFormID
()
}
" method="POST"></form>
<input
type="submit"
value="add"
form="
${
this
.
getInnerFormID
()
}
"
formaction="
${
this
.
getActionURL
(
form_id
,
{
insert
:
{
index
:
items
.
length
,
value
:
{
}
},
})}"
/>
</turbo-frame>`
;
}
render
(
fctx
:
FormControlContext
)
{
return
this
.
_render
(
fctx
.
ctx
,
fctx
.
form_id
,
fctx
.
data
);
}
async
getTargetItemID
(
ctx
:
Context
)
:
Promise
<
string
>
{
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
return
ctx
.
params
.
id
as
string
;
}
mount
(
router
:
Router
)
{
console
.
log
(
"mounting!"
,
this
.
getActionURL
());
router
.
post
(
this
.
getActionURL
(),
async
(
ctx
)
=>
{
const
form_id
=
ctx
.
query
.
form_id
;
if
(
typeof
form_id
!=
"string"
)
{
throw
new
Error
(
"Missing form_id query param"
);
}
const
item
=
await
this
.
field
.
sealious_field
.
collection
.
getByID
(
ctx
.
$context
,
await
this
.
getTargetItemID
(
ctx
)
);
if
(
!
hasShape
({
action
:
predicates
.
object
},
ctx
.
$body
))
{
throw
new
Error
(
"Missing action param"
);
}
const
field_data
=
(
ctx
.
$body
as
Record
<
string
,
unknown
>
)[
this
.
field
.
name
]
||
{
data
:
[]
};
console
.
log
({
action
:
field_data
});
if
(
!
hasShape
(
{
data
:
predicates
.
array
(
this
.
field
.
sealious_field
.
value_predicate
),
},
field_data
)
)
{
throw
new
Error
(
"missing data atribute in action description"
);
}
item
.
set
(
this
.
field
.
name
,
{
...
ctx
.
$body
.
action
,
data
:
field_data
.
data
||
[],
});
console
.
log
(
"ACTION"
,
{
...
ctx
.
$body
.
action
,
data
:
field_data
.
data
||
[],
});
await
item
.
save
(
ctx
.
$context
);
console
.
log
(
await
item
.
getDecodedBody
(
ctx
.
$context
,
{}));
ctx
.
body
=
this
.
_render
(
ctx
,
form_id
,
await
item
.
getDecodedBody
(
ctx
.
$context
,
{})
);
});
}
}
File Metadata
Details
Attached
Mime Type
text/x-java
Expires
Tue, Dec 24, 14:05 (12 h, 57 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
557302
Default Alt Text
array.ts (5 KB)
Attached To
Mode
rSGEN sealgen
Attached
Detach File
Event Timeline
Log In to Comment