@kennofizet/apphub-frontend 0.1.0
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/README.md +84 -0
- package/package.json +31 -0
- package/src/api/coreApi.js +25 -0
- package/src/api/index.js +80 -0
- package/src/composables/createZoneContext.js +156 -0
- package/src/composables/useAppHubHostApi.js +24 -0
- package/src/composables/useAppHubZoneContext.js +11 -0
- package/src/composables/useDevOriginToggle.js +40 -0
- package/src/i18n/index.js +16 -0
- package/src/i18n/resolveLang.js +6 -0
- package/src/i18n/resolveTheme.js +30 -0
- package/src/i18n/translations/en.js +303 -0
- package/src/i18n/translations/vi.js +302 -0
- package/src/index.js +427 -0
- package/src/moduleStore.js +10 -0
- package/src/modules/app-store/components/AppHubAppStoreApp.vue +210 -0
- package/src/modules/app-store/components/AppHubAppStoreCard.vue +88 -0
- package/src/modules/app-store/components/AppHubAppStoreSettingsPanel.vue +266 -0
- package/src/modules/app-store/components/AppHubAppVersionHistory.vue +77 -0
- package/src/modules/app-store/components/AppHubDevReviewPanel.vue +206 -0
- package/src/modules/app-store/components/AppHubDraftStoreApp.vue +184 -0
- package/src/modules/app-store/components/AppHubDraftStoreCard.vue +116 -0
- package/src/modules/app-store/composables/useAppStore.js +206 -0
- package/src/modules/app-store/composables/useCatalogInfiniteScroll.js +47 -0
- package/src/modules/app-store/constants/catalogModes.js +2 -0
- package/src/modules/app-store/data/defaultCatalog.js +19 -0
- package/src/modules/app-store/index.js +9 -0
- package/src/modules/app-store/utils/normalizeCatalogApp.js +37 -0
- package/src/modules/desktop/components/AppHubDesktop.vue +1510 -0
- package/src/modules/desktop/components/AppHubDesktopDevOriginBar.vue +57 -0
- package/src/modules/desktop/components/AppHubDesktopDropLayer.vue +15 -0
- package/src/modules/desktop/components/AppHubDesktopDropTarget.vue +32 -0
- package/src/modules/desktop/components/AppHubDesktopIconContextMenu.vue +74 -0
- package/src/modules/desktop/components/AppHubDesktopIconFolder.vue +60 -0
- package/src/modules/desktop/components/AppHubDesktopIconGroup.vue +58 -0
- package/src/modules/desktop/components/AppHubDesktopIconInfoDialog.vue +33 -0
- package/src/modules/desktop/components/AppHubDesktopIconRenameDialog.vue +62 -0
- package/src/modules/desktop/components/AppHubDesktopSettings.vue +28 -0
- package/src/modules/desktop/components/AppHubDropInstallBadge.vue +65 -0
- package/src/modules/desktop/components/AppHubDuplicateAppDialog.vue +38 -0
- package/src/modules/desktop/components/AppHubGuideApp.vue +278 -0
- package/src/modules/desktop/components/AppHubOriginBlockScreen.vue +105 -0
- package/src/modules/desktop/components/AppHubOriginLoadingScreen.vue +23 -0
- package/src/modules/desktop/components/AppHubPlaceholderApp.vue +14 -0
- package/src/modules/desktop/components/AppHubSettingsApp.vue +319 -0
- package/src/modules/desktop/components/AppHubStartButton.vue +24 -0
- package/src/modules/desktop/components/AppHubStartMenu.vue +182 -0
- package/src/modules/desktop/components/AppHubTaskbarPins.vue +23 -0
- package/src/modules/desktop/components/settings/AppHubSettingsKeyboardPanel.vue +82 -0
- package/src/modules/desktop/components/settings/AppHubSettingsScreenPanel.vue +41 -0
- package/src/modules/desktop/components/settings/AppHubSettingsStartMenuPanel.vue +95 -0
- package/src/modules/desktop/composables/simulateInstallProgress.js +15 -0
- package/src/modules/desktop/composables/useDesktopDropInstall.js +272 -0
- package/src/modules/desktop/composables/useDesktopHubSettings.js +51 -0
- package/src/modules/desktop/composables/useDesktopIconDrag.js +207 -0
- package/src/modules/desktop/composables/useDesktopShell.js +335 -0
- package/src/modules/desktop/data/builtinApps.js +77 -0
- package/src/modules/desktop/index.js +12 -0
- package/src/modules/desktop/styles/desktop.css +3104 -0
- package/src/modules/desktop/styles/theme.css +616 -0
- package/src/modules/desktop/utils/desktopGrid.js +43 -0
- package/src/modules/desktop/utils/desktopIconGroups.js +103 -0
- package/src/modules/desktop/utils/desktopSession.js +40 -0
- package/src/modules/desktop/utils/desktopSettings.js +37 -0
- package/src/modules/desktop/utils/dropPackageParser.js +140 -0
- package/src/modules/desktop/utils/duplicateAppUtils.js +28 -0
- package/src/modules/desktop/utils/hubKeyboardSettings.js +63 -0
- package/src/modules/desktop/utils/recentApps.js +148 -0
- package/src/modules/desktop/utils/startMenuFavorites.js +100 -0
- package/src/modules/desktop/utils/startMenuPins.js +90 -0
- package/src/modules/notifications/components/AppHubDesktopNotifications.vue +54 -0
- package/src/modules/notifications/composables/createDesktopNotifications.js +86 -0
- package/src/modules/notifications/index.js +9 -0
- package/src/modules/notifications/styles/notifications.css +118 -0
- package/src/modules/notifications/utils/parseApiError.js +29 -0
- package/src/modules/runner/components/AppHubRunner.vue +292 -0
- package/src/modules/runner/index.js +1 -0
- package/src/modules/window-manager/components/AppHubWindowFrame.vue +224 -0
- package/src/modules/window-manager/composables/useWindowManager.js +652 -0
- package/src/modules/window-manager/index.js +7 -0
- package/src/modules/window-manager/utils/sessionLayout.js +28 -0
- package/src/modules/window-manager/utils/windowLayout.js +236 -0
- package/src/modules/window-manager/utils/windowSnap.js +146 -0
- package/src/utils/bootstrapCache.js +47 -0
- package/src/utils/devOriginSettings.js +22 -0
- package/src/utils/launchUrl.js +111 -0
- package/src/utils/originSafety.js +267 -0
- package/src/utils/safeStorage.js +191 -0
- package/src/utils/semver.js +30 -0
- package/src/utils/zoneContext.js +38 -0
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="apphub-guide">
|
|
3
|
+
<header class="apphub-guide__header">
|
|
4
|
+
<h2 class="apphub-guide__title">{{ labels.title }}</h2>
|
|
5
|
+
<p class="apphub-guide__subtitle">{{ labels.subtitle }}</p>
|
|
6
|
+
</header>
|
|
7
|
+
|
|
8
|
+
<nav class="apphub-guide__tabs" role="tablist">
|
|
9
|
+
<button
|
|
10
|
+
type="button"
|
|
11
|
+
role="tab"
|
|
12
|
+
class="apphub-guide__tab"
|
|
13
|
+
:class="{ 'apphub-guide__tab--active': tab === 'user' }"
|
|
14
|
+
:aria-selected="tab === 'user'"
|
|
15
|
+
@click="tab = 'user'"
|
|
16
|
+
>
|
|
17
|
+
{{ labels.tab_user }}
|
|
18
|
+
</button>
|
|
19
|
+
<button
|
|
20
|
+
type="button"
|
|
21
|
+
role="tab"
|
|
22
|
+
class="apphub-guide__tab"
|
|
23
|
+
:class="{ 'apphub-guide__tab--active': tab === 'dev' }"
|
|
24
|
+
:aria-selected="tab === 'dev'"
|
|
25
|
+
@click="tab = 'dev'"
|
|
26
|
+
>
|
|
27
|
+
{{ labels.tab_dev }}
|
|
28
|
+
</button>
|
|
29
|
+
</nav>
|
|
30
|
+
|
|
31
|
+
<div class="apphub-guide__body">
|
|
32
|
+
<article v-show="tab === 'user'" class="apphub-guide__article">
|
|
33
|
+
<section v-for="block in userSections" :key="block.title" class="apphub-guide__section">
|
|
34
|
+
<h3>{{ block.title }}</h3>
|
|
35
|
+
<ul>
|
|
36
|
+
<li v-for="(line, i) in block.lines" :key="i">{{ line }}</li>
|
|
37
|
+
</ul>
|
|
38
|
+
</section>
|
|
39
|
+
</article>
|
|
40
|
+
|
|
41
|
+
<article v-show="tab === 'dev'" class="apphub-guide__article">
|
|
42
|
+
<section v-for="block in devSections" :key="block.title" class="apphub-guide__section">
|
|
43
|
+
<h3>{{ block.title }}</h3>
|
|
44
|
+
<ul v-if="block.lines?.length">
|
|
45
|
+
<li v-for="(line, i) in block.lines" :key="i">{{ line }}</li>
|
|
46
|
+
</ul>
|
|
47
|
+
<pre v-if="block.code" class="apphub-guide__code"><code>{{ block.code }}</code></pre>
|
|
48
|
+
</section>
|
|
49
|
+
</article>
|
|
50
|
+
</div>
|
|
51
|
+
</div>
|
|
52
|
+
</template>
|
|
53
|
+
|
|
54
|
+
<script setup>
|
|
55
|
+
import { computed, inject, ref } from 'vue'
|
|
56
|
+
import { resolveLang } from '../../../i18n/resolveLang.js'
|
|
57
|
+
import { t } from '../../../i18n/index.js'
|
|
58
|
+
|
|
59
|
+
const tab = ref('user')
|
|
60
|
+
const lang = computed(() => resolveLang(inject('apphubOptions', {})?.language, 'vi'))
|
|
61
|
+
|
|
62
|
+
const labels = computed(() => ({
|
|
63
|
+
title: t('guide_app_title', lang.value),
|
|
64
|
+
subtitle: t('guide_app_subtitle', lang.value),
|
|
65
|
+
tab_user: t('guide_tab_user', lang.value),
|
|
66
|
+
tab_dev: t('guide_tab_dev', lang.value),
|
|
67
|
+
}))
|
|
68
|
+
|
|
69
|
+
const userSections = computed(() => [
|
|
70
|
+
{
|
|
71
|
+
title: t('guide_user_welcome_title', lang.value),
|
|
72
|
+
lines: [
|
|
73
|
+
t('guide_user_welcome_1', lang.value),
|
|
74
|
+
t('guide_user_welcome_2', lang.value),
|
|
75
|
+
],
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
title: t('guide_user_desktop_title', lang.value),
|
|
79
|
+
lines: [
|
|
80
|
+
t('guide_user_desktop_1', lang.value),
|
|
81
|
+
t('guide_user_desktop_2', lang.value),
|
|
82
|
+
t('guide_user_desktop_3', lang.value),
|
|
83
|
+
],
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
title: t('guide_user_windows_title', lang.value),
|
|
87
|
+
lines: [
|
|
88
|
+
t('guide_user_windows_1', lang.value),
|
|
89
|
+
t('guide_user_windows_2', lang.value),
|
|
90
|
+
t('guide_user_windows_3', lang.value),
|
|
91
|
+
],
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
title: t('guide_user_install_title', lang.value),
|
|
95
|
+
lines: [
|
|
96
|
+
t('guide_user_install_1', lang.value),
|
|
97
|
+
t('guide_user_install_2', lang.value),
|
|
98
|
+
t('guide_user_install_3', lang.value),
|
|
99
|
+
],
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
title: t('guide_user_start_title', lang.value),
|
|
103
|
+
lines: [
|
|
104
|
+
t('guide_user_start_1', lang.value),
|
|
105
|
+
t('guide_user_start_2', lang.value),
|
|
106
|
+
],
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
title: t('guide_user_tips_title', lang.value),
|
|
110
|
+
lines: [
|
|
111
|
+
t('guide_user_tips_1', lang.value),
|
|
112
|
+
t('guide_user_tips_2', lang.value),
|
|
113
|
+
t('guide_user_tips_3', lang.value),
|
|
114
|
+
],
|
|
115
|
+
},
|
|
116
|
+
])
|
|
117
|
+
|
|
118
|
+
const devSections = computed(() => [
|
|
119
|
+
{
|
|
120
|
+
title: t('guide_dev_who_title', lang.value),
|
|
121
|
+
lines: [
|
|
122
|
+
t('guide_dev_who_1', lang.value),
|
|
123
|
+
t('guide_dev_who_2', lang.value),
|
|
124
|
+
],
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
title: t('guide_dev_bridge_title', lang.value),
|
|
128
|
+
lines: [
|
|
129
|
+
t('guide_dev_bridge_1', lang.value),
|
|
130
|
+
t('guide_dev_bridge_2', lang.value),
|
|
131
|
+
t('guide_dev_bridge_3', lang.value),
|
|
132
|
+
],
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
title: t('guide_dev_permissions_title', lang.value),
|
|
136
|
+
lines: [
|
|
137
|
+
t('guide_dev_permissions_1', lang.value),
|
|
138
|
+
t('guide_dev_permissions_2', lang.value),
|
|
139
|
+
t('guide_dev_permissions_3', lang.value),
|
|
140
|
+
t('guide_dev_permissions_4', lang.value),
|
|
141
|
+
],
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
title: t('guide_dev_bridge_code_title', lang.value),
|
|
145
|
+
code: t('guide_dev_bridge_code', lang.value),
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
title: t('guide_dev_user_title', lang.value),
|
|
149
|
+
lines: [
|
|
150
|
+
t('guide_dev_user_1', lang.value),
|
|
151
|
+
t('guide_dev_user_2', lang.value),
|
|
152
|
+
t('guide_dev_user_3', lang.value),
|
|
153
|
+
],
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
title: t('guide_dev_desktop_title', lang.value),
|
|
157
|
+
lines: [
|
|
158
|
+
t('guide_dev_desktop_1', lang.value),
|
|
159
|
+
t('guide_dev_desktop_2', lang.value),
|
|
160
|
+
t('guide_dev_desktop_3', lang.value),
|
|
161
|
+
],
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
title: t('guide_dev_deploy_title', lang.value),
|
|
165
|
+
lines: [
|
|
166
|
+
t('guide_dev_deploy_1', lang.value),
|
|
167
|
+
t('guide_dev_deploy_2', lang.value),
|
|
168
|
+
],
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
title: t('guide_dev_docs_title', lang.value),
|
|
172
|
+
lines: [
|
|
173
|
+
t('guide_dev_docs_1', lang.value),
|
|
174
|
+
t('guide_dev_docs_2', lang.value),
|
|
175
|
+
t('guide_dev_docs_3', lang.value),
|
|
176
|
+
],
|
|
177
|
+
},
|
|
178
|
+
])
|
|
179
|
+
</script>
|
|
180
|
+
|
|
181
|
+
<style scoped>
|
|
182
|
+
.apphub-guide {
|
|
183
|
+
display: flex;
|
|
184
|
+
flex-direction: column;
|
|
185
|
+
height: 100%;
|
|
186
|
+
min-height: 0;
|
|
187
|
+
color: var(--ah-text-secondary, #cbd5e1);
|
|
188
|
+
background: var(--ah-surface, #1e293b);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
.apphub-guide__header {
|
|
192
|
+
padding: 20px 24px 12px;
|
|
193
|
+
border-bottom: 1px solid var(--ah-border-subtle, rgba(255, 255, 255, 0.08));
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
.apphub-guide__title {
|
|
197
|
+
margin: 0;
|
|
198
|
+
font-size: 1.35rem;
|
|
199
|
+
color: var(--ah-text, #f0f4fc);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
.apphub-guide__subtitle {
|
|
203
|
+
margin: 6px 0 0;
|
|
204
|
+
font-size: 0.88rem;
|
|
205
|
+
color: var(--ah-text-muted, #94a3b8);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
.apphub-guide__tabs {
|
|
209
|
+
display: flex;
|
|
210
|
+
gap: 4px;
|
|
211
|
+
padding: 10px 16px;
|
|
212
|
+
border-bottom: 1px solid var(--ah-border-subtle, rgba(255, 255, 255, 0.08));
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
.apphub-guide__tab {
|
|
216
|
+
padding: 8px 16px;
|
|
217
|
+
border: 1px solid transparent;
|
|
218
|
+
border-radius: 6px;
|
|
219
|
+
background: transparent;
|
|
220
|
+
color: var(--ah-text-muted, #94a3b8);
|
|
221
|
+
font-size: 0.85rem;
|
|
222
|
+
font-weight: 600;
|
|
223
|
+
cursor: pointer;
|
|
224
|
+
transition: background 0.15s ease, color 0.15s ease;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
.apphub-guide__tab:hover {
|
|
228
|
+
background: var(--ah-hover, rgba(255, 255, 255, 0.08));
|
|
229
|
+
color: var(--ah-text, #f0f4fc);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
.apphub-guide__tab--active {
|
|
233
|
+
background: var(--ah-hover-strong, rgba(255, 255, 255, 0.12));
|
|
234
|
+
border-color: var(--ah-border, rgba(255, 255, 255, 0.1));
|
|
235
|
+
color: var(--ah-text, #f0f4fc);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
.apphub-guide__body {
|
|
239
|
+
flex: 1;
|
|
240
|
+
overflow-y: auto;
|
|
241
|
+
padding: 16px 24px 24px;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
.apphub-guide__section {
|
|
245
|
+
margin-bottom: 22px;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
.apphub-guide__section h3 {
|
|
249
|
+
margin: 0 0 10px;
|
|
250
|
+
font-size: 1rem;
|
|
251
|
+
color: var(--ah-text, #f0f4fc);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
.apphub-guide__section ul {
|
|
255
|
+
margin: 0;
|
|
256
|
+
padding-left: 1.25rem;
|
|
257
|
+
line-height: 1.55;
|
|
258
|
+
font-size: 0.875rem;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
.apphub-guide__section li {
|
|
262
|
+
margin-bottom: 6px;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
.apphub-guide__code {
|
|
266
|
+
margin: 10px 0 0;
|
|
267
|
+
padding: 12px 14px;
|
|
268
|
+
border-radius: 6px;
|
|
269
|
+
background: var(--ah-hover, rgba(0, 0, 0, 0.25));
|
|
270
|
+
border: 1px solid var(--ah-border-subtle, rgba(255, 255, 255, 0.08));
|
|
271
|
+
overflow-x: auto;
|
|
272
|
+
font-size: 0.78rem;
|
|
273
|
+
line-height: 1.5;
|
|
274
|
+
color: var(--ah-text, #e2e8f0);
|
|
275
|
+
white-space: pre-wrap;
|
|
276
|
+
word-break: break-word;
|
|
277
|
+
}
|
|
278
|
+
</style>
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="apphub-origin-block" role="alert">
|
|
3
|
+
<div class="apphub-origin-block__panel">
|
|
4
|
+
<span class="apphub-origin-block__icon" aria-hidden="true">🛡️</span>
|
|
5
|
+
<h1 class="apphub-origin-block__title">{{ labels.title }}</h1>
|
|
6
|
+
<p class="apphub-origin-block__message">{{ message }}</p>
|
|
7
|
+
<p class="apphub-origin-block__hint">{{ labels.hint }}</p>
|
|
8
|
+
<dl v-if="showOrigins" class="apphub-origin-block__dl">
|
|
9
|
+
<div class="apphub-origin-block__row">
|
|
10
|
+
<dt>{{ labels.current_origin }}</dt>
|
|
11
|
+
<dd>{{ currentOrigin }}</dd>
|
|
12
|
+
</div>
|
|
13
|
+
<div v-if="expectedHubOrigin" class="apphub-origin-block__row">
|
|
14
|
+
<dt>{{ labels.expected_hub_origin }}</dt>
|
|
15
|
+
<dd>{{ expectedHubOrigin }}</dd>
|
|
16
|
+
</div>
|
|
17
|
+
<div v-if="expectedRuntimeOrigin" class="apphub-origin-block__row">
|
|
18
|
+
<dt>{{ labels.expected_runtime_origin }}</dt>
|
|
19
|
+
<dd>{{ expectedRuntimeOrigin }}</dd>
|
|
20
|
+
</div>
|
|
21
|
+
<div v-if="parentOrigin" class="apphub-origin-block__row">
|
|
22
|
+
<dt>{{ labels.parent_origin }}</dt>
|
|
23
|
+
<dd>{{ parentOrigin }}</dd>
|
|
24
|
+
</div>
|
|
25
|
+
</dl>
|
|
26
|
+
|
|
27
|
+
<div v-if="devOriginVisible" class="apphub-origin-block__dev">
|
|
28
|
+
<p class="apphub-origin-block__dev-title">{{ devOriginLabels.title }}</p>
|
|
29
|
+
<p class="apphub-origin-block__dev-status">
|
|
30
|
+
{{ devFriendlyOn ? devOriginLabels.status_relaxed : devOriginLabels.status_strict }}
|
|
31
|
+
</p>
|
|
32
|
+
<button type="button" class="apphub-origin-block__dev-btn" @click="toggleDevOrigin">
|
|
33
|
+
{{ devFriendlyOn ? devOriginLabels.action_enable_strict : devOriginLabels.action_enable_relaxed }}
|
|
34
|
+
</button>
|
|
35
|
+
</div>
|
|
36
|
+
</div>
|
|
37
|
+
</div>
|
|
38
|
+
</template>
|
|
39
|
+
|
|
40
|
+
<script setup>
|
|
41
|
+
import { computed, inject } from 'vue'
|
|
42
|
+
import { t } from '../../../i18n/index.js'
|
|
43
|
+
import { resolveLang } from '../../../i18n/resolveLang.js'
|
|
44
|
+
import { useDevOriginToggle } from '../../../composables/useDevOriginToggle.js'
|
|
45
|
+
import {
|
|
46
|
+
ORIGIN_UNSAFE_NOT_CONFIGURED,
|
|
47
|
+
ORIGIN_UNSAFE_RUNTIME_NOT_CONFIGURED,
|
|
48
|
+
ORIGIN_UNSAFE_RUNTIME_SAME_ORIGIN,
|
|
49
|
+
ORIGIN_UNSAFE_SAME_ORIGIN_EMBED,
|
|
50
|
+
ORIGIN_UNSAFE_WRONG_ORIGIN,
|
|
51
|
+
} from '../../../utils/originSafety.js'
|
|
52
|
+
|
|
53
|
+
const props = defineProps({
|
|
54
|
+
reason: { type: String, default: null },
|
|
55
|
+
parentOrigin: { type: String, default: null },
|
|
56
|
+
expectedHubOrigin: { type: String, default: null },
|
|
57
|
+
expectedRuntimeOrigin: { type: String, default: null },
|
|
58
|
+
labels: { type: Object, required: true },
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
const moduleOptions = inject('apphubOptions', {})
|
|
62
|
+
const lang = computed(() => resolveLang(moduleOptions?.language, 'vi'))
|
|
63
|
+
const { visible: devOriginVisible, devFriendlyOn, toggle: toggleDevOrigin } = useDevOriginToggle()
|
|
64
|
+
|
|
65
|
+
const devOriginLabels = computed(() => ({
|
|
66
|
+
title: t('dev_origin_bar_title', lang.value),
|
|
67
|
+
status_relaxed: t('dev_origin_status_relaxed', lang.value),
|
|
68
|
+
status_strict: t('dev_origin_status_strict', lang.value),
|
|
69
|
+
action_enable_strict: t('dev_origin_action_strict', lang.value),
|
|
70
|
+
action_enable_relaxed: t('dev_origin_action_relaxed', lang.value),
|
|
71
|
+
}))
|
|
72
|
+
|
|
73
|
+
const currentOrigin = computed(() => {
|
|
74
|
+
if (typeof window === 'undefined') return ''
|
|
75
|
+
return window.location.origin
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
const message = computed(() => {
|
|
79
|
+
if (props.reason === ORIGIN_UNSAFE_SAME_ORIGIN_EMBED) {
|
|
80
|
+
return props.labels.same_origin_embed
|
|
81
|
+
}
|
|
82
|
+
if (props.reason === ORIGIN_UNSAFE_NOT_CONFIGURED) {
|
|
83
|
+
return props.labels.not_configured
|
|
84
|
+
}
|
|
85
|
+
if (props.reason === ORIGIN_UNSAFE_WRONG_ORIGIN) {
|
|
86
|
+
return props.labels.wrong_origin
|
|
87
|
+
}
|
|
88
|
+
if (props.reason === ORIGIN_UNSAFE_RUNTIME_NOT_CONFIGURED) {
|
|
89
|
+
return props.labels.runtime_not_configured
|
|
90
|
+
}
|
|
91
|
+
if (props.reason === ORIGIN_UNSAFE_RUNTIME_SAME_ORIGIN) {
|
|
92
|
+
return props.labels.runtime_same_origin
|
|
93
|
+
}
|
|
94
|
+
return props.labels.generic
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
const showOrigins = computed(() =>
|
|
98
|
+
Boolean(
|
|
99
|
+
currentOrigin.value
|
|
100
|
+
|| props.parentOrigin
|
|
101
|
+
|| props.expectedHubOrigin
|
|
102
|
+
|| props.expectedRuntimeOrigin,
|
|
103
|
+
),
|
|
104
|
+
)
|
|
105
|
+
</script>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="apphub-origin-loading" role="status" aria-live="polite">
|
|
3
|
+
<div class="apphub-origin-loading__panel">
|
|
4
|
+
<div class="apphub-origin-loading__spinner" aria-hidden="true" />
|
|
5
|
+
<p class="apphub-origin-loading__title">{{ labels.title }}</p>
|
|
6
|
+
<p class="apphub-origin-loading__hint">{{ labels.hint }}</p>
|
|
7
|
+
</div>
|
|
8
|
+
</div>
|
|
9
|
+
</template>
|
|
10
|
+
|
|
11
|
+
<script setup>
|
|
12
|
+
import { computed, inject } from 'vue'
|
|
13
|
+
import { t } from '../../../i18n/index.js'
|
|
14
|
+
import { resolveLang } from '../../../i18n/resolveLang.js'
|
|
15
|
+
|
|
16
|
+
const moduleOptions = inject('apphubOptions', {})
|
|
17
|
+
const lang = computed(() => resolveLang(moduleOptions?.language, 'vi'))
|
|
18
|
+
|
|
19
|
+
const labels = computed(() => ({
|
|
20
|
+
title: t('origin_loading_title', lang.value),
|
|
21
|
+
hint: t('origin_loading_hint', lang.value),
|
|
22
|
+
}))
|
|
23
|
+
</script>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="apphub-placeholder">
|
|
3
|
+
<p class="apphub-placeholder__icon">{{ icon }}</p>
|
|
4
|
+
<h3>{{ title }}</h3>
|
|
5
|
+
<p class="apphub-placeholder__hint">Demo app shell — connect backend launch URL later.</p>
|
|
6
|
+
</div>
|
|
7
|
+
</template>
|
|
8
|
+
|
|
9
|
+
<script setup>
|
|
10
|
+
defineProps({
|
|
11
|
+
title: { type: String, default: 'App' },
|
|
12
|
+
icon: { type: String, default: '📦' },
|
|
13
|
+
})
|
|
14
|
+
</script>
|