@jskit-ai/workspaces-core 0.1.224 → 0.1.225
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/package.json +9 -9
- package/patterns/workspace-server/PATTERN.md +6 -0
- package/src/server/WorkspacesFeature.js +18 -1
- package/src/server/common/services/workspaceContextService.js +3 -1
- package/src/server/workspaceSettings/workspaceSettingsRepository.js +11 -29
- package/src/shared/resources/workspaceSettingsResource.js +7 -12
- package/src/shared/settings.js +12 -0
- package/src/shared/tenancyProfile.js +3 -2
- package/test/featureRuntime.test.js +13 -1
- package/test/tenancyProfile.test.js +16 -0
- package/test/workspaceService.test.js +28 -0
- package/test/workspaceSettingsRepository.test.js +19 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jskit-ai/workspaces-core",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.225",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test": "node --test --test-concurrency=1"
|
|
@@ -18,11 +18,11 @@
|
|
|
18
18
|
"./shared/resources/workspaceSettingsResource": "./src/shared/resources/workspaceSettingsResource.js"
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@jskit-ai/database-runtime": "0.1.
|
|
22
|
-
"@jskit-ai/json-rest-api-core": "0.1.
|
|
23
|
-
"@jskit-ai/resource-core": "0.1.
|
|
24
|
-
"@jskit-ai/resource-crud-core": "0.1.
|
|
25
|
-
"@jskit-ai/users-core": "0.1.
|
|
21
|
+
"@jskit-ai/database-runtime": "0.1.247",
|
|
22
|
+
"@jskit-ai/json-rest-api-core": "0.1.191",
|
|
23
|
+
"@jskit-ai/resource-core": "0.1.189",
|
|
24
|
+
"@jskit-ai/resource-crud-core": "0.1.189",
|
|
25
|
+
"@jskit-ai/users-core": "0.1.260",
|
|
26
26
|
"json-rest-schema": "^1.0.17"
|
|
27
27
|
},
|
|
28
28
|
"description": "Workspace tenancy runtime plus HTTP routes, role catalog, and workspace config scaffolding.",
|
|
@@ -169,8 +169,8 @@
|
|
|
169
169
|
}
|
|
170
170
|
},
|
|
171
171
|
"peerDependencies": {
|
|
172
|
-
"@jskit-ai/auth-core": "0.1.
|
|
173
|
-
"@jskit-ai/http-runtime": "0.1.
|
|
174
|
-
"@jskit-ai/kernel": "0.1.
|
|
172
|
+
"@jskit-ai/auth-core": "0.1.245",
|
|
173
|
+
"@jskit-ai/http-runtime": "0.1.245",
|
|
174
|
+
"@jskit-ai/kernel": "0.1.247"
|
|
175
175
|
}
|
|
176
176
|
}
|
|
@@ -23,6 +23,12 @@ substitute for a simpler domain ownership column.
|
|
|
23
23
|
Choose workspace creation policy, roles, invitation policy, expiry, email copy,
|
|
24
24
|
member permissions, personal-workspace behavior, and surface access rules.
|
|
25
25
|
|
|
26
|
+
In `workspaces` mode, `tenancyPolicy.workspace.autoProvision: true` gives every
|
|
27
|
+
user a personal workspace in addition to shared ones; the server config function
|
|
28
|
+
`personalWorkspaceName(user)` names it. `workspaceSettings.defaults` sets
|
|
29
|
+
`invitesEnabled` and the colours (`lightPrimaryColor`, `darkPrimaryColor` and
|
|
30
|
+
the other palette fields) that new workspaces start with.
|
|
31
|
+
|
|
26
32
|
## Framework APIs
|
|
27
33
|
|
|
28
34
|
Use workspace routes, resources, scope helpers, tenancy profiles, and settings
|
|
@@ -9,6 +9,7 @@ import { workspaceMembershipsResource } from "../shared/resources/workspaceMembe
|
|
|
9
9
|
import { workspaceResource } from "../shared/resources/workspaceResource.js";
|
|
10
10
|
import { workspaceSettingsResource } from "../shared/resources/workspaceSettingsResource.js";
|
|
11
11
|
import { createWorkspaceRoleCatalog } from "../shared/roles.js";
|
|
12
|
+
import { WORKSPACE_SETTINGS_COLOR_FIELDS, normalizeWorkspaceHexColor } from "../shared/settings.js";
|
|
12
13
|
import { resolveTenancyProfile } from "../shared/tenancyProfile.js";
|
|
13
14
|
import { createRepository as createWorkspaceInvitesRepository } from "./common/repositories/workspaceInvitesRepository.js";
|
|
14
15
|
import { createRepository as createWorkspaceMembershipsRepository } from "./common/repositories/workspaceMembershipsRepository.js";
|
|
@@ -49,6 +50,21 @@ function requireBoolean(value, label) {
|
|
|
49
50
|
return value;
|
|
50
51
|
}
|
|
51
52
|
|
|
53
|
+
function requireWorkspaceColorDefaults(defaults) {
|
|
54
|
+
const colors = {};
|
|
55
|
+
for (const fieldName of WORKSPACE_SETTINGS_COLOR_FIELDS) {
|
|
56
|
+
if (defaults?.[fieldName] === undefined) {
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
const color = normalizeWorkspaceHexColor(defaults[fieldName]);
|
|
60
|
+
if (!color) {
|
|
61
|
+
throw new TypeError(`runtime.config.workspaceSettings.defaults.${fieldName} must be a hex color like #1867C0.`);
|
|
62
|
+
}
|
|
63
|
+
colors[fieldName] = color;
|
|
64
|
+
}
|
|
65
|
+
return colors;
|
|
66
|
+
}
|
|
67
|
+
|
|
52
68
|
function resolveInviteEmailTemplate(config) {
|
|
53
69
|
const template =
|
|
54
70
|
config.workspaceInviteEmailTemplate ||
|
|
@@ -92,7 +108,8 @@ function createWorkspacesRuntime({ config, env, jsonRestApi } = {}) {
|
|
|
92
108
|
defaultInvitesEnabled: requireBoolean(
|
|
93
109
|
config?.workspaceSettings?.defaults?.invitesEnabled,
|
|
94
110
|
"runtime.config.workspaceSettings.defaults.invitesEnabled"
|
|
95
|
-
)
|
|
111
|
+
),
|
|
112
|
+
defaultColorSettings: requireWorkspaceColorDefaults(config?.workspaceSettings?.defaults)
|
|
96
113
|
});
|
|
97
114
|
const workspacesRepository = createWorkspacesRepository({ api: jsonRestApi });
|
|
98
115
|
const workspaceMembershipsRepository = createWorkspaceMembershipsRepository({ api: jsonRestApi });
|
|
@@ -84,6 +84,8 @@ function createService({
|
|
|
84
84
|
const resolvedTenancyProfile = resolveTenancyProfile(appConfig);
|
|
85
85
|
const resolvedTenancyMode = resolvedTenancyProfile.mode;
|
|
86
86
|
const workspacePolicy = resolvedTenancyProfile.workspace;
|
|
87
|
+
const personalWorkspaceName =
|
|
88
|
+
typeof appConfig.personalWorkspaceName === "function" ? appConfig.personalWorkspaceName : null;
|
|
87
89
|
async function ensureUniqueWorkspaceSlug(baseSlug, options = {}) {
|
|
88
90
|
let suffix = 0;
|
|
89
91
|
while (suffix < 1000) {
|
|
@@ -121,7 +123,7 @@ function createService({
|
|
|
121
123
|
const inserted = await workspacesRepository.insert(
|
|
122
124
|
{
|
|
123
125
|
slug,
|
|
124
|
-
name: buildWorkspaceName(user),
|
|
126
|
+
name: normalizeText(personalWorkspaceName?.(user)) || buildWorkspaceName(user),
|
|
125
127
|
ownerUserId: normalizedUserId,
|
|
126
128
|
isPersonal: true,
|
|
127
129
|
avatarUrl: ""
|
|
@@ -6,34 +6,12 @@ import {
|
|
|
6
6
|
createJsonRestContext,
|
|
7
7
|
extractJsonRestCollectionRows
|
|
8
8
|
} from "@jskit-ai/json-rest-api-core/server/jsonRestApiHost";
|
|
9
|
+
import { pickOwnProperties } from "@jskit-ai/kernel/shared/support";
|
|
10
|
+
import { WORKSPACE_SETTINGS_FIELD_KEYS } from "../../shared/resources/workspaceSettingsResource.js";
|
|
9
11
|
import { resolveWorkspaceThemePalettes } from "../../shared/settings.js";
|
|
10
12
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
"lightSecondaryColor",
|
|
14
|
-
"lightSurfaceColor",
|
|
15
|
-
"lightSurfaceVariantColor",
|
|
16
|
-
"darkPrimaryColor",
|
|
17
|
-
"darkSecondaryColor",
|
|
18
|
-
"darkSurfaceColor",
|
|
19
|
-
"darkSurfaceVariantColor",
|
|
20
|
-
"invitesEnabled"
|
|
21
|
-
]);
|
|
22
|
-
|
|
23
|
-
function pickPatchFields(source = {}) {
|
|
24
|
-
const patch = {};
|
|
25
|
-
|
|
26
|
-
for (const fieldName of WORKSPACE_SETTINGS_PATCH_FIELDS) {
|
|
27
|
-
if (Object.hasOwn(source, fieldName)) {
|
|
28
|
-
patch[fieldName] = source[fieldName];
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
return patch;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
function createDefaultWorkspaceSettingsCreatePayload(workspaceId, defaultInvitesEnabled) {
|
|
36
|
-
const palettes = resolveWorkspaceThemePalettes({});
|
|
13
|
+
function createDefaultWorkspaceSettingsCreatePayload(workspaceId, defaultInvitesEnabled, defaultColorSettings = {}) {
|
|
14
|
+
const palettes = resolveWorkspaceThemePalettes(defaultColorSettings);
|
|
37
15
|
|
|
38
16
|
return {
|
|
39
17
|
id: workspaceId,
|
|
@@ -49,7 +27,7 @@ function createDefaultWorkspaceSettingsCreatePayload(workspaceId, defaultInvites
|
|
|
49
27
|
};
|
|
50
28
|
}
|
|
51
29
|
|
|
52
|
-
function createRepository({ api, defaultInvitesEnabled = true } = {}) {
|
|
30
|
+
function createRepository({ api, defaultInvitesEnabled = true, defaultColorSettings = {} } = {}) {
|
|
53
31
|
if (!api?.resources?.workspaceSettings) {
|
|
54
32
|
throw new TypeError("workspaceSettingsRepository requires json-rest-api workspaceSettings resource.");
|
|
55
33
|
}
|
|
@@ -95,7 +73,11 @@ function createRepository({ api, defaultInvitesEnabled = true } = {}) {
|
|
|
95
73
|
try {
|
|
96
74
|
await api.resources.workspaceSettings.post(
|
|
97
75
|
{
|
|
98
|
-
data: createDefaultWorkspaceSettingsCreatePayload(
|
|
76
|
+
data: createDefaultWorkspaceSettingsCreatePayload(
|
|
77
|
+
normalizedWorkspaceId,
|
|
78
|
+
defaultInvitesEnabled === true,
|
|
79
|
+
defaultColorSettings
|
|
80
|
+
),
|
|
99
81
|
format: "plain",
|
|
100
82
|
returning: "full",
|
|
101
83
|
transaction: options?.trx || null
|
|
@@ -119,7 +101,7 @@ function createRepository({ api, defaultInvitesEnabled = true } = {}) {
|
|
|
119
101
|
|
|
120
102
|
await ensureForWorkspaceId(normalizedWorkspaceId, options);
|
|
121
103
|
const source = patch && typeof patch === "object" && !Array.isArray(patch) ? patch : {};
|
|
122
|
-
const updatePayload =
|
|
104
|
+
const updatePayload = pickOwnProperties(source, WORKSPACE_SETTINGS_FIELD_KEYS);
|
|
123
105
|
|
|
124
106
|
if (Object.keys(updatePayload).length < 1) {
|
|
125
107
|
return findByWorkspaceId(normalizedWorkspaceId, options);
|
|
@@ -3,19 +3,14 @@ import { deepFreeze } from "@jskit-ai/kernel/shared/support/deepFreeze";
|
|
|
3
3
|
import { RECORD_ID_PATTERN } from "@jskit-ai/kernel/shared/validators";
|
|
4
4
|
import { defineCrudResource } from "@jskit-ai/resource-crud-core/shared/crudResource";
|
|
5
5
|
import { workspaceRoleCatalogSchema } from "./workspaceRoleCatalogSchema.js";
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
normalizeWorkspaceHexColor,
|
|
8
|
+
DEFAULT_WORKSPACE_DARK_PALETTE,
|
|
9
|
+
DEFAULT_WORKSPACE_LIGHT_PALETTE,
|
|
10
|
+
WORKSPACE_SETTINGS_COLOR_FIELDS
|
|
11
|
+
} from "../settings.js";
|
|
7
12
|
|
|
8
|
-
const WORKSPACE_SETTINGS_FIELD_KEYS = deepFreeze([
|
|
9
|
-
"lightPrimaryColor",
|
|
10
|
-
"lightSecondaryColor",
|
|
11
|
-
"lightSurfaceColor",
|
|
12
|
-
"lightSurfaceVariantColor",
|
|
13
|
-
"darkPrimaryColor",
|
|
14
|
-
"darkSecondaryColor",
|
|
15
|
-
"darkSurfaceColor",
|
|
16
|
-
"darkSurfaceVariantColor",
|
|
17
|
-
"invitesEnabled"
|
|
18
|
-
]);
|
|
13
|
+
const WORKSPACE_SETTINGS_FIELD_KEYS = deepFreeze([...WORKSPACE_SETTINGS_COLOR_FIELDS, "invitesEnabled"]);
|
|
19
14
|
|
|
20
15
|
const workspaceSettingsBodySchema = createSchema({
|
|
21
16
|
lightPrimaryColor: {
|
package/src/shared/settings.js
CHANGED
|
@@ -18,6 +18,17 @@ const DEFAULT_WORKSPACE_DARK_PALETTE = Object.freeze({
|
|
|
18
18
|
|
|
19
19
|
const DEFAULT_WORKSPACE_COLOR = DEFAULT_WORKSPACE_LIGHT_PALETTE.color;
|
|
20
20
|
|
|
21
|
+
const WORKSPACE_SETTINGS_COLOR_FIELDS = Object.freeze([
|
|
22
|
+
"lightPrimaryColor",
|
|
23
|
+
"lightSecondaryColor",
|
|
24
|
+
"lightSurfaceColor",
|
|
25
|
+
"lightSurfaceVariantColor",
|
|
26
|
+
"darkPrimaryColor",
|
|
27
|
+
"darkSecondaryColor",
|
|
28
|
+
"darkSurfaceColor",
|
|
29
|
+
"darkSurfaceVariantColor"
|
|
30
|
+
]);
|
|
31
|
+
|
|
21
32
|
function normalizeWorkspaceHexColor(value) {
|
|
22
33
|
const normalized = String(value || "").trim();
|
|
23
34
|
if (!HEX_COLOR_PATTERN.test(normalized)) {
|
|
@@ -113,6 +124,7 @@ export {
|
|
|
113
124
|
normalizeWorkspaceThemeMode,
|
|
114
125
|
resolveWorkspaceThemeDefaultPalette,
|
|
115
126
|
resolveWorkspaceThemePalettes,
|
|
127
|
+
WORKSPACE_SETTINGS_COLOR_FIELDS,
|
|
116
128
|
WORKSPACE_THEME_MODE_DARK,
|
|
117
129
|
WORKSPACE_THEME_MODE_LIGHT,
|
|
118
130
|
resolveWorkspaceThemePalette
|
|
@@ -15,7 +15,8 @@ function resolveWorkspacePolicyOverrides(appConfig = {}) {
|
|
|
15
15
|
const workspacePolicy = isRecord(tenancyPolicy.workspace) ? tenancyPolicy.workspace : {};
|
|
16
16
|
|
|
17
17
|
return Object.freeze({
|
|
18
|
-
allowSelfCreate: typeof workspacePolicy.allowSelfCreate === "boolean" ? workspacePolicy.allowSelfCreate : null
|
|
18
|
+
allowSelfCreate: typeof workspacePolicy.allowSelfCreate === "boolean" ? workspacePolicy.allowSelfCreate : null,
|
|
19
|
+
autoProvision: typeof workspacePolicy.autoProvision === "boolean" ? workspacePolicy.autoProvision : null
|
|
19
20
|
});
|
|
20
21
|
}
|
|
21
22
|
|
|
@@ -40,7 +41,7 @@ function resolveWorkspacePolicy(mode, overrides = {}) {
|
|
|
40
41
|
|
|
41
42
|
return Object.freeze({
|
|
42
43
|
enabled: true,
|
|
43
|
-
autoProvision:
|
|
44
|
+
autoProvision: overrides.autoProvision === true,
|
|
44
45
|
allowSelfCreate: overrides.allowSelfCreate === true,
|
|
45
46
|
slugPolicy: WORKSPACE_SLUG_POLICY_USER_SELECTED
|
|
46
47
|
});
|
|
@@ -5,7 +5,7 @@ import { createActionProvider } from "@jskit-ai/kernel/server/actions";
|
|
|
5
5
|
import { createCapabilityRuntime, defineProvider } from "@jskit-ai/kernel/shared/capabilities";
|
|
6
6
|
import { createBootstrapRuntime } from "@jskit-ai/kernel/server/runtime";
|
|
7
7
|
import { createUsersExtensions } from "@jskit-ai/users-core/server/usersExtensions";
|
|
8
|
-
import { WorkspacesFeature } from "../src/server/WorkspacesFeature.js";
|
|
8
|
+
import { WorkspacesFeature, createWorkspacesRuntime } from "../src/server/WorkspacesFeature.js";
|
|
9
9
|
import { WorkspacesIntegrationsProvider } from "../src/server/WorkspacesIntegrationsProvider.js";
|
|
10
10
|
|
|
11
11
|
function createJsonRestApiFixture() {
|
|
@@ -157,3 +157,15 @@ test("workspace realtime audiences are the actor's active memberships", async ()
|
|
|
157
157
|
{ kind: "workspace_user", workspaceId: "12", userId: "9" }
|
|
158
158
|
]);
|
|
159
159
|
});
|
|
160
|
+
|
|
161
|
+
test("workspace settings color defaults must be hex colors", () => {
|
|
162
|
+
const config = runtimeConfig();
|
|
163
|
+
config.workspaceSettings.defaults.lightPrimaryColor = "charcoal";
|
|
164
|
+
const jsonRestApi = createJsonRestApiFixture();
|
|
165
|
+
jsonRestApi.resources.workspaceSettings = {};
|
|
166
|
+
|
|
167
|
+
assert.throws(
|
|
168
|
+
() => createWorkspacesRuntime({ config, env: {}, jsonRestApi }),
|
|
169
|
+
/runtime\.config\.workspaceSettings\.defaults\.lightPrimaryColor must be a hex color/
|
|
170
|
+
);
|
|
171
|
+
});
|
|
@@ -65,3 +65,19 @@ test("resolveTenancyProfile allows explicit workspace self-create policy overrid
|
|
|
65
65
|
assert.equal(workspaceProfile.mode, TENANCY_MODE_WORKSPACES);
|
|
66
66
|
assert.equal(workspaceProfile.workspace.allowSelfCreate, true);
|
|
67
67
|
});
|
|
68
|
+
|
|
69
|
+
test("resolveTenancyProfile lets workspace mode opt into a personal workspace for every user", () => {
|
|
70
|
+
const tenancyPolicy = { workspace: { autoProvision: true } };
|
|
71
|
+
assert.equal(
|
|
72
|
+
resolveTenancyProfile({ tenancyMode: TENANCY_MODE_WORKSPACES, tenancyPolicy }).workspace.autoProvision,
|
|
73
|
+
true
|
|
74
|
+
);
|
|
75
|
+
assert.equal(resolveTenancyProfile({ tenancyMode: TENANCY_MODE_NONE, tenancyPolicy }).workspace.autoProvision, false);
|
|
76
|
+
assert.equal(
|
|
77
|
+
resolveTenancyProfile({
|
|
78
|
+
tenancyMode: TENANCY_MODE_PERSONAL,
|
|
79
|
+
tenancyPolicy: { workspace: { autoProvision: false } }
|
|
80
|
+
}).workspace.autoProvision,
|
|
81
|
+
true
|
|
82
|
+
);
|
|
83
|
+
});
|
|
@@ -27,6 +27,7 @@ function createWorkspaceServiceFixture({
|
|
|
27
27
|
additionalWorkspaces = [],
|
|
28
28
|
userWorkspaceRows = null,
|
|
29
29
|
membershipResolver = null,
|
|
30
|
+
personalWorkspaceName = undefined,
|
|
30
31
|
personalWorkspace = {
|
|
31
32
|
id: "1",
|
|
32
33
|
slug: "tonymobily3",
|
|
@@ -72,6 +73,7 @@ function createWorkspaceServiceFixture({
|
|
|
72
73
|
appConfig: {
|
|
73
74
|
tenancyMode,
|
|
74
75
|
tenancyPolicy,
|
|
76
|
+
personalWorkspaceName,
|
|
75
77
|
roleCatalog: roleCatalog && typeof roleCatalog === "object" ? { ...roleCatalog } : roleCatalog
|
|
76
78
|
},
|
|
77
79
|
workspacesRepository: {
|
|
@@ -278,6 +280,32 @@ test("workspaceService.ensureProvisionedWorkspaceForAuthenticatedUser provisions
|
|
|
278
280
|
assert.equal(calls.ensureOwnerMembership, 1);
|
|
279
281
|
assert.equal(calls.ensureWorkspaceSettings, 1);
|
|
280
282
|
assert.equal(insertedPayloads[0].isPersonal, true);
|
|
283
|
+
assert.equal(insertedPayloads[0].name, "Chiara's Workspace");
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
test("workspaceService.ensureProvisionedWorkspaceForAuthenticatedUser provisions a named personal workspace when workspace tenancy opts in", async () => {
|
|
287
|
+
const { service, calls, insertedPayloads } = createWorkspaceServiceFixture({
|
|
288
|
+
tenancyMode: "workspaces",
|
|
289
|
+
tenancyPolicy: {
|
|
290
|
+
workspace: {
|
|
291
|
+
autoProvision: true
|
|
292
|
+
}
|
|
293
|
+
},
|
|
294
|
+
personalWorkspaceName: (user) => `${user.displayName}'s home`,
|
|
295
|
+
personalWorkspace: null
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
const workspace = await service.ensureProvisionedWorkspaceForAuthenticatedUser({
|
|
299
|
+
id: "7",
|
|
300
|
+
email: "chiaramobily@gmail.com",
|
|
301
|
+
displayName: "Chiara"
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
assert.equal(Number(workspace.ownerUserId), 7);
|
|
305
|
+
assert.equal(calls.insert, 1);
|
|
306
|
+
assert.equal(calls.ensureOwnerMembership, 1);
|
|
307
|
+
assert.equal(insertedPayloads[0].isPersonal, true);
|
|
308
|
+
assert.equal(insertedPayloads[0].name, "Chiara's home");
|
|
281
309
|
});
|
|
282
310
|
|
|
283
311
|
test("workspaceService.ensureProvisionedWorkspaceForAuthenticatedUser reuses the existing personal workspace in personal tenancy", async () => {
|
|
@@ -181,6 +181,25 @@ test("workspaceSettingsRepository.ensureForWorkspaceId delegates defaults to the
|
|
|
181
181
|
assert.equal(record.id, "5");
|
|
182
182
|
});
|
|
183
183
|
|
|
184
|
+
test("workspaceSettingsRepository.ensureForWorkspaceId starts new workspaces from the app's default colors", async () => {
|
|
185
|
+
const { api, state, DEFAULT_WORKSPACE_THEME } = createWorkspaceSettingsApiStub();
|
|
186
|
+
state.row = null;
|
|
187
|
+
const repository = createRepository({
|
|
188
|
+
api,
|
|
189
|
+
defaultColorSettings: {
|
|
190
|
+
lightPrimaryColor: "#1C1C1C",
|
|
191
|
+
darkPrimaryColor: "#F5F5F5"
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
await repository.ensureForWorkspaceId("5");
|
|
196
|
+
|
|
197
|
+
assert.equal(state.postPayload.data.lightPrimaryColor, "#1C1C1C");
|
|
198
|
+
assert.equal(state.postPayload.data.darkPrimaryColor, "#F5F5F5");
|
|
199
|
+
assert.equal(state.postPayload.data.lightSecondaryColor, DEFAULT_WORKSPACE_THEME.light.secondaryColor);
|
|
200
|
+
assert.equal(state.postPayload.data.darkSurfaceColor, DEFAULT_WORKSPACE_THEME.dark.surfaceColor);
|
|
201
|
+
});
|
|
202
|
+
|
|
184
203
|
test("workspaceSettingsRepository.updateSettingsByWorkspaceId updates workspace settings fields", async () => {
|
|
185
204
|
const { api, state } = createWorkspaceSettingsApiStub();
|
|
186
205
|
const repository = createRepository({
|