Skip to content

Commit b3dcd1d

Browse files
committed
wip
1 parent 4246898 commit b3dcd1d

File tree

7 files changed

+102
-31
lines changed

7 files changed

+102
-31
lines changed

admin_ui/src/components/CallbackButton.vue renamed to admin_ui/src/components/ActionButton.vue

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
<template>
22
<a
33
href="#"
4-
id="callback"
5-
title="Row callback"
4+
id="action"
5+
title="Row Action"
66
v-on:click.prevent="$emit('triggered')"
77
>
8-
<span v-if="includeTitle">{{ $t("Callback") }}</span>
8+
<span v-if="includeTitle">{{ $t("Action") }}</span>
99
</a>
1010
</template>
1111

@@ -36,7 +36,7 @@ export default {
3636
}
3737
}
3838
39-
a#callback {
39+
a#action {
4040
text-decoration: none;
4141
4242
span {
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
2+
<template>
3+
<a
4+
href="#"
5+
id="actiondropdown"
6+
title="Actions"
7+
>
8+
<!-- <DropDownMenu> -->
9+
<li v-for="action in allActions">
10+
<span>{{ action.action_name }}</span>
11+
</li>
12+
<!-- </DropDownMenu> -->
13+
</a>
14+
</template>
15+
16+
<script lang="ts">
17+
import Vue from "vue"
18+
19+
// import DropDownMenu from "./DropDownMenu.vue"
20+
21+
export default Vue.extend({
22+
// components: {
23+
// DropDownMenu
24+
// },
25+
computed: {
26+
allActions() {
27+
return this.$store.state.actions;
28+
}
29+
},
30+
})
31+
</script>
32+
33+
<style scoped lang="less">
34+
#actiondropdown {
35+
background-color: pink;
36+
}
37+
</style>

admin_ui/src/interfaces.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@ export interface DeleteRow {
88
rowID: number
99
}
1010

