@live-change/balance-frontend 0.8.62 → 0.8.63
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/front/src/Balance.vue +168 -0
- package/front/src/Index.vue +62 -5
- package/front/src/components/OperationsList.vue +15 -0
- package/front/src/pages/index.vue +13 -0
- package/front/src/router.js +16 -11
- package/package.json +38 -38
- package/server/app.config.js +3 -0
- package/server/balanceTest/balanceTest.js +172 -0
- package/server/balanceTest/definition.js +12 -0
- package/server/balanceTest/index.js +8 -0
- package/server/services.list.js +6 -0
- package/front/src/components/Clock.vue +0 -22
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="w-full">
|
|
3
|
+
<div class="surface-card shadow-1 border-round p-3 mb-1">
|
|
4
|
+
<div class="text-xl">Balance: {{ balance.owner }}</div>
|
|
5
|
+
<div>Amount: {{ balance.amount }}</div>
|
|
6
|
+
<div>Available: {{ balance.available }}</div>
|
|
7
|
+
</div>
|
|
8
|
+
<div class="surface-card shadow-1 border-round p-3 text-xl mb-1 mt-2 text-xl">
|
|
9
|
+
Operations:
|
|
10
|
+
</div>
|
|
11
|
+
<div v-if="startedOperations.length === 0" class="surface-card shadow-1 border-round p-3 mb-1">
|
|
12
|
+
No operations started
|
|
13
|
+
</div>
|
|
14
|
+
<div v-for="operation of startedOperations"
|
|
15
|
+
class="surface-card shadow-1 border-round mb-1 flex flex-row align-items-center">
|
|
16
|
+
<div class="flex-1 flex-grow pl-3">
|
|
17
|
+
{{ operation.cause }}
|
|
18
|
+
</div>
|
|
19
|
+
<div class="w-15rem text-right pl-3 font-semibold mr-3">
|
|
20
|
+
{{ operation.createdAt }}
|
|
21
|
+
</div>
|
|
22
|
+
<div class="w-10rem text-right pl-3 font-semibold mr-3"
|
|
23
|
+
:class="operation.change > 0 ? 'text-green-500' : 'text-red-500'">
|
|
24
|
+
{{ operation.change > 0 ? '+' : '-' }} {{ Math.abs(operation.change) }}
|
|
25
|
+
</div>
|
|
26
|
+
<Button label="Finish" icon="pi pi-check" severity="success"
|
|
27
|
+
@click="actions.balanceTest.finishOperation({ balance: balance.id, operation: operation.id })" />
|
|
28
|
+
<Button label="Cancel" icon="pi pi-cross" severity="warning"
|
|
29
|
+
@click="actions.balanceTest.cancelOperation({ balance: balance.id, operation: operation.id })" />
|
|
30
|
+
|
|
31
|
+
</div>
|
|
32
|
+
|
|
33
|
+
<div class="flex flex-row">
|
|
34
|
+
<div class="surface-card shadow-1 border-round p-3 text-xl mt-3 flex-1">
|
|
35
|
+
<div class="text-xl mb-2">Start operation</div>
|
|
36
|
+
<command-form service="balanceTest" action="startOperation"
|
|
37
|
+
:parameters="{ balance: balance.id }"
|
|
38
|
+
v-slot="{ data }" reset-on-done>
|
|
39
|
+
<div class="col-12 md:col-6 py-1">
|
|
40
|
+
<div class="p-field mb-3">
|
|
41
|
+
<label for="email" class="block text-900 font-medium mb-2">
|
|
42
|
+
Name
|
|
43
|
+
</label>
|
|
44
|
+
<InputText id="name" type="text" class="w-full"
|
|
45
|
+
aria-describedby="email-help" :class="{ 'p-invalid': data.nameError }"
|
|
46
|
+
v-model="data.name" />
|
|
47
|
+
<small id="email-help" class="p-error">{{ data.nameError }}</small>
|
|
48
|
+
</div>
|
|
49
|
+
</div>
|
|
50
|
+
<div class="col-12 md:col-6 py-1">
|
|
51
|
+
<div class="p-field mb-3">
|
|
52
|
+
<label for="email" class="block text-900 font-medium mb-2">
|
|
53
|
+
Change
|
|
54
|
+
</label>
|
|
55
|
+
<InputNumber id="name" type="text" class="w-full" :min="-1000000" :max="1000000" showButtons :step="1000"
|
|
56
|
+
aria-describedby="email-help" :class="{ 'p-invalid': data.changeError }"
|
|
57
|
+
v-model="data.change" />
|
|
58
|
+
<small id="email-help" class="p-error">{{ data.changeError }}</small>
|
|
59
|
+
</div>
|
|
60
|
+
</div>
|
|
61
|
+
<Button label="Start operation" icon="pi pi-plus" type="submit" />
|
|
62
|
+
</command-form>
|
|
63
|
+
</div>
|
|
64
|
+
<div class="surface-card shadow-1 border-round p-3 text-xl mt-3 flex-1 ml-2">
|
|
65
|
+
<div class="text-xl mb-2">Do instant operation</div>
|
|
66
|
+
<command-form service="balanceTest" action="doOperation"
|
|
67
|
+
:parameters="{ balance: balance.id }"
|
|
68
|
+
v-slot="{ data }" reset-on-done>
|
|
69
|
+
<div class="col-12 md:col-6 py-1">
|
|
70
|
+
<div class="p-field mb-3">
|
|
71
|
+
<label for="email" class="block text-900 font-medium mb-2">
|
|
72
|
+
Name
|
|
73
|
+
</label>
|
|
74
|
+
<InputText id="name" type="text" class="w-full"
|
|
75
|
+
aria-describedby="email-help" :class="{ 'p-invalid': data.nameError }"
|
|
76
|
+
v-model="data.name" />
|
|
77
|
+
<small id="email-help" class="p-error">{{ data.nameError }}</small>
|
|
78
|
+
</div>
|
|
79
|
+
</div>
|
|
80
|
+
<div class="col-12 md:col-6 py-1">
|
|
81
|
+
<div class="p-field mb-3">
|
|
82
|
+
<label for="email" class="block text-900 font-medium mb-2">
|
|
83
|
+
Change
|
|
84
|
+
</label>
|
|
85
|
+
<InputNumber id="name" type="text" class="w-full" :min="-1000000" :max="1000000" showButtons :step="1000"
|
|
86
|
+
aria-describedby="email-help" :class="{ 'p-invalid': data.changeError }"
|
|
87
|
+
v-model="data.change" />
|
|
88
|
+
<small id="email-help" class="p-error">{{ data.changeError }}</small>
|
|
89
|
+
</div>
|
|
90
|
+
</div>
|
|
91
|
+
<Button label="Do operation" icon="pi pi-plus" type="submit" />
|
|
92
|
+
</command-form>
|
|
93
|
+
</div>
|
|
94
|
+
</div>
|
|
95
|
+
|
|
96
|
+
<div class="surface-card shadow-1 border-round p-3 text-xl mb-1 mt-2 text-xl">
|
|
97
|
+
Finished operations:
|
|
98
|
+
</div>
|
|
99
|
+
<div v-if="finishedOperations.length === 0" class="surface-card shadow-1 border-round p-3 mb-1">
|
|
100
|
+
No operations finished
|
|
101
|
+
</div>
|
|
102
|
+
<div v-for="operation of finishedOperations"
|
|
103
|
+
class="surface-card shadow-1 border-round mb-1 flex flex-row align-items-center">
|
|
104
|
+
<div class="flex-1 flex-grow pl-3 py-1">
|
|
105
|
+
{{ operation.cause }}
|
|
106
|
+
</div>
|
|
107
|
+
<div class="w-15rem text-right pl-3 font-semibold mr-3">
|
|
108
|
+
{{ operation.updatedAt ?? operation.createdAt }}
|
|
109
|
+
</div>
|
|
110
|
+
<div class="w-10rem text-right pl-3 font-semibold mr-3"
|
|
111
|
+
:class="operation.change > 0 ? 'text-green-500' : 'text-red-500'">
|
|
112
|
+
{{ operation.change > 0 ? '+' : '-' }} {{ Math.abs(operation.change) }}
|
|
113
|
+
</div>
|
|
114
|
+
<div class="w-10rem text-right pl-3 font-semibold mr-3">
|
|
115
|
+
{{ operation.amountAfter }}
|
|
116
|
+
</div>
|
|
117
|
+
</div>
|
|
118
|
+
|
|
119
|
+
</div>
|
|
120
|
+
</template>
|
|
121
|
+
|
|
122
|
+
<script setup>
|
|
123
|
+
|
|
124
|
+
import InputText from "primevue/inputtext"
|
|
125
|
+
|
|
126
|
+
import {
|
|
127
|
+
defineProps, defineEmits, defineModel, toRefs, computed, watch, ref, watchEffect, onUnmounted,
|
|
128
|
+
getCurrentInstance, unref,
|
|
129
|
+
} from 'vue'
|
|
130
|
+
|
|
131
|
+
const props = defineProps({
|
|
132
|
+
name: {
|
|
133
|
+
type: String,
|
|
134
|
+
required: true
|
|
135
|
+
}
|
|
136
|
+
})
|
|
137
|
+
const { name } = toRefs(props)
|
|
138
|
+
|
|
139
|
+
import { usePath, live, useClient, useActions, reverseRange, useTimeSynchronization } from '@live-change/vue3-ssr'
|
|
140
|
+
const path = usePath()
|
|
141
|
+
const actions = useActions()
|
|
142
|
+
|
|
143
|
+
const balancePath = computed(() => path.balance.ownerOwnedBalance({
|
|
144
|
+
ownerType: 'balanceTest_balance',
|
|
145
|
+
owner: name.value
|
|
146
|
+
}))
|
|
147
|
+
const startedOperationsPath = computed(() => path.balance.operationsByBalance({
|
|
148
|
+
balance: `"balanceTest_balance":${JSON.stringify(name.value)}`,
|
|
149
|
+
state: 'started',
|
|
150
|
+
reverse: true,
|
|
151
|
+
}))
|
|
152
|
+
const finishedOperationsPath = computed(() => path.balance.operationsByBalance({
|
|
153
|
+
balance: `"balanceTest_balance":${JSON.stringify(name.value)}`,
|
|
154
|
+
state: 'finished',
|
|
155
|
+
reverse: true,
|
|
156
|
+
}))
|
|
157
|
+
|
|
158
|
+
const [balance, startedOperations, finishedOperations] = await Promise.all([
|
|
159
|
+
live(balancePath),
|
|
160
|
+
live(startedOperationsPath),
|
|
161
|
+
live(finishedOperationsPath)
|
|
162
|
+
])
|
|
163
|
+
|
|
164
|
+
</script>
|
|
165
|
+
|
|
166
|
+
<style scoped>
|
|
167
|
+
|
|
168
|
+
</style>
|
package/front/src/Index.vue
CHANGED
|
@@ -1,13 +1,70 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div>
|
|
3
|
-
<
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
<div class="w-full">
|
|
3
|
+
<div class="surface-card shadow-1 border-round p-3 text-xl mb-1">
|
|
4
|
+
All balances:
|
|
5
|
+
</div>
|
|
6
|
+
<div v-for="balance in allBalances" class="surface-card shadow-1 border-round flex flex-row align-items-center mt-1">
|
|
7
|
+
<div class="flex-1 flex-grow pl-3">
|
|
8
|
+
{{ balance.owner }}
|
|
9
|
+
</div>
|
|
10
|
+
<div class="w-10rem">
|
|
11
|
+
Amount: {{ balance.amount }}
|
|
12
|
+
</div>
|
|
13
|
+
<div class="w-10rem">
|
|
14
|
+
Available: {{ balance.available }}
|
|
15
|
+
</div>
|
|
16
|
+
<div>
|
|
17
|
+
<router-link :to="{ name: 'balance', params: { name: balance.owner }}" class="no-underline">
|
|
18
|
+
<Button label="Open" icon="pi pi-star" />
|
|
19
|
+
</router-link>
|
|
20
|
+
<Button @click="() => deleteBalance(balance)" label="Delete" icon="pi pi-trash" severity="danger" />
|
|
21
|
+
</div>
|
|
22
|
+
</div>
|
|
23
|
+
<div v-if="allBalances.length === 0" class="surface-card shadow-1 border-round p-3 flex flex-row">
|
|
24
|
+
No balances found
|
|
25
|
+
</div>
|
|
26
|
+
<div class="surface-card shadow-1 border-round p-3 mt-3">
|
|
27
|
+
<div class="text-xl mb-2">Add balance</div>
|
|
28
|
+
<command-form service="balanceTest" action="createBalance" v-slot="{ data }" reset-on-done>
|
|
29
|
+
<div class="col-12 md:col-6 py-1">
|
|
30
|
+
<div class="p-field mb-3">
|
|
31
|
+
<label for="email" class="block text-900 font-medium mb-2">
|
|
32
|
+
Name
|
|
33
|
+
</label>
|
|
34
|
+
<InputText id="name" type="text" class="w-full"
|
|
35
|
+
aria-describedby="email-help" :class="{ 'p-invalid': data.nameError }"
|
|
36
|
+
v-model="data.name" />
|
|
37
|
+
<small id="email-help" class="p-error">{{ data.nameError }}</small>
|
|
38
|
+
</div>
|
|
39
|
+
</div>
|
|
40
|
+
<Button label="Add balance" icon="pi pi-plus" type="submit" />
|
|
41
|
+
</command-form>
|
|
42
|
+
</div>
|
|
6
43
|
</div>
|
|
7
44
|
</template>
|
|
8
45
|
|
|
9
46
|
<script setup>
|
|
10
|
-
|
|
47
|
+
|
|
48
|
+
import InputText from "primevue/inputtext"
|
|
49
|
+
|
|
50
|
+
import {
|
|
51
|
+
defineProps, defineEmits, defineModel, toRefs, computed, watch, ref, watchEffect, onUnmounted,
|
|
52
|
+
getCurrentInstance, unref
|
|
53
|
+
} from 'vue'
|
|
54
|
+
|
|
55
|
+
import { usePath, live, useClient, useActions, reverseRange, useTimeSynchronization } from '@live-change/vue3-ssr'
|
|
56
|
+
const path = usePath()
|
|
57
|
+
const actions = useActions()
|
|
58
|
+
|
|
59
|
+
const allBalancesPath = computed(() => path.balanceTest.allBalances({}))
|
|
60
|
+
|
|
61
|
+
const [allBalances] = await Promise.all([
|
|
62
|
+
live(allBalancesPath)
|
|
63
|
+
])
|
|
64
|
+
|
|
65
|
+
async function deleteBalance(balance) {
|
|
66
|
+
await actions.balanceTest.deleteBalance({ name: balance.owner })
|
|
67
|
+
}
|
|
11
68
|
|
|
12
69
|
</script>
|
|
13
70
|
|
package/front/src/router.js
CHANGED
|
@@ -12,24 +12,15 @@ import { dbAdminRoutes } from "@live-change/db-admin"
|
|
|
12
12
|
import { userRoutes } from "@live-change/user-frontend"
|
|
13
13
|
import { catchAllPagesRoute, contentEditRoutes, pagesSitemap } from "@live-change/content-frontend"
|
|
14
14
|
|
|
15
|
-
import pagesRoutes from '~pages'
|
|
16
15
|
|
|
17
|
-
export function
|
|
16
|
+
export function balanceRoutes(config = {}) {
|
|
18
17
|
const { prefix = '/', route = (r) => r } = config
|
|
19
18
|
return [
|
|
20
19
|
...userRoutes({ ...config, prefix: prefix + 'user/' }),
|
|
21
20
|
|
|
22
|
-
route({
|
|
23
|
-
name: 'index', path: prefix, meta: { },
|
|
24
|
-
component: () => import("./Index.vue")
|
|
25
|
-
}),
|
|
26
21
|
|
|
27
|
-
...pagesRoutes,
|
|
28
22
|
|
|
29
|
-
...contentEditRoutes({ ...config }),
|
|
30
23
|
|
|
31
|
-
...dbAdminRoutes({ prefix: '/_db', route: r => ({ ...r, meta: { ...r.meta, raw: true }}) }),
|
|
32
|
-
...catchAllPagesRoute({ ...config }),
|
|
33
24
|
]
|
|
34
25
|
}
|
|
35
26
|
|
|
@@ -49,7 +40,21 @@ export function createRouter(app, config) {
|
|
|
49
40
|
// use appropriate history implementation for server/client
|
|
50
41
|
// import.meta.env.SSR is injected by Vite.
|
|
51
42
|
history: import.meta.env.SSR ? createMemoryHistory() : createWebHistory(),
|
|
52
|
-
routes:
|
|
43
|
+
routes: [
|
|
44
|
+
...balanceRoutes(config),
|
|
45
|
+
|
|
46
|
+
{
|
|
47
|
+
name: 'index', path: '/', meta: { },
|
|
48
|
+
component: () => import("./Index.vue")
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
name: 'balance', path: '/balance/:name', meta: { }, props: true,
|
|
52
|
+
component: () => import("./Balance.vue")
|
|
53
|
+
},
|
|
54
|
+
|
|
55
|
+
...dbAdminRoutes({ prefix: '/_db', route: r => ({ ...r, meta: { ...r.meta, raw: true }}) }),
|
|
56
|
+
...catchAllPagesRoute({ ...config }),
|
|
57
|
+
]
|
|
53
58
|
})
|
|
54
59
|
installRouterAnalytics(router)
|
|
55
60
|
router.beforeEach(async (to, from) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@live-change/balance-frontend",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.63",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"memDev": "node server/start.js memDev --enableSessions --initScript ./init.js --dbAccess",
|
|
6
6
|
"localDevInit": "rm tmp.db; node server/start.js localDev --enableSessions --initScript ./init.js",
|
|
@@ -35,41 +35,41 @@
|
|
|
35
35
|
"@codemirror/language": "6.10.1",
|
|
36
36
|
"@dotenvx/dotenvx": "0.27.0",
|
|
37
37
|
"@fortawesome/fontawesome-free": "^6.5.2",
|
|
38
|
-
"@live-change/access-control-frontend": "^0.8.
|
|
39
|
-
"@live-change/access-control-service": "^0.8.
|
|
40
|
-
"@live-change/backup-service": "^0.8.
|
|
41
|
-
"@live-change/blog-frontend": "^0.8.
|
|
42
|
-
"@live-change/blog-service": "^0.8.
|
|
43
|
-
"@live-change/cli": "^0.8.
|
|
44
|
-
"@live-change/content-frontend": "^0.8.
|
|
45
|
-
"@live-change/content-service": "^0.8.
|
|
46
|
-
"@live-change/dao": "^0.8.
|
|
47
|
-
"@live-change/dao-vue3": "^0.8.
|
|
48
|
-
"@live-change/dao-websocket": "^0.8.
|
|
49
|
-
"@live-change/db-client": "^0.8.
|
|
50
|
-
"@live-change/email-service": "^0.8.
|
|
51
|
-
"@live-change/framework": "^0.8.
|
|
52
|
-
"@live-change/frontend-auto-form": "^0.8.
|
|
53
|
-
"@live-change/frontend-base": "^0.8.
|
|
54
|
-
"@live-change/geoip-service": "^0.8.
|
|
55
|
-
"@live-change/image-frontend": "^0.8.
|
|
56
|
-
"@live-change/locale-settings-service": "^0.8.
|
|
57
|
-
"@live-change/password-authentication-service": "^0.8.
|
|
58
|
-
"@live-change/prosemirror-service": "^0.8.
|
|
59
|
-
"@live-change/secret-code-service": "^0.8.
|
|
60
|
-
"@live-change/secret-link-service": "^0.8.
|
|
61
|
-
"@live-change/session-service": "^0.8.
|
|
62
|
-
"@live-change/task-service": "^0.8.
|
|
63
|
-
"@live-change/upload-frontend": "^0.8.
|
|
64
|
-
"@live-change/url-frontend": "^0.8.
|
|
65
|
-
"@live-change/url-service": "^0.8.
|
|
66
|
-
"@live-change/user-frontend": "^0.8.
|
|
67
|
-
"@live-change/user-identification-service": "^0.8.
|
|
68
|
-
"@live-change/user-service": "^0.8.
|
|
69
|
-
"@live-change/vote-service": "^0.8.
|
|
70
|
-
"@live-change/vue3-components": "^0.8.
|
|
71
|
-
"@live-change/vue3-ssr": "^0.8.
|
|
72
|
-
"@live-change/wysiwyg-frontend": "^0.8.
|
|
38
|
+
"@live-change/access-control-frontend": "^0.8.63",
|
|
39
|
+
"@live-change/access-control-service": "^0.8.63",
|
|
40
|
+
"@live-change/backup-service": "^0.8.63",
|
|
41
|
+
"@live-change/blog-frontend": "^0.8.63",
|
|
42
|
+
"@live-change/blog-service": "^0.8.63",
|
|
43
|
+
"@live-change/cli": "^0.8.63",
|
|
44
|
+
"@live-change/content-frontend": "^0.8.63",
|
|
45
|
+
"@live-change/content-service": "^0.8.63",
|
|
46
|
+
"@live-change/dao": "^0.8.63",
|
|
47
|
+
"@live-change/dao-vue3": "^0.8.63",
|
|
48
|
+
"@live-change/dao-websocket": "^0.8.63",
|
|
49
|
+
"@live-change/db-client": "^0.8.63",
|
|
50
|
+
"@live-change/email-service": "^0.8.63",
|
|
51
|
+
"@live-change/framework": "^0.8.63",
|
|
52
|
+
"@live-change/frontend-auto-form": "^0.8.63",
|
|
53
|
+
"@live-change/frontend-base": "^0.8.63",
|
|
54
|
+
"@live-change/geoip-service": "^0.8.63",
|
|
55
|
+
"@live-change/image-frontend": "^0.8.63",
|
|
56
|
+
"@live-change/locale-settings-service": "^0.8.63",
|
|
57
|
+
"@live-change/password-authentication-service": "^0.8.63",
|
|
58
|
+
"@live-change/prosemirror-service": "^0.8.63",
|
|
59
|
+
"@live-change/secret-code-service": "^0.8.63",
|
|
60
|
+
"@live-change/secret-link-service": "^0.8.63",
|
|
61
|
+
"@live-change/session-service": "^0.8.63",
|
|
62
|
+
"@live-change/task-service": "^0.8.63",
|
|
63
|
+
"@live-change/upload-frontend": "^0.8.63",
|
|
64
|
+
"@live-change/url-frontend": "^0.8.63",
|
|
65
|
+
"@live-change/url-service": "^0.8.63",
|
|
66
|
+
"@live-change/user-frontend": "^0.8.63",
|
|
67
|
+
"@live-change/user-identification-service": "^0.8.63",
|
|
68
|
+
"@live-change/user-service": "^0.8.63",
|
|
69
|
+
"@live-change/vote-service": "^0.8.63",
|
|
70
|
+
"@live-change/vue3-components": "^0.8.63",
|
|
71
|
+
"@live-change/vue3-ssr": "^0.8.63",
|
|
72
|
+
"@live-change/wysiwyg-frontend": "^0.8.63",
|
|
73
73
|
"@vueuse/core": "^10.11.0",
|
|
74
74
|
"codeceptjs-assert": "^0.0.5",
|
|
75
75
|
"compression": "^1.7.4",
|
|
@@ -91,7 +91,7 @@
|
|
|
91
91
|
"vue3-scroll-border": "0.1.6"
|
|
92
92
|
},
|
|
93
93
|
"devDependencies": {
|
|
94
|
-
"@live-change/codeceptjs-helper": "^0.8.
|
|
94
|
+
"@live-change/codeceptjs-helper": "^0.8.63",
|
|
95
95
|
"codeceptjs": "^3.6.5",
|
|
96
96
|
"generate-password": "1.7.1",
|
|
97
97
|
"playwright": "^1.41.2",
|
|
@@ -102,5 +102,5 @@
|
|
|
102
102
|
"author": "Michał Łaszczewski <michal@laszczewski.pl>",
|
|
103
103
|
"license": "ISC",
|
|
104
104
|
"description": "",
|
|
105
|
-
"gitHead": "
|
|
105
|
+
"gitHead": "f49f580138d6c44d9e9820197765ef982c5bab03"
|
|
106
106
|
}
|
package/server/app.config.js
CHANGED
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import App from '@live-change/framework'
|
|
2
|
+
const app = App.app()
|
|
3
|
+
|
|
4
|
+
import definition from './definition.js'
|
|
5
|
+
|
|
6
|
+
const Balance = definition.foreignModel('balance', 'Balance')
|
|
7
|
+
const Operation = definition.foreignModel('balance', 'Operation')
|
|
8
|
+
|
|
9
|
+
definition.action({
|
|
10
|
+
name: 'createBalance',
|
|
11
|
+
properties: {
|
|
12
|
+
name: {
|
|
13
|
+
type: String,
|
|
14
|
+
validation: ["nonEmpty"]
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
returns: {
|
|
18
|
+
type: Balance
|
|
19
|
+
},
|
|
20
|
+
async execute({ name }, { service, client, triggerService }, emit) {
|
|
21
|
+
await triggerService({
|
|
22
|
+
service: 'accessControl',
|
|
23
|
+
type: 'accessControl_setOrUpdateObjectOwnedPublicAccess'
|
|
24
|
+
}, {
|
|
25
|
+
objectType: 'balanceTest_balance',
|
|
26
|
+
object: name,
|
|
27
|
+
sessionRoles: ['owner'],
|
|
28
|
+
})
|
|
29
|
+
return await triggerService({
|
|
30
|
+
service: 'balance',
|
|
31
|
+
type: 'balance_setOwnerOwnedBalance'
|
|
32
|
+
}, {
|
|
33
|
+
ownerType: 'balanceTest_balance',
|
|
34
|
+
owner: name
|
|
35
|
+
})
|
|
36
|
+
}
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
definition.action({
|
|
40
|
+
name: 'deleteBalance',
|
|
41
|
+
properties: {
|
|
42
|
+
name: {
|
|
43
|
+
type: String,
|
|
44
|
+
validation: ["nonEmpty"]
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
async execute({ name }, { service, client, triggerService }, emit) {
|
|
48
|
+
return await triggerService({
|
|
49
|
+
service: 'balance',
|
|
50
|
+
type: 'balance_resetOwnerOwnedBalance'
|
|
51
|
+
}, {
|
|
52
|
+
ownerType: 'balanceTest_balance',
|
|
53
|
+
owner: name
|
|
54
|
+
})
|
|
55
|
+
}
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
definition.view({
|
|
59
|
+
name: 'allBalances',
|
|
60
|
+
properties: {
|
|
61
|
+
...App.rangeProperties
|
|
62
|
+
},
|
|
63
|
+
returns: {
|
|
64
|
+
type: Array,
|
|
65
|
+
of: {
|
|
66
|
+
type: Balance
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
async daoPath(range, { client, service }, method) {
|
|
70
|
+
return await Balance.rangePath(range)
|
|
71
|
+
}
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
definition.action({
|
|
75
|
+
name: 'startOperation',
|
|
76
|
+
properties: {
|
|
77
|
+
balance: {
|
|
78
|
+
type: Balance,
|
|
79
|
+
validation: ['nonEmpty']
|
|
80
|
+
},
|
|
81
|
+
change: {
|
|
82
|
+
type: Number,
|
|
83
|
+
validation: ['nonEmpty', 'integer']
|
|
84
|
+
},
|
|
85
|
+
name: {
|
|
86
|
+
type: String,
|
|
87
|
+
validation: ['nonEmpty']
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
async execute({ balance, change, name }, { client, service, triggerService }, emit) {
|
|
91
|
+
return await triggerService({
|
|
92
|
+
service: 'balance',
|
|
93
|
+
type: 'balance_startOperation'
|
|
94
|
+
}, {
|
|
95
|
+
balance, change,
|
|
96
|
+
causeType: 'balanceTest_operation',
|
|
97
|
+
cause: name
|
|
98
|
+
})
|
|
99
|
+
}
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
definition.action({
|
|
103
|
+
name: 'finishOperation',
|
|
104
|
+
properties: {
|
|
105
|
+
balance: {
|
|
106
|
+
type: Balance,
|
|
107
|
+
validation: ['nonEmpty']
|
|
108
|
+
},
|
|
109
|
+
operation: {
|
|
110
|
+
type: Operation,
|
|
111
|
+
validation: ['nonEmpty']
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
async execute({ balance, operation }, { client, service, triggerService }, emit) {
|
|
115
|
+
return await triggerService({
|
|
116
|
+
service: 'balance',
|
|
117
|
+
type: 'balance_finishOperation'
|
|
118
|
+
}, {
|
|
119
|
+
balance, operation
|
|
120
|
+
})
|
|
121
|
+
}
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
definition.action({
|
|
125
|
+
name: 'cancelOperation',
|
|
126
|
+
properties: {
|
|
127
|
+
balance: {
|
|
128
|
+
type: Balance,
|
|
129
|
+
validation: ['nonEmpty']
|
|
130
|
+
},
|
|
131
|
+
operation: {
|
|
132
|
+
type: Operation,
|
|
133
|
+
validation: ['nonEmpty']
|
|
134
|
+
}
|
|
135
|
+
},
|
|
136
|
+
async execute({ balance, operation }, { client, service, triggerService }, emit) {
|
|
137
|
+
return await triggerService({
|
|
138
|
+
service: 'balance',
|
|
139
|
+
type: 'balance_cancelOperation'
|
|
140
|
+
}, {
|
|
141
|
+
balance, operation
|
|
142
|
+
})
|
|
143
|
+
}
|
|
144
|
+
})
|
|
145
|
+
|
|
146
|
+
definition.action({
|
|
147
|
+
name: 'doOperation',
|
|
148
|
+
properties: {
|
|
149
|
+
balance: {
|
|
150
|
+
type: Balance,
|
|
151
|
+
validation: ['nonEmpty']
|
|
152
|
+
},
|
|
153
|
+
change: {
|
|
154
|
+
type: Number,
|
|
155
|
+
validation: ['nonEmpty', 'integer']
|
|
156
|
+
},
|
|
157
|
+
name: {
|
|
158
|
+
type: String,
|
|
159
|
+
validation: ['nonEmpty']
|
|
160
|
+
}
|
|
161
|
+
},
|
|
162
|
+
async execute({ balance, change, name }, { client, service, triggerService }, emit) {
|
|
163
|
+
return await triggerService({
|
|
164
|
+
service: 'balance',
|
|
165
|
+
type: 'balance_doOperation'
|
|
166
|
+
}, {
|
|
167
|
+
balance, change,
|
|
168
|
+
causeType: 'balanceTest_operation',
|
|
169
|
+
cause: name
|
|
170
|
+
})
|
|
171
|
+
}
|
|
172
|
+
})
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import App from '@live-change/framework'
|
|
2
|
+
const app = App.app()
|
|
3
|
+
|
|
4
|
+
import relationsPlugin from '@live-change/relations-plugin'
|
|
5
|
+
import accessControlService from '@live-change/access-control-service'
|
|
6
|
+
|
|
7
|
+
const definition = app.createServiceDefinition({
|
|
8
|
+
name: "balanceTest",
|
|
9
|
+
use: [ relationsPlugin, accessControlService ]
|
|
10
|
+
})
|
|
11
|
+
|
|
12
|
+
export default definition
|
package/server/services.list.js
CHANGED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
<template>
|
|
3
|
-
<div class="surface-card p-3 shadow-2 border-round">
|
|
4
|
-
{{ d(new Date(), 'long') }}
|
|
5
|
-
</div>
|
|
6
|
-
</template>
|
|
7
|
-
|
|
8
|
-
<script setup lang="ts">
|
|
9
|
-
import { defineProps, toRefs } from 'vue'
|
|
10
|
-
import { useI18n } from 'vue-i18n'
|
|
11
|
-
const { t, d, n } = useI18n()
|
|
12
|
-
|
|
13
|
-
const props = defineProps<{
|
|
14
|
-
time: number
|
|
15
|
-
}>()
|
|
16
|
-
|
|
17
|
-
const { time } = toRefs(props)
|
|
18
|
-
</script>
|
|
19
|
-
|
|
20
|
-
<style scoped>
|
|
21
|
-
|
|
22
|
-
</style>
|