Skip to content

Commit 313fc83

Browse files
authored
Improve facades apply (#26)
* Add apply method to facades * Update components to apply * Remove redundant children * Minor changes
1 parent 9057e3c commit 313fc83

27 files changed

+206
-125
lines changed

spra-web/src/main/scala/net/wiringbits/spra/ui/web/AdminView.scala

+5-7
Original file line numberDiff line numberDiff line change
@@ -43,18 +43,16 @@ object AdminView {
4343
def buildResources: Seq[ReactElement] = {
4444
tables.map { table =>
4545
Resource(
46-
Resource.Props(
47-
name = table.name,
48-
list = ListGuesser(table),
49-
edit = EditGuesser(table, props.dataExplorerSettings),
50-
create = CreateGuesser(table)
51-
)
46+
name = table.name,
47+
list = ListGuesser(table),
48+
edit = EditGuesser(table, props.dataExplorerSettings),
49+
create = CreateGuesser(table)
5250
).withKey(table.name)
5351
}
5452
}
5553

5654
div()(
57-
Admin(Admin.Props(dataProvider = simpleRestProvider(tablesUrl), children = buildResources)),
55+
Admin(simpleRestProvider(tablesUrl))(buildResources),
5856
error.map(h1(_))
5957
)
6058
}

spra-web/src/main/scala/net/wiringbits/spra/ui/web/components/CreateGuesser.scala

+11-20
Original file line numberDiff line numberDiff line change
@@ -23,38 +23,29 @@ object CreateGuesser {
2323

2424
field.`type` match {
2525
case ColumnType.Date =>
26-
DateTimeInput(DateTimeInput.Props(source = field.name, isRequired = isRequired, validate = required))
26+
DateTimeInput(source = field.name, isRequired = isRequired, validate = required)
2727
case ColumnType.Text =>
28-
TextInput(TextInput.Props(source = field.name, isRequired = isRequired, validate = required))
28+
TextInput(source = field.name, isRequired = isRequired, validate = required)
2929
case ColumnType.Email =>
30-
TextInput(TextInput.Props(source = field.name, isRequired = isRequired, validate = required))
30+
TextInput(source = field.name, isRequired = isRequired, validate = required)
3131
case ColumnType.Image =>
32-
ImageField(ImageField.Props(source = field.name, isRequired = isRequired, validate = required))
32+
ImageField(source = field.name, isRequired = isRequired, validate = required)
3333
case ColumnType.Number =>
34-
NumberInput(NumberInput.Props(source = field.name, isRequired = isRequired, validate = required))
34+
NumberInput(source = field.name, isRequired = isRequired, validate = required)
3535
case ColumnType.Reference(reference, source) =>
3636
ReferenceInput(
37-
ReferenceInput.Props(
38-
source = field.name,
39-
reference = reference,
40-
children = Seq(
41-
SelectInput(SelectInput.Props(optionText = source, isRequired = isRequired, validate = required))
42-
),
43-
isRequired = isRequired,
44-
validate = required
45-
)
46-
)
37+
source = field.name,
38+
reference = reference,
39+
isRequired = isRequired,
40+
validate = required
41+
)(SelectInput(optionText = source, isRequired = isRequired, validate = required))
4742
}
4843
}
4944
.getOrElse(Fragment())
5045
}
5146

5247
Create(
53-
Create.Props(
54-
SimpleForm(
55-
SimpleForm.Props(toolbar = Fragment(), children = inputs :+ SaveButton())
56-
)
57-
)
48+
SimpleForm(Fragment())(inputs.appended(SaveButton()): _*)
5849
)
5950
}
6051
}

spra-web/src/main/scala/net/wiringbits/spra/ui/web/components/EditGuesser.scala