11-
export interface ExecuteCallback {
11+
export interface ExecuteAction {
1212
tableName: string
1313
rowID: number
14+
actionId: number
1415
}
1516

1617
export interface UpdateRow {
@@ -149,3 +150,8 @@ export interface FormConfig {
149150
slug: string
150151
description: string
151152
}
153+
154+
export interface Action {
155+
actionID: number
156+
actionName: string
157+
}

admin_ui/src/store.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ export default new Vuex.Store({
3333
tableNames: [],
3434
formConfigs: [] as i.FormConfig[],
3535
user: undefined,
36-
loadingStatus: false
36+
loadingStatus: false,
37+
actions: [] as i.Action[]
3738
},
3839
mutations: {
3940
updateTableNames(state, value) {
@@ -66,6 +67,9 @@ export default new Vuex.Store({
6667
updateSortBy(state, config: i.SortByConfig) {
6768
state.sortBy = config
6869
},
70+
updateActions(state, actions) {
71+
state.actions = actions
72+
},
6973
reset(state) {
7074
state.sortBy = null
7175
state.filterParams = {}
@@ -229,9 +233,16 @@ export default new Vuex.Store({
229233
)
230234
return response
231235
},
232-
async executeCallback(context, config: i.ExecuteCallback) {
236+
async fetchActions(context, tableName: string) {
237+
const response = await axios.get(
238+
`${BASE_URL}tables/${tableName}/actions`
239+
)
240+
context.commit("updateActions", response.data)
241+
return response
242+
},
243+
async executeAction(context, config: i.ExecuteAction) {
233244
const response = await axios.post(
234-
`${BASE_URL}tables/${config.tableName}/callback/execute`,
245+
`${BASE_URL}tables/${config.tableName}/actions/${config.actionId}/execute`,
235246
{
236247
table_name: config.tableName,
237248
row_id: config.rowID

admin_ui/src/views/RowListing.vue

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@
2727
v-if="selectedRows.length > 0"
2828
v-on:triggered="deleteRows"
2929
/>
30-
30+
31+
<ActionDropDownMenu class="button" v-on:triggered="executeAction"/>
32+
3133
<router-link
3234
:to="{
3335
name: 'addRow',
@@ -40,6 +42,7 @@
4042
<span>{{ $t("Add Row") }}</span>
4143
</router-link>
4244

45+
4346
<a
4447
class="button"
4548
href="#"
@@ -300,14 +303,10 @@
300303
/>
301304
</li>
302305
<li>
303-
<CallbackButton
306+
<ActionButton
304307
:includeTitle="true"
305308
class=""
306-
v-on:triggered="
307-
executeCallback(
308-
row[pkName]
309-
)
310-
"
309+
v-on:triggered="executeAction"
311310
/>
312311
</li>
313312
</DropDownMenu>
@@ -381,7 +380,8 @@ import BulkUpdateModal from "../components/BulkUpdateModal.vue"
381380
import BulkDeleteButton from "../components/BulkDeleteButton.vue"
382381
import CSVButton from "../components/CSVButton.vue"
383382
import DeleteButton from "../components/DeleteButton.vue"
384-
import CallbackButton from "../components/CallbackButton.vue"
383+
import ActionButton from "../components/ActionButton.vue"
384+
import ActionDropDownMenu from "../components/ActionDropDownMenu.vue"
385385
import DropDownMenu from "../components/DropDownMenu.vue"
386386
import ChangePageSize from "../components/ChangePageSize.vue"
387387
import MediaViewer from "../components/MediaViewer.vue"
@@ -420,7 +420,8 @@ export default Vue.extend({
420420
ChangePageSize,
421421
CSVButton,
422422
DeleteButton,
423-
CallbackButton,
423+
ActionButton,
424+
ActionDropDownMenu,
424425
DropDownMenu,
425426
MediaViewer,
426427
Pagination,
@@ -448,6 +449,9 @@ export default Vue.extend({
448449
schema() {
449450
return this.$store.state.schema
450451
},
452+
actions() {
453+
return this.$store.state.actions
454+
},
451455
rowCount() {
452456
return this.$store.state.rowCount
453457
},
@@ -579,20 +583,25 @@ export default Vue.extend({
579583
this.showSuccess("Successfully deleted row")
580584
}
581585
},
582-
async executeCallback(rowID) {
583-
if (confirm(`Are you sure you want to run callback for this row?`)) {
584-
console.log("Requesting to run callback!")
586+
async executeAction() {
587+
console.log("RUNNING");
588+
589+
if (confirm(`Are you sure you want to run action for this row?`)) {
590+
console.log("Requesting to run action!")
585591
try {
586-
let response = await this.$store.dispatch("executeCallback", {
587-
tableName: this.tableName,
588-
rowID
589-
})
590-
this.showSuccess(`Successfully ran callback and got response: ${response.data}`, 10000)
592+
for (let i = 0; i < this.selectedRows.length; i++) {
593+
let response = await this.$store.dispatch("executeAction", {
594+
tableName: this.tableName,
595+
rowID: this.selectedRows[i],
596+
actionId: 1
597+
})
598+
this.showSuccess(`Successfully ran action and got response: ${response.data}`, 10000)
599+
}
591600
} catch (error) {
592601
if (error.response.status == 404) {
593602
console.log(error.response.status)
594603
this.$store.commit("updateApiResponseMessage", {
595-
contents: "This table is not configured for callback action",
604+
contents: "This table is not configured for any actions",
596605
type: "error"
597606
})
598607
} else {
@@ -623,6 +632,9 @@ export default Vue.extend({
623632
},
624633
async fetchSchema() {
625634
await this.$store.dispatch("fetchSchema", this.tableName)
635+
},
636+
async fetchActions() {
637+
await this.$store.dispatch("fetchActions", this.tableName)
626638
}
627639
},
628640
watch: {
@@ -650,7 +662,7 @@ export default Vue.extend({
650662
this.$router.currentRoute.query
651663
)
652664
653-
await Promise.all([this.fetchRows(), this.fetchSchema()])
665+
await Promise.all([this.fetchRows(), this.fetchSchema(), this.fetchActions()])
654666
}
655667
})
656668
</script>

piccolo_admin/endpoints.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ async def manager_only(
152152
validators=Validators(post_single=manager_only)
153153
)
154154
)
155+
:param custom_actions: Optional list of custom actions handler function
155156
156157
"""
157158

@@ -164,7 +165,7 @@ async def manager_only(
164165
hooks: t.Optional[t.List[Hook]] = None
165166
media_storage: t.Optional[t.Sequence[MediaStorage]] = None
166167
validators: t.Optional[Validators] = None
167-
custom_callback: t.Optional[t.Callable] = None
168+
custom_actions: t.Optional[t.List[t.Callable]] = None
168169

169170
def __post_init__(self):
170171
if self.visible_columns and self.exclude_visible_columns:
@@ -464,7 +465,7 @@ def __init__(
464465
"tags": [f"{table_class._meta.tablename.capitalize()}"]
465466
},
466467
),
467-
callback=table_config.custom_callback,
468+
actions=table_config.custom_actions,
468469
)
469470

470471
private_app.add_api_route(

piccolo_admin/example.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -259,12 +259,16 @@ async def booking_endpoint(request, data):
259259

260260
return "Booking complete"
261261

262-
async def my_callback_fn(**kwargs) -> JSONResponse:
262+
async def my_custom_action(**kwargs) -> JSONResponse:
263+
print(kwargs)
263264
request_data = kwargs['request_params']
264265
table_name = request_data['table_name']
265266
row_id = request_data['row_id']
266267
return JSONResponse(f"My API received the row_id: {row_id} from table: {table_name}")
267268

269+
async def custom_action_2(**kwargs) -> JSONResponse:
270+
return JSONResponse("This is the second action")
271+
268272
TABLE_CLASSES: t.Tuple[t.Type[Table], ...] = (
269273
Director,
270274
Movie,
@@ -307,7 +311,7 @@ async def my_callback_fn(**kwargs) -> JSONResponse:
307311
media_path=os.path.join(MEDIA_ROOT, "movie_screenshots"),
308312
),
309313
),
310-
custom_callback=my_callback_fn
314+
custom_actions=[my_custom_action, custom_action_2]
311315
)
312316

313317
director_config = TableConfig(

0 commit comments

Comments
 (0)