@vandenberghinc/volt 1.1.4 → 1.1.6
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/backend/dist/cjs/database.d.ts +41 -68
- package/backend/dist/cjs/database.js +136 -78
- package/backend/dist/cjs/endpoint.d.ts +23 -9
- package/backend/dist/cjs/endpoint.js +98 -21
- package/backend/dist/cjs/file_watcher.js +2 -2
- package/backend/dist/cjs/frontend.d.ts +0 -2
- package/backend/dist/cjs/frontend.js +9 -9
- package/backend/dist/cjs/image_endpoint.d.ts +3 -1
- package/backend/dist/cjs/image_endpoint.js +2 -1
- package/backend/dist/cjs/payments/paddle.js +10 -2
- package/backend/dist/cjs/plugins/css.d.ts +6 -5
- package/backend/dist/cjs/plugins/css.js +32 -7
- package/backend/dist/cjs/plugins/ts/compiler.d.ts +6 -1
- package/backend/dist/cjs/plugins/ts/compiler.js +26 -2
- package/backend/dist/cjs/plugins/ts/preprocessing.js +5 -3
- package/backend/dist/cjs/server.d.ts +7 -13
- package/backend/dist/cjs/server.js +184 -303
- package/backend/dist/cjs/status.d.ts +1 -0
- package/backend/dist/cjs/status.js +2 -1
- package/backend/dist/cjs/stream.d.ts +5 -3
- package/backend/dist/cjs/stream.js +13 -4
- package/backend/dist/cjs/users.d.ts +1 -1
- package/backend/dist/cjs/users.js +87 -72
- package/backend/dist/cjs/utils.d.ts +17 -9
- package/backend/dist/cjs/utils.js +22 -64
- package/backend/dist/cjs/view.d.ts +2 -2
- package/backend/dist/cjs/view.js +38 -40
- package/backend/dist/cjs/volt.d.ts +3 -2
- package/backend/dist/cjs/volt.js +2 -2
- package/backend/dist/css/volt.css +5 -0
- package/backend/dist/esm/database.d.ts +41 -68
- package/backend/dist/esm/database.js +137 -79
- package/backend/dist/esm/endpoint.d.ts +23 -9
- package/backend/dist/esm/endpoint.js +99 -22
- package/backend/dist/esm/file_watcher.js +2 -2
- package/backend/dist/esm/frontend.d.ts +0 -2
- package/backend/dist/esm/frontend.js +9 -9
- package/backend/dist/esm/image_endpoint.d.ts +3 -1
- package/backend/dist/esm/image_endpoint.js +2 -1
- package/backend/dist/esm/payments/paddle.js +11 -3
- package/backend/dist/esm/plugins/css.d.ts +6 -5
- package/backend/dist/esm/plugins/css.js +32 -6
- package/backend/dist/esm/plugins/ts/compiler.d.ts +6 -1
- package/backend/dist/esm/plugins/ts/compiler.js +26 -2
- package/backend/dist/esm/plugins/ts/preprocessing.js +5 -3
- package/backend/dist/esm/server.d.ts +7 -13
- package/backend/dist/esm/server.js +182 -301
- package/backend/dist/esm/status.d.ts +1 -0
- package/backend/dist/esm/status.js +1 -0
- package/backend/dist/esm/stream.d.ts +5 -3
- package/backend/dist/esm/stream.js +13 -4
- package/backend/dist/esm/users.d.ts +1 -1
- package/backend/dist/esm/users.js +87 -72
- package/backend/dist/esm/utils.d.ts +17 -9
- package/backend/dist/esm/utils.js +21 -62
- package/backend/dist/esm/view.d.ts +2 -2
- package/backend/dist/esm/view.js +38 -40
- package/backend/dist/esm/volt.d.ts +3 -2
- package/backend/dist/esm/volt.js +2 -1
- package/backend/dist/esm-dev/blacklist.js +1 -1
- package/backend/dist/esm-dev/cli.js +2 -2
- package/backend/dist/esm-dev/database.d.ts +41 -68
- package/backend/dist/esm-dev/database.js +138 -80
- package/backend/dist/esm-dev/endpoint.d.ts +23 -9
- package/backend/dist/esm-dev/endpoint.js +100 -23
- package/backend/dist/esm-dev/file_watcher.js +3 -3
- package/backend/dist/esm-dev/frontend.d.ts +0 -2
- package/backend/dist/esm-dev/frontend.js +9 -9
- package/backend/dist/esm-dev/image_endpoint.d.ts +3 -1
- package/backend/dist/esm-dev/image_endpoint.js +2 -1
- package/backend/dist/esm-dev/logger.js +1 -1
- package/backend/dist/esm-dev/payments/paddle.js +12 -4
- package/backend/dist/esm-dev/plugins/css.d.ts +6 -5
- package/backend/dist/esm-dev/plugins/css.js +33 -7
- package/backend/dist/esm-dev/plugins/ts/compiler.d.ts +6 -1
- package/backend/dist/esm-dev/plugins/ts/compiler.js +27 -3
- package/backend/dist/esm-dev/plugins/ts/preprocessing.js +7 -5
- package/backend/dist/esm-dev/rate_limit.js +1 -1
- package/backend/dist/esm-dev/server.d.ts +7 -13
- package/backend/dist/esm-dev/server.js +184 -303
- package/backend/dist/esm-dev/status.d.ts +1 -0
- package/backend/dist/esm-dev/status.js +1 -0
- package/backend/dist/esm-dev/stream.d.ts +5 -3
- package/backend/dist/esm-dev/stream.js +13 -4
- package/backend/dist/esm-dev/users.d.ts +1 -1
- package/backend/dist/esm-dev/users.js +88 -73
- package/backend/dist/esm-dev/utils.d.ts +17 -9
- package/backend/dist/esm-dev/utils.js +22 -63
- package/backend/dist/esm-dev/view.d.ts +2 -2
- package/backend/dist/esm-dev/view.js +39 -41
- package/backend/dist/esm-dev/volt.d.ts +3 -2
- package/backend/dist/esm-dev/volt.js +2 -1
- package/backend/src/database.ts +173 -155
- package/backend/src/endpoint.ts +123 -31
- package/backend/src/file_watcher.ts +2 -2
- package/backend/src/frontend.ts +9 -8
- package/backend/src/image_endpoint.ts +4 -0
- package/backend/src/payments/paddle.ts +11 -3
- package/backend/src/plugins/css.ts +36 -8
- package/backend/src/plugins/ts/compiler.ts +37 -1
- package/backend/src/plugins/ts/preprocessing.ts +5 -3
- package/backend/src/server.ts +167 -306
- package/backend/src/status.ts +1 -0
- package/backend/src/stream.ts +28 -8
- package/backend/src/users.ts +87 -72
- package/backend/src/utils.ts +58 -25
- package/backend/src/view.ts +30 -28
- package/backend/src/{volt.js → volt.ts} +2 -1
- package/backend/tsconfig.cjs.json +3 -3
- package/backend/tsconfig.esm.json +3 -3
- package/frontend/dist/elements/base.d.ts +414 -432
- package/frontend/dist/elements/base.js +566 -329
- package/frontend/dist/elements/module.d.ts +26 -12
- package/frontend/dist/elements/module.js +69 -32
- package/frontend/dist/elements/register_element.d.ts +3 -0
- package/frontend/dist/elements/register_element.js +22 -0
- package/frontend/dist/modules/auth.d.ts +1 -0
- package/frontend/dist/modules/auth.js +6 -5
- package/frontend/dist/modules/color.d.ts +159 -0
- package/frontend/dist/modules/color.js +315 -0
- package/frontend/dist/modules/colors.d.ts +1 -26
- package/frontend/dist/modules/colors.js +417 -340
- package/frontend/dist/modules/cookies.d.ts +1 -0
- package/frontend/dist/modules/cookies.js +1 -0
- package/frontend/dist/modules/events.d.ts +1 -0
- package/frontend/dist/modules/events.js +1 -0
- package/frontend/dist/modules/google.d.ts +1 -0
- package/frontend/dist/modules/google.js +1 -0
- package/frontend/dist/modules/meta.d.ts +1 -0
- package/frontend/dist/modules/meta.js +1 -0
- package/frontend/dist/modules/mutex.d.ts +1 -2
- package/frontend/dist/modules/mutex.js +3 -4
- package/frontend/dist/modules/paddle.d.ts +1 -0
- package/frontend/dist/modules/paddle.js +14 -13
- package/frontend/dist/modules/scheme.d.ts +1 -0
- package/frontend/dist/modules/scheme.js +5 -3
- package/frontend/dist/modules/statics.d.ts +1 -0
- package/frontend/dist/modules/statics.js +1 -0
- package/frontend/dist/modules/support.d.ts +1 -0
- package/frontend/dist/modules/support.js +3 -2
- package/frontend/dist/modules/theme.d.ts +56 -0
- package/frontend/dist/{ui → modules}/theme.js +186 -75
- package/frontend/dist/modules/themes.d.ts +1 -1
- package/frontend/dist/modules/themes.js +1 -0
- package/frontend/dist/modules/user.d.ts +1 -0
- package/frontend/dist/modules/user.js +11 -10
- package/frontend/dist/modules/utils.d.ts +23 -2
- package/frontend/dist/modules/utils.js +93 -1
- package/frontend/dist/types/gradient.js +4 -0
- package/frontend/dist/ui/border_button.d.ts +0 -25
- package/frontend/dist/ui/border_button.js +50 -51
- package/frontend/dist/ui/button.d.ts +0 -21
- package/frontend/dist/ui/button.js +41 -46
- package/frontend/dist/ui/canvas.js +15 -15
- package/frontend/dist/ui/checkbox.d.ts +3 -17
- package/frontend/dist/ui/checkbox.js +36 -30
- package/frontend/dist/ui/code.d.ts +15 -82
- package/frontend/dist/ui/code.js +150 -125
- package/frontend/dist/ui/color.d.ts +0 -1
- package/frontend/dist/ui/color.js +1 -1
- package/frontend/dist/ui/context_menu.d.ts +4 -2
- package/frontend/dist/ui/context_menu.js +16 -17
- package/frontend/dist/ui/css.js +2 -0
- package/frontend/dist/ui/divider.d.ts +0 -7
- package/frontend/dist/ui/divider.js +21 -25
- package/frontend/dist/ui/dropdown.d.ts +13 -7
- package/frontend/dist/ui/dropdown.js +65 -30
- package/frontend/dist/ui/for_each.d.ts +0 -5
- package/frontend/dist/ui/for_each.js +17 -22
- package/frontend/dist/ui/form.d.ts +17 -12
- package/frontend/dist/ui/form.js +21 -18
- package/frontend/dist/ui/frame_modes.d.ts +9 -12
- package/frontend/dist/ui/frame_modes.js +8 -10
- package/frontend/dist/ui/google_map.d.ts +0 -11
- package/frontend/dist/ui/google_map.js +23 -28
- package/frontend/dist/ui/gradient.d.ts +0 -5
- package/frontend/dist/ui/gradient.js +17 -22
- package/frontend/dist/ui/image.d.ts +27 -58
- package/frontend/dist/ui/image.js +99 -93
- package/frontend/dist/ui/input.d.ts +20 -97
- package/frontend/dist/ui/input.js +192 -170
- package/frontend/dist/ui/link.d.ts +0 -18
- package/frontend/dist/ui/link.js +42 -48
- package/frontend/dist/ui/list.js +36 -37
- package/frontend/dist/ui/loader_button.d.ts +4 -19
- package/frontend/dist/ui/loader_button.js +35 -37
- package/frontend/dist/ui/loaders.d.ts +0 -8
- package/frontend/dist/ui/loaders.js +20 -25
- package/frontend/dist/ui/popup.d.ts +11 -8
- package/frontend/dist/ui/popup.js +183 -24
- package/frontend/dist/ui/pseudo.d.ts +3 -3
- package/frontend/dist/ui/pseudo.js +14 -17
- package/frontend/dist/ui/scroller.d.ts +10 -48
- package/frontend/dist/ui/scroller.js +306 -300
- package/frontend/dist/ui/slider.d.ts +9 -3
- package/frontend/dist/ui/slider.js +31 -17
- package/frontend/dist/ui/spacer.d.ts +0 -9
- package/frontend/dist/ui/spacer.js +21 -26
- package/frontend/dist/ui/span.js +13 -15
- package/frontend/dist/ui/stack.d.ts +14 -75
- package/frontend/dist/ui/stack.js +166 -169
- package/frontend/dist/ui/steps.d.ts +10 -23
- package/frontend/dist/ui/steps.js +47 -34
- package/frontend/dist/ui/style.d.ts +4 -3
- package/frontend/dist/ui/style.js +13 -18
- package/frontend/dist/ui/switch.d.ts +10 -4
- package/frontend/dist/ui/switch.js +24 -16
- package/frontend/dist/ui/table.d.ts +0 -23
- package/frontend/dist/ui/table.js +113 -119
- package/frontend/dist/ui/tabs.d.ts +3 -19
- package/frontend/dist/ui/tabs.js +35 -29
- package/frontend/dist/ui/text.d.ts +0 -8
- package/frontend/dist/ui/text.js +20 -25
- package/frontend/dist/ui/title.d.ts +0 -15
- package/frontend/dist/ui/title.js +39 -45
- package/frontend/dist/ui/ui.d.ts +0 -2
- package/frontend/dist/ui/ui.js +0 -2
- package/frontend/dist/ui/view.d.ts +3 -17
- package/frontend/dist/ui/view.js +27 -32
- package/frontend/dist/volt.d.ts +2 -1
- package/frontend/dist/volt.js +3 -1
- package/frontend/examples/dashboard/dashboard.ts +774 -0
- package/frontend/examples/theme/theme.ts +58 -0
- package/frontend/src/css/volt.css +5 -0
- package/frontend/src/elements/base.ts +767 -545
- package/frontend/src/elements/module.ts +90 -29
- package/frontend/src/elements/register_element.ts +24 -0
- package/frontend/src/modules/auth.ts +7 -6
- package/frontend/src/modules/color.ts +348 -0
- package/frontend/src/modules/colors.ts +468 -449
- package/frontend/src/modules/cookies.ts +1 -0
- package/frontend/src/modules/events.ts +1 -0
- package/frontend/src/modules/google.ts +1 -0
- package/frontend/src/modules/meta.ts +2 -1
- package/frontend/src/modules/mutex.ts +2 -4
- package/frontend/src/modules/paddle.ts +21 -20
- package/frontend/src/modules/scheme.ts +5 -4
- package/frontend/src/modules/statics.ts +2 -1
- package/frontend/src/modules/support.ts +3 -2
- package/frontend/src/modules/theme.ts +413 -0
- package/frontend/src/modules/themes.ts +2 -1
- package/frontend/src/modules/user.ts +12 -11
- package/frontend/src/modules/utils.ts +125 -2
- package/frontend/src/ui/border_button.ts +41 -37
- package/frontend/src/ui/button.ts +33 -32
- package/frontend/src/ui/canvas.ts +5 -2
- package/frontend/src/ui/checkbox.ts +21 -22
- package/frontend/src/ui/code.ts +92 -86
- package/frontend/src/ui/context_menu.ts +7 -5
- package/frontend/src/ui/css.ts +1 -1
- package/frontend/src/ui/divider.ts +15 -10
- package/frontend/src/ui/dropdown.ts +38 -21
- package/frontend/src/ui/for_each.ts +9 -8
- package/frontend/src/ui/form.ts +26 -21
- package/frontend/src/ui/frame_modes.ts +13 -17
- package/frontend/src/ui/google_map.ts +15 -13
- package/frontend/src/ui/gradient.ts +9 -8
- package/frontend/src/ui/image.ts +108 -86
- package/frontend/src/ui/input.ts +145 -144
- package/frontend/src/ui/link.ts +25 -23
- package/frontend/src/ui/list.ts +12 -6
- package/frontend/src/ui/loader_button.ts +26 -25
- package/frontend/src/ui/loaders.ts +12 -11
- package/frontend/src/ui/popup.ts +168 -14
- package/frontend/src/ui/pseudo.ts +5 -3
- package/frontend/src/ui/scroller.ts +303 -294
- package/frontend/src/ui/slider.ts +15 -10
- package/frontend/src/ui/spacer.ts +14 -11
- package/frontend/src/ui/span.ts +6 -2
- package/frontend/src/ui/stack.ts +196 -183
- package/frontend/src/ui/steps.ts +38 -22
- package/frontend/src/ui/style.ts +7 -4
- package/frontend/src/ui/switch.ts +16 -11
- package/frontend/src/ui/table.ts +42 -34
- package/frontend/src/ui/tabs.ts +20 -19
- package/frontend/src/ui/text.ts +12 -11
- package/frontend/src/ui/title.ts +22 -20
- package/frontend/src/ui/ui.ts +0 -2
- package/frontend/src/ui/view.ts +20 -19
- package/frontend/src/volt.ts +3 -1
- package/frontend/{compile.js → tools/compile.old.js} +2 -2
- package/frontend/tools/embed_scripts.js +69 -0
- package/frontend/tsconfig.json +26 -0
- package/package.json +7 -6
- package/frontend/dist/ui/theme.d.ts +0 -25
- package/frontend/exports.json +0 -1340
- package/frontend/src/modules/date.js +0 -535
- package/frontend/src/ui/color.ts +0 -117
- package/frontend/src/ui/theme.ts +0 -279
- /package/backend/src/{vinc.dev.js → vinc.dev.ts} +0 -0
|
@@ -0,0 +1,774 @@
|
|
|
1
|
+
// Imports.
|
|
2
|
+
import * as volt from "@vandenberghinc/volt/frontend"
|
|
3
|
+
import { ResponseStatus, Theme, UI } from "../defaults.js";
|
|
4
|
+
|
|
5
|
+
// Global variables.
|
|
6
|
+
const endpoint = volt.Utils.endpoint();
|
|
7
|
+
|
|
8
|
+
// ---------------------------------------------------------
|
|
9
|
+
// Utils.
|
|
10
|
+
|
|
11
|
+
// A side by side form container.
|
|
12
|
+
const SideByFormContainer = (...children) => {
|
|
13
|
+
return volt.HStack(
|
|
14
|
+
...children
|
|
15
|
+
)
|
|
16
|
+
.align_height()
|
|
17
|
+
.width("100%")
|
|
18
|
+
.overflow("hidden")
|
|
19
|
+
.media(
|
|
20
|
+
"width >= 900px",
|
|
21
|
+
e => e.side_by_side({ columns: 2, vspacing: 0, hspacing: 65 }).margin_bottom(65),
|
|
22
|
+
e => e.side_by_side({ columns: 1, vspacing: 50, hspacing: 0 }).margin_bottom(50)
|
|
23
|
+
)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Dashboard form.
|
|
27
|
+
function FormWidget(
|
|
28
|
+
{
|
|
29
|
+
title = undefined,
|
|
30
|
+
text = undefined,
|
|
31
|
+
button = "Button",
|
|
32
|
+
center_button = false,
|
|
33
|
+
small_button = true,
|
|
34
|
+
right_top_button = false,
|
|
35
|
+
inputs = [],
|
|
36
|
+
on_submit = (data, form) => { },
|
|
37
|
+
spacer = false,
|
|
38
|
+
}: {
|
|
39
|
+
title?: string,
|
|
40
|
+
text?: string,
|
|
41
|
+
button?: string | boolean,
|
|
42
|
+
center_button?: boolean,
|
|
43
|
+
small_button?: boolean,
|
|
44
|
+
right_top_button?: boolean,
|
|
45
|
+
inputs?: any[],
|
|
46
|
+
on_submit?: (data: any, form: volt.FormElement) => any,
|
|
47
|
+
spacer?: boolean,
|
|
48
|
+
}
|
|
49
|
+
) {
|
|
50
|
+
return volt.Form(
|
|
51
|
+
|
|
52
|
+
right_top_button
|
|
53
|
+
? [
|
|
54
|
+
volt.HStack(
|
|
55
|
+
UI.Title(title)
|
|
56
|
+
.stretch(true)
|
|
57
|
+
.margin(0)
|
|
58
|
+
.wrap(true),
|
|
59
|
+
UI.Button(button)
|
|
60
|
+
.padding(5, 15)
|
|
61
|
+
.margin_top(0)
|
|
62
|
+
.font_size(15)
|
|
63
|
+
)
|
|
64
|
+
.center_vertical()
|
|
65
|
+
.margin(0, 0, 12.5, 0)
|
|
66
|
+
.wrap(false)
|
|
67
|
+
]
|
|
68
|
+
: title == null ? null : (
|
|
69
|
+
UI.Title(title)
|
|
70
|
+
.width("fit-content")
|
|
71
|
+
.margin(0, 0, 7.5, 0)
|
|
72
|
+
),
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
// @ts-ignore-error
|
|
76
|
+
text == null ? null : (
|
|
77
|
+
UI.Text(text)
|
|
78
|
+
.margin_bottom(inputs.length > 0 ? 20 : 0)
|
|
79
|
+
),
|
|
80
|
+
|
|
81
|
+
volt.ForEach(inputs, (item) => UI.Input(item)),
|
|
82
|
+
|
|
83
|
+
spacer ? volt.Spacer() : null,
|
|
84
|
+
|
|
85
|
+
// Save.
|
|
86
|
+
right_top_button ? null : (
|
|
87
|
+
volt.VStack(
|
|
88
|
+
button === false ? null : (
|
|
89
|
+
UI.Button(button)
|
|
90
|
+
.padding(small_button ? 7.5 : 10, small_button ? 25 : 40)
|
|
91
|
+
.margin_top(inputs.length > 0 ? 15 : 25)
|
|
92
|
+
)
|
|
93
|
+
)
|
|
94
|
+
.width("100%")
|
|
95
|
+
.align(center_button ? (inputs.length > 0 ? "center" : "start") : "start")
|
|
96
|
+
),
|
|
97
|
+
)
|
|
98
|
+
.width("100%")
|
|
99
|
+
.on_submit((e, data) => on_submit(data, e))
|
|
100
|
+
.on_submit_error((_, error) => {
|
|
101
|
+
ResponseStatus.error(error)
|
|
102
|
+
})
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// ---------------------------------------------------------
|
|
106
|
+
// Pages.
|
|
107
|
+
|
|
108
|
+
function AccountPage(): PageOptions {
|
|
109
|
+
return {
|
|
110
|
+
type: "item",
|
|
111
|
+
title: "Account Settings",
|
|
112
|
+
endpoint: "/dashboard/account",
|
|
113
|
+
icon: "/static/icons/username.webp",
|
|
114
|
+
content() {
|
|
115
|
+
return volt.Frame(
|
|
116
|
+
SideByFormContainer(
|
|
117
|
+
|
|
118
|
+
// General info.
|
|
119
|
+
FormWidget({
|
|
120
|
+
title: "Profile",
|
|
121
|
+
text: "Setup your account and edit your profile details.",
|
|
122
|
+
button: "Update",
|
|
123
|
+
inputs: [
|
|
124
|
+
{ label: "First name", placeholder: "John", id: "first_name", required: true, image: "/static/icons/username.red.webp", },
|
|
125
|
+
{ label: "Last name", placeholder: "Doe", id: "last_name", required: true, image: "/static/icons/username.red.webp", },
|
|
126
|
+
{ label: "Username", placeholder: "myusername", id: "username", required: true, image: "/static/icons/username.red.webp", },
|
|
127
|
+
{ label: "Email", placeholder: "my@email.com", id: "email", required: true, image: "/static/icons/mail.webp", },
|
|
128
|
+
],
|
|
129
|
+
right_top_button: true,
|
|
130
|
+
on_submit: async (data) => {
|
|
131
|
+
const response = await volt.User.set(data)
|
|
132
|
+
ResponseStatus.message(response.message);
|
|
133
|
+
}
|
|
134
|
+
}),
|
|
135
|
+
// ThemeV2.Divider().margin(40, 0),
|
|
136
|
+
|
|
137
|
+
// Password.
|
|
138
|
+
FormWidget({
|
|
139
|
+
title: "Password",
|
|
140
|
+
text: "Change your account's password.",
|
|
141
|
+
button: "Update",
|
|
142
|
+
inputs: [
|
|
143
|
+
{ label: "Current password", placeholder: "Current password", id: "current_password", required: true, image: "/static/icons/password.webp", type: "password" },
|
|
144
|
+
{ label: "New Password", placeholder: "Password", id: "password", required: true, image: "/static/icons/password.webp", type: "password" },
|
|
145
|
+
{ label: "Verify new password", placeholder: "Verify password", id: "verify_password", required: true, image: "/static/icons/password.webp", type: "password" },
|
|
146
|
+
],
|
|
147
|
+
right_top_button: true,
|
|
148
|
+
on_submit: async (data, form) => {
|
|
149
|
+
const response =
|
|
150
|
+
volt.User.change_password(data)
|
|
151
|
+
.then((response) => {
|
|
152
|
+
ResponseStatus.message(response.message);
|
|
153
|
+
})
|
|
154
|
+
.catch(({ error, status, invalid_fields }) => {
|
|
155
|
+
if (invalid_fields) {
|
|
156
|
+
if (invalid_fields.current_password) {
|
|
157
|
+
form.fields.current_password.missing(true, invalid_fields.current_password);
|
|
158
|
+
}
|
|
159
|
+
if (invalid_fields.password) {
|
|
160
|
+
form.fields.password.missing(true, invalid_fields.password);
|
|
161
|
+
}
|
|
162
|
+
if (invalid_fields.verify_password) {
|
|
163
|
+
form.fields.verify_password.missing(true, invalid_fields.verify_password);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
ResponseStatus.error(error);
|
|
167
|
+
})
|
|
168
|
+
},
|
|
169
|
+
}),
|
|
170
|
+
),
|
|
171
|
+
SideByFormContainer(
|
|
172
|
+
volt.VStack(
|
|
173
|
+
// No api key exists.
|
|
174
|
+
FormWidget({
|
|
175
|
+
title: "API key",
|
|
176
|
+
text: "Currently you do not have an API key. Generate an API key to get API access.\nWhen generated the API key is only shown once. Make sure to store it correctly, since you have to regenerate the API key if you lose it.",
|
|
177
|
+
button: "Generate",
|
|
178
|
+
right_top_button: true,
|
|
179
|
+
async on_submit() {
|
|
180
|
+
const response = await volt.User.generate_api_key()
|
|
181
|
+
if (response.error) {
|
|
182
|
+
ResponseStatus.message(response.error);
|
|
183
|
+
} else if (response.api_key) {
|
|
184
|
+
volt.Elements.get("api_key").value(response.api_key);
|
|
185
|
+
volt.Elements.get("api_key_not_generated").hide();
|
|
186
|
+
volt.Elements.get("api_key_generated").show();
|
|
187
|
+
ResponseStatus.message(response.message);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
})
|
|
191
|
+
.id("api_key_not_generated"),
|
|
192
|
+
|
|
193
|
+
// API key exists.
|
|
194
|
+
FormWidget({
|
|
195
|
+
title: "API key",
|
|
196
|
+
text: "Your personal API key. An API key is only shown once.\nYou should revoke your old API key and generate an one when you have lost your API key.",
|
|
197
|
+
button: "Revoke",
|
|
198
|
+
inputs: [
|
|
199
|
+
{
|
|
200
|
+
label: "API key",
|
|
201
|
+
placeholder: "**************************************************************",
|
|
202
|
+
id: "api_key",
|
|
203
|
+
readonly: true,
|
|
204
|
+
type: volt.Input,
|
|
205
|
+
image: "/static/icons/password.webp",
|
|
206
|
+
}
|
|
207
|
+
],
|
|
208
|
+
right_top_button: true,
|
|
209
|
+
async on_submit(data) {
|
|
210
|
+
const response = await volt.User.revoke_api_key()
|
|
211
|
+
volt.Elements.get("api_key").value("");
|
|
212
|
+
volt.Elements.get("api_key_not_generated").show();
|
|
213
|
+
volt.Elements.get("api_key_generated").hide();
|
|
214
|
+
ResponseStatus.message(response.message);
|
|
215
|
+
}
|
|
216
|
+
})
|
|
217
|
+
.id("api_key_generated")
|
|
218
|
+
.hide(),
|
|
219
|
+
),
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
// Support PIN.
|
|
223
|
+
FormWidget({
|
|
224
|
+
title: "Support PIN",
|
|
225
|
+
text: "Your account's support pin to verify any support tickets.",
|
|
226
|
+
button: false,
|
|
227
|
+
inputs: [
|
|
228
|
+
{ label: "Support PIN", placeholder: "Support PIN", id: "support_pin", required: false, readonly: true, image: "/static/icons/key.webp" },
|
|
229
|
+
],
|
|
230
|
+
}),
|
|
231
|
+
)
|
|
232
|
+
)
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// ---------------------------------------------------------
|
|
238
|
+
// Build content tree mapped under Navigations module.
|
|
239
|
+
|
|
240
|
+
interface PageOptions {
|
|
241
|
+
type: "chapter" | "item",
|
|
242
|
+
title: string,
|
|
243
|
+
endpoint?: string, // only chapter type may omit this.
|
|
244
|
+
icon: string,
|
|
245
|
+
content?: () => void,
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
const Navigation: {
|
|
249
|
+
selected_name: string,
|
|
250
|
+
selected_index: number,
|
|
251
|
+
items: {
|
|
252
|
+
text: string,
|
|
253
|
+
active: boolean,
|
|
254
|
+
navigation_node?: { select(): void; },
|
|
255
|
+
content: PageOptions[],
|
|
256
|
+
on_select?: () => void,
|
|
257
|
+
}[],
|
|
258
|
+
select(index_or_name: string | number): void;
|
|
259
|
+
} = {
|
|
260
|
+
selected_name: undefined as any,
|
|
261
|
+
selected_index: undefined as any,
|
|
262
|
+
items: [
|
|
263
|
+
{
|
|
264
|
+
text: "Account",
|
|
265
|
+
active: endpoint === "/dashboard" || endpoint.includes("/dashboard/account/"),
|
|
266
|
+
content: [
|
|
267
|
+
{
|
|
268
|
+
type: "chapter",
|
|
269
|
+
title: "Account",
|
|
270
|
+
icon: "/static/icons/username.webp",
|
|
271
|
+
content: () => { }
|
|
272
|
+
},
|
|
273
|
+
AccountPage(),
|
|
274
|
+
{
|
|
275
|
+
type: "item",
|
|
276
|
+
title: "API",
|
|
277
|
+
endpoint: "/dashboard/api",
|
|
278
|
+
icon: "/static/icons/key.webp",
|
|
279
|
+
content: () => { }
|
|
280
|
+
},
|
|
281
|
+
|
|
282
|
+
{
|
|
283
|
+
type: "chapter",
|
|
284
|
+
title: "Billing",
|
|
285
|
+
icon: "/static/icons/pricing.webp",
|
|
286
|
+
content: () => { }
|
|
287
|
+
},
|
|
288
|
+
{
|
|
289
|
+
type: "item",
|
|
290
|
+
title: "Subscriptions",
|
|
291
|
+
endpoint: "/dashboard/billing",
|
|
292
|
+
icon: "/static/icons/pricing.webp",
|
|
293
|
+
content: () => { }
|
|
294
|
+
},
|
|
295
|
+
{
|
|
296
|
+
type: "item",
|
|
297
|
+
title: "Usage",
|
|
298
|
+
endpoint: "/dashboard/usage",
|
|
299
|
+
icon: "/static/icons/bar-chart.webp",
|
|
300
|
+
content: () => { }
|
|
301
|
+
},
|
|
302
|
+
|
|
303
|
+
{
|
|
304
|
+
type: "chapter",
|
|
305
|
+
title: "Customer Service",
|
|
306
|
+
icon: "/static/icons/username.webp",
|
|
307
|
+
content: () => { }
|
|
308
|
+
},
|
|
309
|
+
{
|
|
310
|
+
type: "item",
|
|
311
|
+
title: "Contact",
|
|
312
|
+
endpoint: "/dashboard/billing",
|
|
313
|
+
icon: "/static/icons/help.webp",
|
|
314
|
+
content: () => { }
|
|
315
|
+
},
|
|
316
|
+
{
|
|
317
|
+
type: "item",
|
|
318
|
+
title: "Feedback",
|
|
319
|
+
endpoint: "/dashboard/usage",
|
|
320
|
+
icon: "/static/icons/feedback.webp",
|
|
321
|
+
content: () => { }
|
|
322
|
+
},
|
|
323
|
+
|
|
324
|
+
],
|
|
325
|
+
},
|
|
326
|
+
{
|
|
327
|
+
text: "Projects",
|
|
328
|
+
active: endpoint.includes("/dashboard/project/") || endpoint.includes("/dashboard/projects/"),
|
|
329
|
+
content: [
|
|
330
|
+
{
|
|
331
|
+
type: "chapter",
|
|
332
|
+
title: "Settings",
|
|
333
|
+
icon: "/static/icons/settings.webp",
|
|
334
|
+
content: () => { }
|
|
335
|
+
},
|
|
336
|
+
{
|
|
337
|
+
type: "item",
|
|
338
|
+
title: "Roles & Permissions",
|
|
339
|
+
endpoint: "/dashboard/project/permissions",
|
|
340
|
+
icon: "/static/icons/key.webp",
|
|
341
|
+
content: () => { }
|
|
342
|
+
},
|
|
343
|
+
{
|
|
344
|
+
type: "item",
|
|
345
|
+
title: "Git Integration",
|
|
346
|
+
endpoint: "/dashboard/project/git",
|
|
347
|
+
icon: "/static/icons/github.webp",
|
|
348
|
+
content: () => { }
|
|
349
|
+
},
|
|
350
|
+
// ------------------------------------------
|
|
351
|
+
{
|
|
352
|
+
type: "chapter",
|
|
353
|
+
title: "AI",
|
|
354
|
+
icon: "/static/icons/sparkle.webp",
|
|
355
|
+
content: () => { }
|
|
356
|
+
},
|
|
357
|
+
{
|
|
358
|
+
type: "item",
|
|
359
|
+
title: "MDX Pages",
|
|
360
|
+
endpoint: "/dashboard/project/mdx",
|
|
361
|
+
icon: "/static/icons/code.webp",
|
|
362
|
+
content: () => { }
|
|
363
|
+
},
|
|
364
|
+
{
|
|
365
|
+
type: "item",
|
|
366
|
+
title: "Generated Pages",
|
|
367
|
+
endpoint: "/dashboard/project/generate",
|
|
368
|
+
icon: "/static/icons/docs.webp",
|
|
369
|
+
content: () => { }
|
|
370
|
+
},
|
|
371
|
+
// ------------------------------------------
|
|
372
|
+
{
|
|
373
|
+
type: "chapter",
|
|
374
|
+
title: "Insight",
|
|
375
|
+
icon: "/static/icons/search.webp",
|
|
376
|
+
content: () => { }
|
|
377
|
+
},
|
|
378
|
+
{
|
|
379
|
+
type: "item",
|
|
380
|
+
title: "Analytics",
|
|
381
|
+
endpoint: "/dashboard/project/analytics",
|
|
382
|
+
icon: "/static/icons/bar-chart.webp",
|
|
383
|
+
content: () => { }
|
|
384
|
+
},
|
|
385
|
+
{
|
|
386
|
+
type: "item",
|
|
387
|
+
title: "User Feedback",
|
|
388
|
+
endpoint: "/dashboard/project/feedback",
|
|
389
|
+
icon: "/static/icons/feedback.webp",
|
|
390
|
+
content: () => { }
|
|
391
|
+
},
|
|
392
|
+
],
|
|
393
|
+
on_select() {
|
|
394
|
+
const node = volt.HStack(
|
|
395
|
+
UI.SelectionPicker({
|
|
396
|
+
value: "Select Project",
|
|
397
|
+
title: "Select Project",
|
|
398
|
+
items: [],
|
|
399
|
+
})
|
|
400
|
+
.border_radius(12.5)
|
|
401
|
+
.width("initial")
|
|
402
|
+
.letter_spacing(UI.letter_spacing_1)
|
|
403
|
+
.flex(1),
|
|
404
|
+
volt.ImageMask("/static/icons/plus.webp")
|
|
405
|
+
.frame(25, 25)
|
|
406
|
+
.padding(6.5)
|
|
407
|
+
.margin_left(15)
|
|
408
|
+
.flex_shrink(0)
|
|
409
|
+
.color(Theme.fg_2)
|
|
410
|
+
.border(1, Theme.div_bg)
|
|
411
|
+
.border_radius("50%")
|
|
412
|
+
.flex_shrink(0) // wrap items in hstack instead of shrinking.
|
|
413
|
+
.transition("background 300ms ease-in-out")
|
|
414
|
+
.transition_mask("background 300ms ease-in-out")
|
|
415
|
+
.on_mouse_over_out(
|
|
416
|
+
e => e.color(Theme.fg).background(Theme.auto_darken_lighten("bg", 0.05)),
|
|
417
|
+
e => e.color(Theme.fg_2).background("transparent"),
|
|
418
|
+
)
|
|
419
|
+
)
|
|
420
|
+
.center_vertical()
|
|
421
|
+
.width("100%").overflow("hidden").wrap(false)
|
|
422
|
+
.padding(7.5, 20, 20, 20)
|
|
423
|
+
SideBar.content.insertBefore(node, SideBar.content.child(0))
|
|
424
|
+
},
|
|
425
|
+
},
|
|
426
|
+
],
|
|
427
|
+
select(index: string | number) {
|
|
428
|
+
if (typeof index === "string") {
|
|
429
|
+
const name = index;
|
|
430
|
+
for (let i = 0; i < this.items.length; i++) {
|
|
431
|
+
if (this.items[i].text === name) {
|
|
432
|
+
index = i;
|
|
433
|
+
break;
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
if (typeof index === "string") {
|
|
437
|
+
throw new Error(`Navigation "${name}" does not exist.`)
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
// Set attrs.
|
|
442
|
+
if (index >= this.items.length) {
|
|
443
|
+
throw new Error(`Invalid index ${index} max index is ${this.items.length - 1}`);
|
|
444
|
+
}
|
|
445
|
+
const item = this.items[index];
|
|
446
|
+
this.selected_name = item.text;
|
|
447
|
+
this.selected_index = index as number;
|
|
448
|
+
|
|
449
|
+
// Select active node from nav bar.
|
|
450
|
+
this.items[index]?.navigation_node?.select();
|
|
451
|
+
|
|
452
|
+
// Render sidebar content of active nav.
|
|
453
|
+
SideBar.render();
|
|
454
|
+
|
|
455
|
+
// Call on select.
|
|
456
|
+
if (typeof item.on_select === "function") {
|
|
457
|
+
item.on_select();
|
|
458
|
+
}
|
|
459
|
+
},
|
|
460
|
+
}
|
|
461
|
+
if (endpoint === "/dashboard") {
|
|
462
|
+
Navigation.selected_name = Navigation.items[0].text;
|
|
463
|
+
Navigation.selected_index = 0;
|
|
464
|
+
} else {
|
|
465
|
+
for (let i = 0; i < Navigation.items.length; i++) {
|
|
466
|
+
if (Navigation.items[i].content.find(item => endpoint === item.endpoint)){
|
|
467
|
+
Navigation.selected_name = Navigation.items[i].text;
|
|
468
|
+
Navigation.selected_index = i;
|
|
469
|
+
break;
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
if (!Navigation.selected_name) {
|
|
474
|
+
throw new Error("No navigation is selected with the current url.");
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
// ---------------------------------------------------------
|
|
478
|
+
// Core elements.
|
|
479
|
+
|
|
480
|
+
// TopBar.
|
|
481
|
+
const TopBar = (() => {
|
|
482
|
+
return volt.HStack(
|
|
483
|
+
UI.ProjectIcon(20),
|
|
484
|
+
volt.Spacer(),
|
|
485
|
+
volt.ImageMask("/static/icons/username.webp")
|
|
486
|
+
.color(Theme.fg)
|
|
487
|
+
.frame(20,20)
|
|
488
|
+
.margin_right(15),
|
|
489
|
+
volt.Frame(
|
|
490
|
+
UI.Text(volt.User.first_name())
|
|
491
|
+
.color(Theme.fg)
|
|
492
|
+
.font_size(13)
|
|
493
|
+
.margin(0, 0, 0, 0),
|
|
494
|
+
UI.Text(volt.User.email())
|
|
495
|
+
.color(Theme.fg_1)
|
|
496
|
+
.font_size(11)
|
|
497
|
+
.margin(0),
|
|
498
|
+
)
|
|
499
|
+
.width("fit-content")
|
|
500
|
+
.on_click(() => Navigation.select("Account"))
|
|
501
|
+
)
|
|
502
|
+
.center_vertical()
|
|
503
|
+
.border_bottom(1, Theme.div_bg)
|
|
504
|
+
.padding(12.5, 20)
|
|
505
|
+
})()
|
|
506
|
+
|
|
507
|
+
// Navigation bar (a second top bar below the first top bar).
|
|
508
|
+
const NavigationBar = (() => {
|
|
509
|
+
let selected_node;
|
|
510
|
+
return volt.HStack(
|
|
511
|
+
|
|
512
|
+
Navigation.items.map((item, index) => {
|
|
513
|
+
let text, divider;
|
|
514
|
+
const node = volt.VStack(
|
|
515
|
+
text = UI.Text(item.text)
|
|
516
|
+
.font_size(14)
|
|
517
|
+
.line_height("2.2em")
|
|
518
|
+
.font_weight(500)
|
|
519
|
+
.margin(0, 7.5) // to make divider larger then text.
|
|
520
|
+
.letter_spacing(UI.letter_spacing_2)
|
|
521
|
+
.transition("color 300ms ease-in-out, font-weight 500ms ease-in-out"),
|
|
522
|
+
divider = volt.Frame()
|
|
523
|
+
.position(null, 0, 0, 0)
|
|
524
|
+
.height(1.75)
|
|
525
|
+
.border_radius(0.5)
|
|
526
|
+
.transition("background 300ms ease-in-out")
|
|
527
|
+
.background("transparent"),
|
|
528
|
+
)
|
|
529
|
+
.width("fit-content")
|
|
530
|
+
.position("relative")
|
|
531
|
+
.margin_right(10)
|
|
532
|
+
.extend({
|
|
533
|
+
hover(forced = false) {
|
|
534
|
+
if (!forced && selected_node === node) return;
|
|
535
|
+
text.color(Theme.fg);
|
|
536
|
+
},
|
|
537
|
+
unhover(forced = false) {
|
|
538
|
+
if (!forced && selected_node === node) return;
|
|
539
|
+
text.color(Theme.fg_2);
|
|
540
|
+
},
|
|
541
|
+
select() {
|
|
542
|
+
if (selected_node === node) return;
|
|
543
|
+
else if (selected_node) selected_node.unselect();
|
|
544
|
+
selected_node = node;
|
|
545
|
+
this.hover(true);
|
|
546
|
+
text.font_weight(600);
|
|
547
|
+
divider.background(Theme.fg);
|
|
548
|
+
},
|
|
549
|
+
unselect() {
|
|
550
|
+
if (selected_node !== node) return;
|
|
551
|
+
selected_node = undefined;
|
|
552
|
+
this.unhover(true);
|
|
553
|
+
text.font_weight(500);
|
|
554
|
+
divider.background("transparent");
|
|
555
|
+
},
|
|
556
|
+
})
|
|
557
|
+
.on_mouse_over_out(e => e.hover(), e => e.unhover())
|
|
558
|
+
.on_click(() => index != null && Navigation.select(index))
|
|
559
|
+
if (Navigation.selected_index === index) {
|
|
560
|
+
node.select();
|
|
561
|
+
}
|
|
562
|
+
item.navigation_node = node;
|
|
563
|
+
return node;
|
|
564
|
+
}),
|
|
565
|
+
|
|
566
|
+
volt.Spacer(),
|
|
567
|
+
)
|
|
568
|
+
.center_vertical()
|
|
569
|
+
.border_bottom(1, Theme.div_bg)
|
|
570
|
+
.padding(15, 20)
|
|
571
|
+
})();
|
|
572
|
+
|
|
573
|
+
// SideBar.
|
|
574
|
+
const SideBar = (() => {
|
|
575
|
+
let selected_node: any;
|
|
576
|
+
return volt.Scroller()
|
|
577
|
+
.flex("1 1 0") // for height
|
|
578
|
+
.fixed_width(350)
|
|
579
|
+
.border_right(1, Theme.div_bg)
|
|
580
|
+
.content
|
|
581
|
+
.padding(15, 0)
|
|
582
|
+
.parent<volt.ScrollerElement>()
|
|
583
|
+
.extend({
|
|
584
|
+
render() {
|
|
585
|
+
selected_node = undefined; // reset is required.
|
|
586
|
+
const items = Navigation.items[Navigation.selected_index].content;
|
|
587
|
+
console.log("Rendering sidebar...");
|
|
588
|
+
console.log("Items:", items);
|
|
589
|
+
this.remove_children()
|
|
590
|
+
this.append(
|
|
591
|
+
items.map((item, index) => {
|
|
592
|
+
let image, text, divider;
|
|
593
|
+
const node = volt.HStack(
|
|
594
|
+
divider = item.type === "chapter" ? undefined : UI.Divider()
|
|
595
|
+
.frame(1, "100%")
|
|
596
|
+
.transition("background 300ms ease-in-out")
|
|
597
|
+
.margin(0, 23, 0, 7.5),
|
|
598
|
+
volt.HStack(
|
|
599
|
+
image = volt.ImageMask(item.icon)
|
|
600
|
+
.frame(15, 15)
|
|
601
|
+
.transition_mask("background 300ms ease-in-out")
|
|
602
|
+
.color(item.type === "chapter" ? Theme.fg : Theme.fg_1)
|
|
603
|
+
.margin_right(15)
|
|
604
|
+
.margin_bottom(4),
|
|
605
|
+
text = volt.Text(item.title)
|
|
606
|
+
.font_size(14)
|
|
607
|
+
.line_height("1.6em")
|
|
608
|
+
.font_weight(item.type === "chapter" ? 500 : 300)
|
|
609
|
+
.transition("color 300ms ease-in-out, font-weight 300ms ease-in-out")
|
|
610
|
+
.color(item.type === "chapter" ? Theme.fg : Theme.fg_1)
|
|
611
|
+
.letter_spacing(UI.letter_spacing_1)
|
|
612
|
+
.margin(0),
|
|
613
|
+
)
|
|
614
|
+
.wrap(false)
|
|
615
|
+
.center_vertical()
|
|
616
|
+
.padding(10, 0)
|
|
617
|
+
)
|
|
618
|
+
.padding(0, 20)
|
|
619
|
+
.center_vertical()
|
|
620
|
+
.transition("background 300ms ease-in-out")
|
|
621
|
+
.on_click(() => {
|
|
622
|
+
if (item.content) item.content();
|
|
623
|
+
})
|
|
624
|
+
.extend({
|
|
625
|
+
hover(forced = false) {
|
|
626
|
+
if (item.type === "chapter") { return; }
|
|
627
|
+
else if (!forced && selected_node === node) return;
|
|
628
|
+
image.color(Theme.fg);
|
|
629
|
+
// text.font_weight(400)
|
|
630
|
+
text.color(Theme.fg);
|
|
631
|
+
this.background(Theme.auto_darken_lighten("bg", 0.025))
|
|
632
|
+
if (divider) divider.background(Theme.auto_darken_lighten("bg", 0.5))
|
|
633
|
+
},
|
|
634
|
+
unhover(forced = false) {
|
|
635
|
+
if (item.type === "chapter") { return; }
|
|
636
|
+
else if (!forced && selected_node === node) return;
|
|
637
|
+
image.color(Theme.fg_2);
|
|
638
|
+
// text.font_weight(300)
|
|
639
|
+
text.color(Theme.fg_2);
|
|
640
|
+
this.background("transparent")
|
|
641
|
+
if (divider) divider.background(Theme.div_bg)
|
|
642
|
+
},
|
|
643
|
+
select() {
|
|
644
|
+
if (item.type === "chapter") { return; }
|
|
645
|
+
else if (selected_node === node) return;
|
|
646
|
+
else if (selected_node) selected_node.unselect();
|
|
647
|
+
selected_node = node;
|
|
648
|
+
this.hover(true);
|
|
649
|
+
text.font_weight(400)
|
|
650
|
+
if (divider) divider.background(Theme.fg_1)
|
|
651
|
+
},
|
|
652
|
+
unselect() {
|
|
653
|
+
if (item.type === "chapter") { return; }
|
|
654
|
+
else if (selected_node !== node) return;
|
|
655
|
+
selected_node = undefined;
|
|
656
|
+
this.unhover(true);
|
|
657
|
+
text.font_weight(300)
|
|
658
|
+
if (divider) divider.background(Theme.div_bg)
|
|
659
|
+
},
|
|
660
|
+
})
|
|
661
|
+
.on_mouse_over_out(e => e.hover(), e => e.unhover())
|
|
662
|
+
if (item.type === "chapter") {
|
|
663
|
+
node.color("#ffffff")
|
|
664
|
+
if (index > 0) {
|
|
665
|
+
node.margin_top(15)
|
|
666
|
+
}
|
|
667
|
+
} else {
|
|
668
|
+
if (endpoint === item.endpoint || (selected_node === undefined && endpoint === "/dashboard")) {
|
|
669
|
+
node.select();
|
|
670
|
+
} else {
|
|
671
|
+
node.unselect();
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
return node;
|
|
675
|
+
})
|
|
676
|
+
);
|
|
677
|
+
return this;
|
|
678
|
+
},
|
|
679
|
+
})
|
|
680
|
+
.render()
|
|
681
|
+
})();
|
|
682
|
+
|
|
683
|
+
// Actions.
|
|
684
|
+
const Actions = (() => {
|
|
685
|
+
return volt.VStack(
|
|
686
|
+
[
|
|
687
|
+
{ text: "Documentation", icon: "/static/icons/book-0.webp", href: "/docs" }
|
|
688
|
+
].map((item) => {
|
|
689
|
+
return volt.AnchorHStack<{ text: volt.TextElement, img: volt.ImageMaskElement, arrow: volt.ImageMaskElement }>(
|
|
690
|
+
volt.ImageMask(item.icon)
|
|
691
|
+
.assign_to_parent_as("img")
|
|
692
|
+
.frame(15, 15)
|
|
693
|
+
.transition_mask("background 300ms ease-in-out")
|
|
694
|
+
.color(Theme.fg_1)
|
|
695
|
+
.margin_right(15)
|
|
696
|
+
.margin_bottom(2),
|
|
697
|
+
UI.Text(item.text)
|
|
698
|
+
.assign_to_parent_as("text")
|
|
699
|
+
.font_size(14)
|
|
700
|
+
.line_height("2.2em")
|
|
701
|
+
.font_weight(500)
|
|
702
|
+
.margin(0)
|
|
703
|
+
.letter_spacing(UI.letter_spacing_2)
|
|
704
|
+
.transition("color 300ms ease-in-out, font-weight 500ms ease-in-out"),
|
|
705
|
+
volt.Spacer(),
|
|
706
|
+
UI.FoldArrow()
|
|
707
|
+
.rotate(0)
|
|
708
|
+
.assign_to_parent_as("arrow")
|
|
709
|
+
.color(Theme.fg_1)
|
|
710
|
+
.margin_left(15),
|
|
711
|
+
)
|
|
712
|
+
.position("relative")
|
|
713
|
+
.center_vertical()
|
|
714
|
+
.wrap(false)
|
|
715
|
+
.margin_right(10)
|
|
716
|
+
.href(item.href)
|
|
717
|
+
.on_mouse_over_out(
|
|
718
|
+
e => {
|
|
719
|
+
e.text.color(Theme.fg);
|
|
720
|
+
e.img.color(Theme.fg);
|
|
721
|
+
e.arrow.color(Theme.fg);
|
|
722
|
+
},
|
|
723
|
+
e => {
|
|
724
|
+
e.text.color(Theme.fg_1);
|
|
725
|
+
e.img.color(Theme.fg_1);
|
|
726
|
+
e.arrow.color(Theme.fg_1);
|
|
727
|
+
},
|
|
728
|
+
)
|
|
729
|
+
})
|
|
730
|
+
|
|
731
|
+
)
|
|
732
|
+
.flex(0)
|
|
733
|
+
.padding(10, 20)
|
|
734
|
+
.border_top(1, Theme.div_bg)
|
|
735
|
+
.border_right(1, Theme.div_bg)
|
|
736
|
+
})()
|
|
737
|
+
|
|
738
|
+
// Content.
|
|
739
|
+
const Content = (() => {
|
|
740
|
+
return volt.Scroller(
|
|
741
|
+
|
|
742
|
+
)
|
|
743
|
+
.height("100%")
|
|
744
|
+
.flex(1)
|
|
745
|
+
.background(Theme.auto_darken_lighten("bg", 0.01))
|
|
746
|
+
.content
|
|
747
|
+
.padding(20)
|
|
748
|
+
.parent<volt.ScrollerElement>()
|
|
749
|
+
})
|
|
750
|
+
|
|
751
|
+
// ---------------------------------------------------------
|
|
752
|
+
// On load.
|
|
753
|
+
|
|
754
|
+
volt.Utils.on_load(() => {
|
|
755
|
+
return UI.View(
|
|
756
|
+
|
|
757
|
+
// Topbar.
|
|
758
|
+
TopBar,
|
|
759
|
+
|
|
760
|
+
// Navigation bar.
|
|
761
|
+
NavigationBar,
|
|
762
|
+
|
|
763
|
+
// Main content.
|
|
764
|
+
volt.HStack(
|
|
765
|
+
volt.VStack(
|
|
766
|
+
SideBar,
|
|
767
|
+
Actions,
|
|
768
|
+
)
|
|
769
|
+
.frame("fit-content", "100%"),
|
|
770
|
+
Content,
|
|
771
|
+
)
|
|
772
|
+
.flex("1 1 0")
|
|
773
|
+
);
|
|
774
|
+
});
|