+14-24
Original file line numberDiff line numberDiff line change
@@ -30,19 +30,16 @@ object EditGuesser {
3030
if !field.isVisible then Fragment()
3131
else
3232
field.`type` match {
33-
case ColumnType.Date => DateTimeInput(DateTimeInput.Props(source = field.name, disabled = field.disabled))
34-
case ColumnType.Text => TextInput(TextInput.Props(source = field.name, disabled = field.disabled))
35-
case ColumnType.Email => TextInput(TextInput.Props(source = field.name, disabled = field.disabled))
36-
case ColumnType.Image => ImageField(ImageField.Props(source = field.name))
37-
case ColumnType.Number => NumberInput(NumberInput.Props(source = field.name, disabled = field.disabled))
33+
case ColumnType.Date => DateTimeInput(source = field.name, disabled = field.disabled)
34+
case ColumnType.Text => TextInput(source = field.name, disabled = field.disabled)
35+
case ColumnType.Email => TextInput(source = field.name, disabled = field.disabled)
36+
case ColumnType.Image => ImageField(source = field.name)
37+
case ColumnType.Number => NumberInput(source = field.name, disabled = field.disabled)
3838
case ColumnType.Reference(reference, source) =>
3939
ReferenceInput(
40-
ReferenceInput.Props(
41-
source = field.name,
42-
reference = reference,
43-
children = Seq(SelectInput(SelectInput.Props(optionText = source, disabled = field.disabled)))
44-
)
45-
)
40+
source = field.name,
41+
reference = reference
42+
)(SelectInput(optionText = source, disabled = field.disabled))
4643
}
4744
}
4845

@@ -65,29 +62,22 @@ object EditGuesser {
6562
tableAction
6663
.map { x =>
6764
x.actions.map { action =>
68-
Button(Button.Props(onClick = () => onClick(action, ctx), children = Seq(action.text)))
65+
Button(onClick = () => onClick(action, ctx))(action.text)
6966
}: Seq[ReactElement]
7067
}
7168
.getOrElse(Seq.empty)
7269
}
7370

74-
val actions = TopToolbar(TopToolbar.Props(children = buttons()))
71+
val actions = TopToolbar(buttons())
7572

7673
val deleteButton: ReactElement = if (props.response.canBeDeleted) DeleteButton() else Fragment()
7774
val toolbar: ReactElement = Toolbar(
78-
Toolbar.Props(children =
79-
Seq(
80-
SaveButton(),
81-
deleteButton
82-
)
83-
)
75+
SaveButton(),
76+
deleteButton
8477
)
8578

86-
Edit(
87-
Edit.Props(
88-
actions = actions(),
89-
children = Seq(SimpleForm(SimpleForm.Props(toolbar = toolbar, children = inputs)))
90-
)
79+
Edit(actions)(
80+
SimpleForm(toolbar)(inputs)
9181
)
9282
}
9383
}

spra-web/src/main/scala/net/wiringbits/spra/ui/web/components/ListGuesser.scala

