sh3-core 0.13.0 → 0.13.2
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/dist/BrandSlot.svelte +62 -13
- package/dist/__test__/setup-dom.js +5 -0
- package/dist/api.d.ts +3 -0
- package/dist/api.js +3 -0
- package/dist/apps/lifecycle.js +10 -2
- package/dist/apps/types.d.ts +11 -4
- package/dist/apps/workspace-rekey.d.ts +1 -0
- package/dist/apps/workspace-rekey.js +35 -0
- package/dist/apps/workspace-rekey.test.js +23 -0
- package/dist/auth/admin-users.svelte.d.ts +9 -0
- package/dist/auth/admin-users.svelte.js +42 -0
- package/dist/auth/admin-users.test.d.ts +1 -0
- package/dist/auth/admin-users.test.js +52 -0
- package/dist/createShell.js +5 -5
- package/dist/documents/config.d.ts +5 -1
- package/dist/documents/config.js +16 -8
- package/dist/documents/index.d.ts +1 -1
- package/dist/documents/index.js +1 -1
- package/dist/host-entry.d.ts +1 -1
- package/dist/host-entry.js +1 -1
- package/dist/host.d.ts +1 -1
- package/dist/host.js +8 -2
- package/dist/primitives/Button.svelte +50 -4
- package/dist/primitives/Button.svelte.d.ts +3 -1
- package/dist/primitives/Collapsible.svelte +110 -0
- package/dist/primitives/Collapsible.svelte.d.ts +14 -0
- package/dist/primitives/widgets/AppPicker.svelte +41 -0
- package/dist/primitives/widgets/AppPicker.svelte.d.ts +9 -0
- package/dist/primitives/widgets/AppPicker.svelte.test.d.ts +1 -0
- package/dist/primitives/widgets/AppPicker.svelte.test.js +26 -0
- package/dist/primitives/widgets/AppPicker.test.d.ts +1 -0
- package/dist/primitives/widgets/AppPicker.test.js +74 -0
- package/dist/primitives/widgets/ColorSwatch.svelte +7 -2
- package/dist/primitives/widgets/ColorSwatch.svelte.d.ts +2 -1
- package/dist/primitives/widgets/ColorSwatch.svelte.test.d.ts +1 -0
- package/dist/primitives/widgets/ColorSwatch.svelte.test.js +31 -0
- package/dist/primitives/widgets/Field.svelte +6 -1
- package/dist/primitives/widgets/Field.svelte.d.ts +2 -1
- package/dist/primitives/widgets/Field.svelte.test.d.ts +1 -0
- package/dist/primitives/widgets/Field.svelte.test.js +33 -0
- package/dist/primitives/widgets/FilePicker.svelte +6 -3
- package/dist/primitives/widgets/FilePicker.svelte.d.ts +2 -1
- package/dist/primitives/widgets/FilePicker.svelte.test.d.ts +1 -0
- package/dist/primitives/widgets/FilePicker.svelte.test.js +31 -0
- package/dist/primitives/widgets/IconToggleGroup.svelte +6 -3
- package/dist/primitives/widgets/IconToggleGroup.svelte.d.ts +3 -2
- package/dist/primitives/widgets/IconToggleGroup.svelte.test.d.ts +1 -0
- package/dist/primitives/widgets/IconToggleGroup.svelte.test.js +40 -0
- package/dist/primitives/widgets/NumberInput.svelte +26 -7
- package/dist/primitives/widgets/NumberInput.svelte.d.ts +2 -1
- package/dist/primitives/widgets/NumberInput.svelte.test.d.ts +1 -0
- package/dist/primitives/widgets/NumberInput.svelte.test.js +48 -0
- package/dist/primitives/widgets/PickerList.d.ts +24 -0
- package/dist/primitives/widgets/PickerList.js +21 -0
- package/dist/primitives/widgets/PickerList.svelte +150 -0
- package/dist/primitives/widgets/PickerList.svelte.d.ts +16 -0
- package/dist/primitives/widgets/PickerList.svelte.test.d.ts +1 -0
- package/dist/primitives/widgets/PickerList.svelte.test.js +31 -0
- package/dist/primitives/widgets/PickerList.test.d.ts +1 -0
- package/dist/primitives/widgets/PickerList.test.js +218 -0
- package/dist/primitives/widgets/RangeSlider.svelte +16 -5
- package/dist/primitives/widgets/RangeSlider.svelte.d.ts +2 -1
- package/dist/primitives/widgets/RangeSlider.svelte.test.d.ts +1 -0
- package/dist/primitives/widgets/RangeSlider.svelte.test.js +38 -0
- package/dist/primitives/widgets/Segmented.svelte +12 -5
- package/dist/primitives/widgets/Segmented.svelte.d.ts +3 -2
- package/dist/primitives/widgets/Segmented.svelte.test.d.ts +1 -0
- package/dist/primitives/widgets/Segmented.svelte.test.js +25 -0
- package/dist/primitives/widgets/Select.svelte +7 -3
- package/dist/primitives/widgets/Select.svelte.d.ts +3 -2
- package/dist/primitives/widgets/Select.svelte.test.d.ts +1 -0
- package/dist/primitives/widgets/Select.svelte.test.js +37 -0
- package/dist/primitives/widgets/Slider.svelte +6 -1
- package/dist/primitives/widgets/Slider.svelte.d.ts +2 -1
- package/dist/primitives/widgets/Slider.svelte.test.d.ts +1 -0
- package/dist/primitives/widgets/Slider.svelte.test.js +22 -0
- package/dist/primitives/widgets/SliderGroup.svelte +6 -1
- package/dist/primitives/widgets/SliderGroup.svelte.d.ts +2 -1
- package/dist/primitives/widgets/SliderGroup.svelte.test.d.ts +1 -0
- package/dist/primitives/widgets/SliderGroup.svelte.test.js +34 -0
- package/dist/primitives/widgets/Textarea.svelte +7 -1
- package/dist/primitives/widgets/Textarea.svelte.d.ts +2 -1
- package/dist/primitives/widgets/Textarea.svelte.test.d.ts +1 -0
- package/dist/primitives/widgets/Textarea.svelte.test.js +29 -0
- package/dist/primitives/widgets/UserPicker.svelte +53 -0
- package/dist/primitives/widgets/UserPicker.svelte.d.ts +9 -0
- package/dist/primitives/widgets/UserPicker.svelte.test.d.ts +1 -0
- package/dist/primitives/widgets/UserPicker.svelte.test.js +30 -0
- package/dist/primitives/widgets/UserPicker.test.d.ts +1 -0
- package/dist/primitives/widgets/UserPicker.test.js +115 -0
- package/dist/primitives/widgets/_contract.d.ts +27 -0
- package/dist/primitives/widgets/_contract.js +10 -0
- package/dist/projects/session-state.svelte.d.ts +17 -0
- package/dist/projects/session-state.svelte.js +39 -0
- package/dist/projects/session-state.test.d.ts +1 -0
- package/dist/projects/session-state.test.js +55 -0
- package/dist/projects-shard/DeleteProjectDialog.svelte +150 -0
- package/dist/projects-shard/DeleteProjectDialog.svelte.d.ts +12 -0
- package/dist/projects-shard/DeleteProjectDialog.test.d.ts +1 -0
- package/dist/projects-shard/DeleteProjectDialog.test.js +120 -0
- package/dist/projects-shard/ProjectManage.svelte +209 -0
- package/dist/projects-shard/ProjectManage.svelte.d.ts +8 -0
- package/dist/projects-shard/ProjectsSection.svelte +120 -0
- package/dist/projects-shard/ProjectsSection.svelte.d.ts +3 -0
- package/dist/projects-shard/index.d.ts +4 -0
- package/dist/projects-shard/index.js +4 -0
- package/dist/projects-shard/projectsApi.d.ts +20 -0
- package/dist/projects-shard/projectsApi.js +44 -0
- package/dist/projects-shard/projectsApi.test.d.ts +1 -0
- package/dist/projects-shard/projectsApi.test.js +71 -0
- package/dist/projects-shard/projectsShard.svelte.d.ts +10 -0
- package/dist/projects-shard/projectsShard.svelte.js +148 -0
- package/dist/sh3core-shard/ShellHome.svelte +19 -1
- package/dist/shards/activate-scopeid.test.d.ts +1 -0
- package/dist/shards/{activate-tenantid.test.js → activate-scopeid.test.js} +6 -6
- package/dist/tokens.css +4 -2
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
- /package/dist/{shards/activate-tenantid.test.d.ts → apps/workspace-rekey.test.d.ts} +0 -0
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* `__projects__` shard — multi-member project scope module.
|
|
3
|
+
*
|
|
4
|
+
* Maintains a reactive list of projects the current user is a member of.
|
|
5
|
+
* Refreshes on activate and on visibility-change so a project created in
|
|
6
|
+
* one tab appears in another after it regains focus. Registers admin-only
|
|
7
|
+
* actions that open the ProjectManage float view (create/edit/delete).
|
|
8
|
+
*/
|
|
9
|
+
import { mount, unmount } from 'svelte';
|
|
10
|
+
import { projectsApi } from './projectsApi';
|
|
11
|
+
import { VERSION } from '../version';
|
|
12
|
+
import ProjectManage from './ProjectManage.svelte';
|
|
13
|
+
import { floatManager } from '../overlays/float';
|
|
14
|
+
import { isAdmin } from '../auth/auth.svelte';
|
|
15
|
+
export const projectsState = $state({ projects: [], loading: false, error: null });
|
|
16
|
+
export async function refreshProjects() {
|
|
17
|
+
projectsState.loading = true;
|
|
18
|
+
projectsState.error = null;
|
|
19
|
+
try {
|
|
20
|
+
projectsState.projects = await projectsApi.list();
|
|
21
|
+
}
|
|
22
|
+
catch (e) {
|
|
23
|
+
projectsState.error = e.message;
|
|
24
|
+
}
|
|
25
|
+
finally {
|
|
26
|
+
projectsState.loading = false;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
const PROJECTS_MANAGE_VIEW = 'projects:manage';
|
|
30
|
+
/*
|
|
31
|
+
* The float manager drops `meta` for `dismissable: true` (per the bare
|
|
32
|
+
* SlotNode wrapper in float.ts). Edit-mode needs to know which project
|
|
33
|
+
* to load, so we stash the target on a module-level slot the factory
|
|
34
|
+
* consumes on mount. Cleared after the factory has read it so a later
|
|
35
|
+
* Create from the palette can't accidentally inherit a previous edit
|
|
36
|
+
* target.
|
|
37
|
+
*/
|
|
38
|
+
let pendingTarget = null;
|
|
39
|
+
function consumePendingTarget() {
|
|
40
|
+
const t = pendingTarget;
|
|
41
|
+
pendingTarget = null;
|
|
42
|
+
return t;
|
|
43
|
+
}
|
|
44
|
+
export function openProjectManage(project) {
|
|
45
|
+
pendingTarget = project;
|
|
46
|
+
floatManager.open(PROJECTS_MANAGE_VIEW, {
|
|
47
|
+
title: project ? `Edit ${project.name}` : 'Create Project',
|
|
48
|
+
size: { w: 560, h: 620 },
|
|
49
|
+
dismissable: true,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
export const projectsShard = {
|
|
53
|
+
manifest: {
|
|
54
|
+
id: '__projects__',
|
|
55
|
+
label: 'Projects',
|
|
56
|
+
version: VERSION,
|
|
57
|
+
views: [{ id: PROJECTS_MANAGE_VIEW, label: 'Project Manager' }],
|
|
58
|
+
},
|
|
59
|
+
activate(ctx) {
|
|
60
|
+
void refreshProjects();
|
|
61
|
+
if (typeof document !== 'undefined') {
|
|
62
|
+
document.addEventListener('visibilitychange', () => {
|
|
63
|
+
if (document.visibilityState === 'visible')
|
|
64
|
+
void refreshProjects();
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
const factory = {
|
|
68
|
+
mount(container, _mountCtx) {
|
|
69
|
+
const project = consumePendingTarget();
|
|
70
|
+
// The float manager has already pushed an entry for this mount —
|
|
71
|
+
// the most recent one whose viewId matches us is ours.
|
|
72
|
+
const list = floatManager.list();
|
|
73
|
+
const floatId = list.length > 0 ? list[list.length - 1].id : null;
|
|
74
|
+
const close = () => {
|
|
75
|
+
if (floatId)
|
|
76
|
+
floatManager.close(floatId);
|
|
77
|
+
};
|
|
78
|
+
const instance = mount(ProjectManage, {
|
|
79
|
+
target: container,
|
|
80
|
+
props: { project, onClose: close },
|
|
81
|
+
});
|
|
82
|
+
return {
|
|
83
|
+
unmount() {
|
|
84
|
+
unmount(instance);
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
ctx.registerView(PROJECTS_MANAGE_VIEW, factory);
|
|
90
|
+
ctx.actions.register({
|
|
91
|
+
id: 'sh3.project.create',
|
|
92
|
+
label: 'Create Project…',
|
|
93
|
+
scope: ['home', 'app'],
|
|
94
|
+
paletteItem: true,
|
|
95
|
+
disabled: () => !isAdmin(),
|
|
96
|
+
run: () => {
|
|
97
|
+
if (isAdmin())
|
|
98
|
+
openProjectManage(null);
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
ctx.actions.register({
|
|
102
|
+
id: 'sh3.project.manage',
|
|
103
|
+
label: 'Manage Project…',
|
|
104
|
+
scope: ['home', 'app'],
|
|
105
|
+
submenu: true,
|
|
106
|
+
paletteItem: true,
|
|
107
|
+
disabled: () => !isAdmin(),
|
|
108
|
+
});
|
|
109
|
+
// Dynamic children: one per project in projectsState.projects, kept in
|
|
110
|
+
// sync as projects are created/deleted. Mirrors the sh3.app.launch
|
|
111
|
+
// pattern in sh3coreShard.
|
|
112
|
+
const manageUnregisters = new Map();
|
|
113
|
+
$effect.root(() => {
|
|
114
|
+
$effect(() => {
|
|
115
|
+
const currentIds = new Set();
|
|
116
|
+
for (const project of projectsState.projects) {
|
|
117
|
+
currentIds.add(project.id);
|
|
118
|
+
if (manageUnregisters.has(project.id))
|
|
119
|
+
continue;
|
|
120
|
+
const off = ctx.actions.register({
|
|
121
|
+
id: `sh3.project.manage:${project.id}`,
|
|
122
|
+
label: project.name,
|
|
123
|
+
scope: ['home', 'app'],
|
|
124
|
+
submenuOf: 'sh3.project.manage',
|
|
125
|
+
run: () => {
|
|
126
|
+
// Re-read the live record so renames since registration are
|
|
127
|
+
// reflected in the form.
|
|
128
|
+
const live = projectsState.projects.find((p) => p.id === project.id);
|
|
129
|
+
if (live)
|
|
130
|
+
openProjectManage(live);
|
|
131
|
+
},
|
|
132
|
+
});
|
|
133
|
+
manageUnregisters.set(project.id, off);
|
|
134
|
+
}
|
|
135
|
+
for (const id of [...manageUnregisters.keys()]) {
|
|
136
|
+
if (!currentIds.has(id)) {
|
|
137
|
+
manageUnregisters.get(id)();
|
|
138
|
+
manageUnregisters.delete(id);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
},
|
|
144
|
+
autostart() {
|
|
145
|
+
/* register on the self-starting path so the project list is available
|
|
146
|
+
on the home screen without an app launch. */
|
|
147
|
+
},
|
|
148
|
+
};
|
|
@@ -9,19 +9,35 @@
|
|
|
9
9
|
|
|
10
10
|
import { listRegisteredApps, launchApp, isAdmin, VERSION } from '../api';
|
|
11
11
|
import ShellTitle from './ShellTitle.svelte';
|
|
12
|
+
import ProjectsSection from '../projects-shard/ProjectsSection.svelte';
|
|
13
|
+
import { sessionState } from '../projects/session-state.svelte';
|
|
14
|
+
import { projectsState } from '../projects-shard/projectsShard.svelte';
|
|
12
15
|
|
|
13
16
|
let filter = $state('');
|
|
14
17
|
|
|
15
18
|
const apps = $derived(listRegisteredApps());
|
|
16
19
|
const elevated = $derived(isAdmin());
|
|
17
20
|
|
|
21
|
+
const activeProject = $derived(
|
|
22
|
+
sessionState.activeProjectId
|
|
23
|
+
? projectsState.projects.find((p) => p.id === sessionState.activeProjectId) ?? null
|
|
24
|
+
: null,
|
|
25
|
+
);
|
|
26
|
+
|
|
18
27
|
function matches(m: { id: string; label: string }, q: string): boolean {
|
|
19
28
|
if (!q) return true;
|
|
20
29
|
const needle = q.toLowerCase();
|
|
21
30
|
return m.label.toLowerCase().includes(needle) || m.id.toLowerCase().includes(needle);
|
|
22
31
|
}
|
|
23
32
|
|
|
24
|
-
|
|
33
|
+
function inAllowlist(appId: string): boolean {
|
|
34
|
+
if (!activeProject) return true;
|
|
35
|
+
return activeProject.appAllowlist.includes(appId);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const userApps = $derived(
|
|
39
|
+
apps.filter((m) => !m.admin && matches(m, filter) && inAllowlist(m.id)),
|
|
40
|
+
);
|
|
25
41
|
const adminApps = $derived(apps.filter((m) => m.admin && matches(m, filter)));
|
|
26
42
|
const totalVisible = $derived(userApps.length + (elevated ? adminApps.length : 0));
|
|
27
43
|
</script>
|
|
@@ -48,6 +64,8 @@
|
|
|
48
64
|
/>
|
|
49
65
|
</div>
|
|
50
66
|
|
|
67
|
+
<ProjectsSection />
|
|
68
|
+
|
|
51
69
|
{#if userApps.length > 0}
|
|
52
70
|
<section class="shell-home-section">
|
|
53
71
|
<h2 class="shell-home-section-title">Apps</h2>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
import { describe, it, expect, beforeEach } from 'vitest';
|
|
2
2
|
import { MemoryDocumentBackend } from '../documents/backends';
|
|
3
|
-
import { __setDocumentBackend,
|
|
3
|
+
import { __setDocumentBackend, __setActiveScope } from '../documents/config';
|
|
4
4
|
import { registerShard, activateShard, __resetShardRegistryForTest } from './activate.svelte';
|
|
5
|
-
describe('ctx.tenantId', () => {
|
|
5
|
+
describe('ctx.tenantId reflects active scope', () => {
|
|
6
6
|
beforeEach(() => {
|
|
7
7
|
__resetShardRegistryForTest();
|
|
8
8
|
__setDocumentBackend(new MemoryDocumentBackend());
|
|
9
|
-
|
|
9
|
+
__setActiveScope('scope-a');
|
|
10
10
|
});
|
|
11
11
|
it('is present unconditionally on ctx', async () => {
|
|
12
12
|
let captured = null;
|
|
13
13
|
const shard = {
|
|
14
|
-
manifest: { id: 'test-
|
|
14
|
+
manifest: { id: 'test-scopeid', label: 't', version: '0.0.0', views: [] },
|
|
15
15
|
activate(ctx) { captured = ctx; },
|
|
16
16
|
};
|
|
17
17
|
registerShard(shard);
|
|
18
|
-
await activateShard('test-
|
|
19
|
-
expect(captured.tenantId).toBe('
|
|
18
|
+
await activateShard('test-scopeid');
|
|
19
|
+
expect(captured.tenantId).toBe('scope-a');
|
|
20
20
|
});
|
|
21
21
|
});
|
package/dist/tokens.css
CHANGED
|
@@ -99,8 +99,10 @@
|
|
|
99
99
|
--shell-track-border: var(--shell-border);
|
|
100
100
|
--shell-track-fill: var(--shell-accent);
|
|
101
101
|
|
|
102
|
-
/* Slider thumbs
|
|
103
|
-
|
|
102
|
+
/* Slider thumbs — pinned to a fixed near-white instead of var(--shell-fg)
|
|
103
|
+
so light themes don't render a dark thumb. Themes that want a different
|
|
104
|
+
thumb override --shell-thumb-bg directly. */
|
|
105
|
+
--shell-thumb-bg: #e4e6eb;
|
|
104
106
|
--shell-thumb-border: var(--shell-accent);
|
|
105
107
|
--shell-thumb-shadow: var(--shell-shadow-sm);
|
|
106
108
|
|
package/dist/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/** Auto-generated from package.json — do not edit manually. */
|
|
2
|
-
export declare const VERSION = "0.13.
|
|
2
|
+
export declare const VERSION = "0.13.2";
|
package/dist/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/** Auto-generated from package.json — do not edit manually. */
|
|
2
|
-
export const VERSION = '0.13.
|
|
2
|
+
export const VERSION = '0.13.2';
|
package/package.json
CHANGED
|
File without changes
|