@synopackageland/templates 0.9.2 → 0.9.4
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 +1 -1
- package/package.json +1 -1
- package/templates/native-go/backend/THIRD_PARTY_NOTICES.txt +1 -1
- package/templates/native-go/backend/go.mod +1 -1
- package/templates/native-go/backend/go.sum +2 -2
- package/templates/native-go-vue/README.md +4 -0
- package/templates/native-go-vue/frontend/DESIGN.md +2 -0
- package/templates/native-go-vue/frontend/package-lock.json +4 -4
- package/templates/native-go-vue/frontend/package.json +1 -1
- package/templates/native-go-vue/frontend/src/App.vue +5 -1
- package/templates/native-go-vue/frontend/test/apps.test.ts +37 -0
package/README.md
CHANGED
|
@@ -21,7 +21,7 @@ An overlay may replace `internal/app/*_none.go` (the CLI deletes the matching
|
|
|
21
21
|
The placeholders `__PACKAGE__` (also the Go module path), `__DISPLAY_NAME__` and
|
|
22
22
|
`__BACKGROUND_ENABLED__` are substituted by `init`.
|
|
23
23
|
|
|
24
|
-
`backend/go.mod` requires `github.com/synopackageland/syno-pkg-land-sdk v0.9.
|
|
24
|
+
`backend/go.mod` requires `github.com/synopackageland/syno-pkg-land-sdk v0.9.5`; that line is
|
|
25
25
|
the single source of the SDK version and `frontend/package.json` pins
|
|
26
26
|
`@synopackageland/sdk` to the same version.
|
|
27
27
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@synopackageland/templates",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.4",
|
|
4
4
|
"description": "Project templates for synopkgland init: native-go (plain or Vue, with jobs, delegate and root-ops overlays), binary and compose.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {"type": "git", "url": "git+https://github.com/synopackageland/syno-pkg-land-templates.git"},
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
github.com/synopackageland/syno-pkg-land-sdk v0.9.
|
|
2
|
-
github.com/synopackageland/syno-pkg-land-sdk v0.9.
|
|
1
|
+
github.com/synopackageland/syno-pkg-land-sdk v0.9.5 h1:Kab3TVny+Zqqy7tzp5YqT1ZdcUhzVtH0uL3uu58wPXo=
|
|
2
|
+
github.com/synopackageland/syno-pkg-land-sdk v0.9.5/go.mod h1:JNoqISvR4biA9IuLi0CFe4c272tsKzCN9Nyj71nrXsQ=
|
|
3
3
|
golang.org/x/sys v0.44.0 h1:ildZl3J4uzeKP07r2F++Op7E9B29JRUy+a27EibtBTQ=
|
|
4
4
|
golang.org/x/sys v0.44.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
|
@@ -37,6 +37,10 @@ Use the installed `@synopackageland/ui`; package.json pins its version.
|
|
|
37
37
|
`AppLayout wide-layout="window"` keeps the DSM shell in window mode even when
|
|
38
38
|
maximized. Only whole-page web/Portal apps should opt into document scope or
|
|
39
39
|
`wide-layout="web"`. The DSM host sets the 700px minimum window width.
|
|
40
|
+
In a DSM window (`ctx.host.platform().host === 'dsm'`) `AppRoot` takes
|
|
41
|
+
`dialog-bounds="viewport"`, so Dialogs can be dragged out of the window, and
|
|
42
|
+
its `activate` event calls `ctx.host.activateWindow()` to bring the window to
|
|
43
|
+
the front. Elsewhere Dialogs stay inside the App.
|
|
40
44
|
Import `themes/dsm7-embedded.css` and assign each mount a unique
|
|
41
45
|
`app.config.idPrefix` before mounting.
|
|
42
46
|
|
|
@@ -36,6 +36,8 @@ editor; the root overlay adds its existing fixed-operation authorization gate.
|
|
|
36
36
|
Use the installed `@synopackageland/ui` controls and `themes/dsm7-embedded.css`.
|
|
37
37
|
The theme owns colors, typography, spacing and dialogs. Keep per-app modal scope,
|
|
38
38
|
a unique Vue ID prefix and vertical scrolling at the DSM minimum window size.
|
|
39
|
+
In a DSM window, Dialogs may leave the window (`dialog-bounds="viewport"`) and a
|
|
40
|
+
press on one brings the window to the front; below 600px they are bottom sheets.
|
|
39
41
|
|
|
40
42
|
Refresh and save expose busy state and localized errors. Reopen refreshes status.
|
|
41
43
|
Each mount owns its state; unmount unsubscribes from host events and ignores late
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"name": "native-dsm-vue-app",
|
|
8
8
|
"dependencies": {
|
|
9
9
|
"@lucide/vue": "1.48.0",
|
|
10
|
-
"@synopackageland/sdk": "0.9.
|
|
10
|
+
"@synopackageland/sdk": "0.9.5",
|
|
11
11
|
"@synopackageland/ui": "0.9.1",
|
|
12
12
|
"vue": "3.5.43"
|
|
13
13
|
},
|
|
@@ -1148,9 +1148,9 @@
|
|
|
1148
1148
|
}
|
|
1149
1149
|
},
|
|
1150
1150
|
"node_modules/@synopackageland/sdk": {
|
|
1151
|
-
"version": "0.9.
|
|
1152
|
-
"resolved": "https://registry.npmjs.org/@synopackageland/sdk/-/sdk-0.9.
|
|
1153
|
-
"integrity": "sha512-
|
|
1151
|
+
"version": "0.9.5",
|
|
1152
|
+
"resolved": "https://registry.npmjs.org/@synopackageland/sdk/-/sdk-0.9.5.tgz",
|
|
1153
|
+
"integrity": "sha512-ikBQthpwj9EvpagykdY2WVCjrN1yXBgReQzrnljfggdsOqd8TRk9eUMF2rgY62oARZx0P1fxIRAzkSUBGS1Qgw==",
|
|
1154
1154
|
"license": "MIT",
|
|
1155
1155
|
"peerDependencies": {
|
|
1156
1156
|
"@lucide/vue": "^1.48.0",
|
|
@@ -17,6 +17,10 @@ let disposed = false
|
|
|
17
17
|
let unsubscribe: (() => void) | undefined
|
|
18
18
|
// The CLI substitutes this only for a declared package-account background worker.
|
|
19
19
|
const backgroundEnabled = (('__BACKGROUND_ENABLED__') as string) === 'true'
|
|
20
|
+
// In a DSM window, dialogs may leave the window as DSM's own do; a press on one
|
|
21
|
+
// does not reach the window, so it brings the window to the front itself.
|
|
22
|
+
const inDsmWindow = props.ctx.host?.platform().host === 'dsm'
|
|
23
|
+
function toFront() {props.ctx.host.activateWindow()}
|
|
20
24
|
const page = ref<ShellPage>('status')
|
|
21
25
|
const pages = computed(() => shellPages({background:backgroundEnabled}))
|
|
22
26
|
const subtitle = computed(() => app.value ? `${app.value.package} · ${app.value.user} · ${app.value.version}` : undefined)
|
|
@@ -64,7 +68,7 @@ onUnmounted(()=>{disposed=true;unsubscribe?.();login.dispose();text.value=''})
|
|
|
64
68
|
</script>
|
|
65
69
|
|
|
66
70
|
<template>
|
|
67
|
-
<AppRoot modal-scope="app" style="height: 100%">
|
|
71
|
+
<AppRoot modal-scope="app" :dialog-bounds="inDsmWindow ? 'viewport' : 'app'" style="height: 100%" @activate="toFront">
|
|
68
72
|
<ConfigProvider :locale="uiLocale(ctx.locale)">
|
|
69
73
|
<LoginPage v-if="login.ready.value && login.enabled.value && !login.subject.value" :session="login" :locale="ctx.locale" />
|
|
70
74
|
<AppShell v-else v-model="page" :locale="ctx.locale" :pages="pages" :description="subtitle">
|
|
@@ -92,3 +92,40 @@ test('a status request that raced the session check is retried once the session
|
|
|
92
92
|
expect(root.textContent).toContain('Raced · admin · 1')
|
|
93
93
|
}finally{app.unmount();root.remove()}
|
|
94
94
|
})
|
|
95
|
+
function hosted(host?:'dsm'|'standalone-web'){
|
|
96
|
+
const call=vi.fn(async(method:string)=>{
|
|
97
|
+
if(method==='app.status')return {package:'Hosted',version:'1',user:'admin',admin:false}
|
|
98
|
+
throw {code:'unknown_method'}
|
|
99
|
+
})
|
|
100
|
+
const activateWindow=vi.fn(()=>({status:'requested'}))
|
|
101
|
+
const ctx={locale:'en',call,reopen(){return ()=>{}},...(host?{host:{platform:()=>({host}),activateWindow}}:{})} as unknown as Context
|
|
102
|
+
const root=document.createElement('div');document.body.append(root)
|
|
103
|
+
const app=mount(root,ctx)
|
|
104
|
+
return {activateWindow,close(){app.unmount();root.remove()}}
|
|
105
|
+
}
|
|
106
|
+
test('in a DSM window dialogs may leave the window, and pressing one brings the window to the front',async()=>{
|
|
107
|
+
const f=hosted('dsm')
|
|
108
|
+
try{
|
|
109
|
+
await settle()
|
|
110
|
+
const floating=document.querySelector<HTMLElement>('[data-ui-floating]')
|
|
111
|
+
expect(floating).not.toBeNull()
|
|
112
|
+
floating!.dispatchEvent(new Event('pointerdown'))
|
|
113
|
+
expect(f.activateWindow).toHaveBeenCalledOnce()
|
|
114
|
+
}finally{f.close()}
|
|
115
|
+
expect(document.querySelector('[data-ui-floating]')).toBeNull()
|
|
116
|
+
})
|
|
117
|
+
test('on a narrow viewport the floating dialogs become sheets that stay on screen',async()=>{
|
|
118
|
+
const width=window.innerWidth
|
|
119
|
+
Object.defineProperty(window,'innerWidth',{configurable:true,value:390})
|
|
120
|
+
const f=hosted('dsm')
|
|
121
|
+
try{
|
|
122
|
+
await settle()
|
|
123
|
+
expect(document.querySelector('[data-ui-floating]')?.getAttribute('data-ui-presentation')).toBe('mobile')
|
|
124
|
+
}finally{f.close();Object.defineProperty(window,'innerWidth',{configurable:true,value:width})}
|
|
125
|
+
})
|
|
126
|
+
test('outside a DSM window dialogs stay inside the app',async()=>{
|
|
127
|
+
for(const host of [undefined,'standalone-web'] as const){
|
|
128
|
+
const f=hosted(host)
|
|
129
|
+
try{await settle();expect(document.querySelector('[data-ui-floating]')).toBeNull()}finally{f.close()}
|
|
130
|
+
}
|
|
131
|
+
})
|