+17-29
Original file line numberDiff line numberDiff line change
@@ -20,57 +20,45 @@ object ListGuesser {
2020
val component: FunctionalComponent[Props] = FunctionalComponent[Props] { props =>
2121
val fields = ResponseGuesser.getTypesFromResponse(props.response)
2222

23-
def defaultField(reference: String, source: String, children: Seq[ReactElement]): ReactElement =
24-
ReferenceField(
25-
ReferenceField.Props(
26-
reference = reference,
27-
source = source,
28-
children = children
29-
)
30-
)
23+
def defaultField(reference: String, source: String)(children: ReactElement*): ReactElement =
24+
ReferenceField(reference = reference, source = source)(children)
3125

3226
val widgetFields: Seq[ReactElement] = fields.map { field =>
3327
if !field.isVisible then Fragment()
3428
else {
3529
val imageStyles = js.Dynamic.literal("width" -> "100px")
3630
val styles = js.Dynamic.literal("& img" -> imageStyles)
3731
field.`type` match {
38-
case Date => DateField(DateField.Props(source = field.name, showTime = true))
39-
case Text => TextField(TextField.Props(source = field.name))
40-
case Email => EmailField(EmailField.Props(source = field.name))
41-
case Image => ImageField(ImageField.Props(source = field.name, sx = styles))
42-
case Number => NumberField(NumberField.Props(source = field.name))
32+
case Date => DateField(source = field.name, showTime = true)
33+
case Text => TextField(source = field.name)
34+
case Email => EmailField(source = field.name)
35+
case Image => ImageField(source = field.name, sx = styles)
36+
case Number => NumberField(source = field.name)
4337
case ColumnType.Reference(reference, source) =>
44-
defaultField(reference, field.name, Seq(TextField(TextField.Props(source = source))))
38+
defaultField(reference, field.name)(TextField(source = source))
4539
}
4640
}
4741
}
4842

4943
val filterList: Seq[ReactElement] = fields.filter(_.filterable).map { field =>
5044
field.`type` match {
51-
case ColumnType.Date => DateInput(DateInput.Props(source = field.name))
52-
case ColumnType.Text | ColumnType.Email => TextInput(TextInput.Props(source = field.name))
45+
case ColumnType.Date => DateInput(source = field.name)
46+
case ColumnType.Text | ColumnType.Email => TextInput(source = field.name)
5347
case ColumnType.Image => Fragment()
54-
case ColumnType.Number => NumberInput(NumberInput.Props(source = field.name))
48+
case ColumnType.Number => NumberInput(source = field.name)
5549
case ColumnType.Reference(reference, source) =>
56-
defaultField(reference, field.name, Seq(TextField(TextField.Props(source = source))))
50+
defaultField(reference, field.name)(TextField(source = source))
5751
}
5852
}
5953

6054
val listToolbar: ReactElement = TopToolbar(
61-
TopToolbar.Props(
62-
children = Seq(
63-
FilterButton(FilterButton.Props(filters = filterList)),
64-
ExportButton(),
65-
CreateButton()
66-
)
67-
)
55+
FilterButton(filters = filterList),
56+
ExportButton(),
57+
CreateButton()
6858
)
6959

70-
ComponentList(ComponentList.Props(actions = listToolbar, filters = filterList))(
71-
Datagrid(
72-
Datagrid.Props(rowClick = "edit", bulkActionButtons = props.response.canBeDeleted, children = widgetFields)
73-
)
60+
ComponentList(listToolbar)(filterList: _*)(
61+
Datagrid(rowClick = "edit", bulkActionButtons = props.response.canBeDeleted)(widgetFields)
7462
)
7563
}
7664
}
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
package net.wiringbits.spra.ui.web.facades.reactadmin
22

33
import net.wiringbits.spra.ui.web.facades.DataProvider
4-
import slinky.core.ExternalComponent
5-
import slinky.core.facade.ReactElement
4+
import slinky.core.{BuildingComponent, ExternalComponent}
65

76
import scala.scalajs.js
87
import scala.scalajs.js.|
98

109
object Admin extends ExternalComponent {
11-
case class Props(dataProvider: DataProvider, children: Seq[ReactElement])
10+
case class Props(dataProvider: DataProvider)
11+
12+
def apply(dataProvider: DataProvider): BuildingComponent[_, _] = {
13+
super.apply(Props(dataProvider))
14+
}
15+
1216
override val component: String | js.Object = ReactAdmin.Admin
1317
}
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
package net.wiringbits.spra.ui.web.facades.reactadmin
22

3-
import slinky.core.ExternalComponent
4-
import slinky.core.facade.ReactElement
3+
import slinky.core.{BuildingComponent, ExternalComponent}
54

65
import scala.scalajs.js
76
import scala.scalajs.js.|
87

98
object Button extends ExternalComponent {
10-
case class Props(onClick: () => Unit, children: Seq[ReactElement])
9+
case class Props(onClick: () => Unit)
10+
11+
def apply(onClick: () => Unit): BuildingComponent[_, _] = {
12+
super.apply(Props(onClick))
13+
}
14+
1115
override val component: String | js.Object = ReactAdmin.Button
1216
}
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
package net.wiringbits.spra.ui.web.facades.reactadmin
22

3-
import slinky.core.ExternalComponent
43
import slinky.core.facade.ReactElement
4+
import slinky.core.{BuildingComponent, ExternalComponent}
55

66
import scala.scalajs.js
77
import scala.scalajs.js.|
88

99
object ComponentList extends ExternalComponent {
1010
case class Props(actions: ReactElement, filters: Seq[ReactElement])
11+
12+
def apply(actions: ReactElement)(filters: ReactElement*): BuildingComponent[_, _] = {
13+
super.apply(Props(actions, filters))
14+
}
15+
1116
override val component: String | js.Object = ReactAdmin.List
1217
}
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
11
package net.wiringbits.spra.ui.web.facades.reactadmin
22

3-
import slinky.core.ExternalComponent
4-
import slinky.core.facade.ReactElement
3+
import slinky.core.ExternalComponentNoProps
54

65
import scala.scalajs.js
76

8-
object Create extends ExternalComponent {
9-
case class Props(children: ReactElement*)
10-
7+
object Create extends ExternalComponentNoProps {
118
override val component: String | js.Object = ReactAdmin.Create
129
}
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
package net.wiringbits.spra.ui.web.facades.reactadmin
22

3-
import slinky.core.ExternalComponent
4-
import slinky.core.facade.ReactElement
3+
import slinky.core.{BuildingComponent, ExternalComponent}
54

65
import scala.scalajs.js
76
import scala.scalajs.js.|
87

98
object Datagrid extends ExternalComponent {
10-
case class Props(rowClick: String, bulkActionButtons: Boolean, children: Seq[ReactElement])
9+
case class Props(rowClick: String, bulkActionButtons: Boolean)
10+
11+
def apply(rowClick: String, bulkActionButtons: Boolean): BuildingComponent[_, _] =
12+
super.apply(Props(rowClick, bulkActionButtons))
13+
1114
override val component: String | js.Object = ReactAdmin.Datagrid
1215
}
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
package net.wiringbits.spra.ui.web.facades.reactadmin
22

3-
import slinky.core.ExternalComponent
3+
import slinky.core.{BuildingComponent, ExternalComponent}
44

55
import scala.scalajs.js
66
import scala.scalajs.js.|
77

88
object DateField extends ExternalComponent {
99
case class Props(source: String, showTime: Boolean)
10+
11+
def apply(source: String, showTime: Boolean = false): BuildingComponent[_, _] = {
12+
super.apply(Props(source, showTime))
13+
}
14+
1015
override val component: String | js.Object = ReactAdmin.DateField
1116
}
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,20 @@
11
package net.wiringbits.spra.ui.web.facades.reactadmin
22

3-
import slinky.core.ExternalComponent
3+
import slinky.core.{BuildingComponent, ExternalComponent}
44

55
import scala.scalajs.js
66
import scala.scalajs.js.|
77

88
object DateInput extends ExternalComponent {
99
case class Props(source: String, isRequired: Boolean = false, validate: js.UndefOr[js.Any] = js.undefined)
10+
11+
def apply(
12+
source: String,
13+
isRequired: Boolean = false,
14+
validate: js.UndefOr[js.Any] = js.undefined
15+
): BuildingComponent[_, _] = {
16+
super.apply(Props(source, isRequired, validate))
17+
}
18+
1019
override val component: String | js.Object = ReactAdmin.DateInput
1120
}

spra-web/src/main/scala/net/wiringbits/spra/ui/web/facades/reactadmin/DateTimeInput.scala

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package net.wiringbits.spra.ui.web.facades.reactadmin
22

3-
import slinky.core.ExternalComponent
3+
import slinky.core.{BuildingComponent, ExternalComponent}
44

55
import scala.scalajs.js
66
import scala.scalajs.js.|
@@ -12,5 +12,13 @@ object DateTimeInput extends ExternalComponent {
1212
isRequired: Boolean = false,
1313
validate: js.UndefOr[js.Any] = js.undefined
1414
)
15+
16+
def apply(
17+
source: String,
18+
disabled: Boolean = false,
19+
isRequired: Boolean = false,
20+
validate: js.UndefOr[js.Any] = js.undefined
21+
): BuildingComponent[_, _] = super.apply(Props(source, disabled, isRequired, validate))
22+
1523
override val component: String | js.Object = ReactAdmin.DateTimeInput
1624
}
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
package net.wiringbits.spra.ui.web.facades.reactadmin
22

3-
import slinky.core.ExternalComponent
43
import slinky.core.facade.ReactElement
4+
import slinky.core.{BuildingComponent, ExternalComponent}
55

66
import scala.scalajs.js
77
import scala.scalajs.js.|
88

99
object Edit extends ExternalComponent {
10-
case class Props(actions: ReactElement, children: Seq[ReactElement])
10+
case class Props(actions: ReactElement)
11+
12+
def apply(actions: ReactElement): BuildingComponent[_, _] = {
13+
super.apply(Props(actions))
14+
}
15+
1116
override val component: String | js.Object = ReactAdmin.Edit
1217
}

0 commit comments

Comments
 (0)