Create a custom moderation view
This example shows you how you can implement a moderations view with a custom Approve/Reject workflow.
In our example, we want to Approve or Reject products to moderate content on our website:
  • We want to preview products images
  • We want to bulk Approve/Reject products

How it works

Smart view definition

Learn more about smart views. File template.hbs
This file contains the HTML and CSS needed to build the view.
Template
1
<div class="view-wrapper">
2
<div class="table-wrapper">
3
<table class="c-table-frame">
4
<thead class="l-table-frame-headers">
5
<tr class="l-table-frame-headers-line">
6
<th scope="col" role="button" class="c-table-frame__header c-table-frame__header--select-all">
7
<div class="c-table-frame__checkbox-select-all">
8
<div class="l-table-frame-checkbox-select-all">
9
<BetaCheckbox
10
@value={{this.allSelected}}
11
@small={{true}}
12
@disabled={{false}}
13
@onChange={{fn this.selectAll}}
14
/>
15
</div>
16
</div>
17
</th>
18
<th scope="col" class="c-table-frame__header c-table-column-header">
19
<span class="c-table-column-header__content">
20
<span class="c-table-column-header__display-name
21
c-table-column-header__display-name--sortable
22
c-table-column-header__display-name--first" role="button">
23
Product details
24
</span>
25
</span>
26
</th>
27
<th scope="col" class="c-table-frame__header c-table-column-header">
28
<span class="c-table-column-header__content">
29
<span class="c-table-column-header__display-name" role="button">
30
Images
31
</span>
32
</span>
33
</th>
34
<th scope="col" class="c-table-frame__header c-table-column-header">
35
<span class="c-table-column-header__content">
36
<span class="c-table-column-header__display-name" role="button">
37
<Button::BetaButton
38
@type="primary"
39
@text="Approve"
40
@size="tiny"
41
@action={{fn this.triggerSmartAction @collection 'Approve' this.selectedRecords}}
42
@disabled={{this.disableButtons}}
43
@class="no-margin"
44
/>
45
<Button::BetaButton
46
@type="danger"
47
@text="Reject"
48
@size="tiny"
49
@disabled={{this.disableButtons}}
50
@action={{fn this.triggerSmartAction @collection 'Reject' this.selectedRecords}}
51
@class="no-margin"
52
/>
53
</span>
54
</span>
55
</th>
56
</tr>
57
</thead>
58
<tbody class="l-table-frame-body">
59
{{#each this.formatedRecords as |record|}}
60
<tr>
61
<td class="align-top first-column" role="">
62
<BetaCheckbox
63
@value={{record._selected}}
64
@small={{true}}
65
@disabled={{false}}
66
@onChange={{fn this.selectRecord}}
67
/>
68
</td>
69
<td class="align-top">
70
<div class="title">
71
<LinkTo
72
@route="project.rendering.data.collection.list.viewEdit.details"
73
@models={{array @collection.id record.id}}
74
>
75
{{record.forest-name}}
76
</LinkTo>
77
</div>
78
<div class="status">
79
<span class="c-badge" style="--badge-color:#0cc251; --badge-background-color:#0cc25133;">
80
<p class="c-badge__label">
81
{{record.forest-state}}
82
</p>
83
</span>
84
</div>
85
</td>
86
<td class="second-column">
87
{{#each record.forest-imagesSF as |image|}}
88
<Widgets::Display::FileViewer::WidgetLayout
89
@value={{image}}
90
@field={{this.pictureField}}
91
/>
92
{{/each}}
93
</td>
94
</tr>
95
{{/each}}
96
</tbody>
97
</table>
98
</div>
99
100
<Table::TableFooter
101
@collection={{@collection}}
102
@records={{@records}}
103
@selectedRecordsCount={{this.selectedRecords.length}}
104
@recordsCount={{@recordsCount}}
105
@currentPage={{@currentPage}}
106
@numberOfPages={{@numberOfPages}}
107
@fetchRecords={{@fetchRecords}}
108
@canEdit={{@canEdit}}
109
@isLoading={{@isLoading}}
110
@displaySearchExtendedButton={{@displaySearchExtendedButton}}
111
@disablePagination={{false}}
112
@hasShowMore={{false}}
113
@class="pagination"
114
/>
115
</div>
Copied!