@skillcdn/console 0.4.1 → 0.4.3
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 +19 -2
- package/SKILLCDN.md +7 -5
- package/dist/api.d.ts +5 -4
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +5 -4
- package/dist/api.js.map +1 -1
- package/dist/cli/cli.d.ts.map +1 -1
- package/dist/cli/cli.js +569 -48
- package/dist/cli/cli.js.map +1 -1
- package/dist/cli/format.d.ts +34 -3
- package/dist/cli/format.d.ts.map +1 -1
- package/dist/cli/format.js +283 -7
- package/dist/cli/format.js.map +1 -1
- package/dist/cli/help.d.ts.map +1 -1
- package/dist/cli/help.js +44 -7
- package/dist/cli/help.js.map +1 -1
- package/dist/cli/plugin-check.d.ts +26 -0
- package/dist/cli/plugin-check.d.ts.map +1 -0
- package/dist/cli/plugin-check.js +396 -0
- package/dist/cli/plugin-check.js.map +1 -0
- package/dist/cli/plugin-cli.d.ts +20 -0
- package/dist/cli/plugin-cli.d.ts.map +1 -0
- package/dist/cli/plugin-cli.js +189 -0
- package/dist/cli/plugin-cli.js.map +1 -0
- package/dist/cli/plugin-init.d.ts +37 -0
- package/dist/cli/plugin-init.d.ts.map +1 -0
- package/dist/cli/plugin-init.js +206 -0
- package/dist/cli/plugin-init.js.map +1 -0
- package/dist/cli/plugin-main.d.ts +3 -0
- package/dist/cli/plugin-main.d.ts.map +1 -0
- package/dist/cli/plugin-main.js +28 -0
- package/dist/cli/plugin-main.js.map +1 -0
- package/dist/client.d.ts +100 -3
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +79 -7
- package/dist/client.js.map +1 -1
- package/dist/compat.d.ts +1 -1
- package/dist/compat.js +2 -2
- package/dist/components/board.d.ts +8 -0
- package/dist/components/board.d.ts.map +1 -1
- package/dist/components/board.js +59 -15
- package/dist/components/board.js.map +1 -1
- package/dist/components/comments.d.ts.map +1 -1
- package/dist/components/comments.js +1 -1
- package/dist/components/comments.js.map +1 -1
- package/dist/components/decision-form.d.ts +2 -1
- package/dist/components/decision-form.d.ts.map +1 -1
- package/dist/components/decision-form.js +36 -4
- package/dist/components/decision-form.js.map +1 -1
- package/dist/components/decision-list.d.ts +4 -0
- package/dist/components/decision-list.d.ts.map +1 -1
- package/dist/components/decision-list.js +29 -3
- package/dist/components/decision-list.js.map +1 -1
- package/dist/components/event-feed.d.ts +1 -1
- package/dist/components/event-feed.d.ts.map +1 -1
- package/dist/components/event-feed.js +33 -1
- package/dist/components/event-feed.js.map +1 -1
- package/dist/components/my-decisions.d.ts +2 -0
- package/dist/components/my-decisions.d.ts.map +1 -1
- package/dist/components/my-decisions.js +2 -2
- package/dist/components/my-decisions.js.map +1 -1
- package/dist/components/plugin-frame.d.ts +52 -0
- package/dist/components/plugin-frame.d.ts.map +1 -0
- package/dist/components/plugin-frame.js +314 -0
- package/dist/components/plugin-frame.js.map +1 -0
- package/dist/components/plugin-settings.d.ts +38 -0
- package/dist/components/plugin-settings.d.ts.map +1 -0
- package/dist/components/plugin-settings.js +348 -0
- package/dist/components/plugin-settings.js.map +1 -0
- package/dist/components/shell.d.ts +2 -0
- package/dist/components/shell.d.ts.map +1 -1
- package/dist/components/shell.js +26 -1
- package/dist/components/shell.js.map +1 -1
- package/dist/components/task-view.d.ts +2 -1
- package/dist/components/task-view.d.ts.map +1 -1
- package/dist/components/task-view.js.map +1 -1
- package/dist/components/workspace.d.ts +7 -1
- package/dist/components/workspace.d.ts.map +1 -1
- package/dist/components/workspace.js +1 -1
- package/dist/components/workspace.js.map +1 -1
- package/dist/console.css +330 -1
- package/dist/console.d.ts.map +1 -1
- package/dist/console.js +152 -41
- package/dist/console.js.map +1 -1
- package/dist/data.d.ts +9 -2
- package/dist/data.d.ts.map +1 -1
- package/dist/data.js +45 -9
- package/dist/data.js.map +1 -1
- package/dist/i18n/en.d.ts +155 -0
- package/dist/i18n/en.d.ts.map +1 -1
- package/dist/i18n/en.js +166 -0
- package/dist/i18n/en.js.map +1 -1
- package/dist/i18n/ko.d.ts.map +1 -1
- package/dist/i18n/ko.js +150 -0
- package/dist/i18n/ko.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/limits.d.ts +2 -0
- package/dist/limits.d.ts.map +1 -1
- package/dist/limits.js +2 -0
- package/dist/limits.js.map +1 -1
- package/dist/plugin/args.d.ts +148 -0
- package/dist/plugin/args.d.ts.map +1 -0
- package/dist/plugin/args.js +369 -0
- package/dist/plugin/args.js.map +1 -0
- package/dist/plugin/bridge.d.ts +146 -0
- package/dist/plugin/bridge.d.ts.map +1 -0
- package/dist/plugin/bridge.js +125 -0
- package/dist/plugin/bridge.js.map +1 -0
- package/dist/plugin/capabilities.d.ts +20 -0
- package/dist/plugin/capabilities.d.ts.map +1 -0
- package/dist/plugin/capabilities.js +133 -0
- package/dist/plugin/capabilities.js.map +1 -0
- package/dist/plugin/context.d.ts +380 -0
- package/dist/plugin/context.d.ts.map +1 -0
- package/dist/plugin/context.js +2 -0
- package/dist/plugin/context.js.map +1 -0
- package/dist/plugin/define.d.ts +208 -0
- package/dist/plugin/define.d.ts.map +1 -0
- package/dist/plugin/define.js +482 -0
- package/dist/plugin/define.js.map +1 -0
- package/dist/plugin/definition-error.d.ts +11 -0
- package/dist/plugin/definition-error.d.ts.map +1 -0
- package/dist/plugin/definition-error.js +17 -0
- package/dist/plugin/definition-error.js.map +1 -0
- package/dist/plugin/limits.d.ts +67 -0
- package/dist/plugin/limits.d.ts.map +1 -0
- package/dist/plugin/limits.js +70 -0
- package/dist/plugin/limits.js.map +1 -0
- package/dist/plugin/load-worker.d.ts +7 -0
- package/dist/plugin/load-worker.d.ts.map +1 -0
- package/dist/plugin/load-worker.js +41 -0
- package/dist/plugin/load-worker.js.map +1 -0
- package/dist/plugin/load.d.ts +18 -0
- package/dist/plugin/load.d.ts.map +1 -0
- package/dist/plugin/load.js +62 -0
- package/dist/plugin/load.js.map +1 -0
- package/dist/plugin/manifest.d.ts +237 -0
- package/dist/plugin/manifest.d.ts.map +1 -0
- package/dist/plugin/manifest.js +411 -0
- package/dist/plugin/manifest.js.map +1 -0
- package/dist/plugin/refusals.d.ts +49 -0
- package/dist/plugin/refusals.d.ts.map +1 -0
- package/dist/plugin/refusals.js +79 -0
- package/dist/plugin/refusals.js.map +1 -0
- package/dist/plugin/rest-schemas.d.ts +556 -0
- package/dist/plugin/rest-schemas.d.ts.map +1 -0
- package/dist/plugin/rest-schemas.js +262 -0
- package/dist/plugin/rest-schemas.js.map +1 -0
- package/dist/plugin/sandbox.d.ts +23 -0
- package/dist/plugin/sandbox.d.ts.map +1 -0
- package/dist/plugin/sandbox.js +99 -0
- package/dist/plugin/sandbox.js.map +1 -0
- package/dist/plugin/testing.d.ts +45 -0
- package/dist/plugin/testing.d.ts.map +1 -0
- package/dist/plugin/testing.js +420 -0
- package/dist/plugin/testing.js.map +1 -0
- package/dist/plugin/web-react.d.ts +11 -0
- package/dist/plugin/web-react.d.ts.map +1 -0
- package/dist/plugin/web-react.js +34 -0
- package/dist/plugin/web-react.js.map +1 -0
- package/dist/plugin/web.d.ts +95 -0
- package/dist/plugin/web.d.ts.map +1 -0
- package/dist/plugin/web.js +245 -0
- package/dist/plugin/web.js.map +1 -0
- package/dist/plugin-nav.d.ts +29 -0
- package/dist/plugin-nav.d.ts.map +1 -0
- package/dist/plugin-nav.js +92 -0
- package/dist/plugin-nav.js.map +1 -0
- package/dist/plugin-testing.d.ts +2 -0
- package/dist/plugin-testing.d.ts.map +1 -0
- package/dist/plugin-testing.js +4 -0
- package/dist/plugin-testing.js.map +1 -0
- package/dist/plugin-web-react.d.ts +3 -0
- package/dist/plugin-web-react.d.ts.map +1 -0
- package/dist/plugin-web-react.js +3 -0
- package/dist/plugin-web-react.js.map +1 -0
- package/dist/plugin-web.d.ts +4 -0
- package/dist/plugin-web.d.ts.map +1 -0
- package/dist/plugin-web.js +5 -0
- package/dist/plugin-web.js.map +1 -0
- package/dist/plugin.d.ts +11 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +15 -0
- package/dist/plugin.js.map +1 -0
- package/dist/router.d.ts +28 -0
- package/dist/router.d.ts.map +1 -1
- package/dist/router.js +47 -0
- package/dist/router.js.map +1 -1
- package/dist/routes.d.ts +4 -0
- package/dist/routes.d.ts.map +1 -1
- package/dist/routes.js +6 -0
- package/dist/routes.js.map +1 -1
- package/dist/schemas.d.ts +194 -9
- package/dist/schemas.d.ts.map +1 -1
- package/dist/schemas.js +98 -17
- package/dist/schemas.js.map +1 -1
- package/dist/tokens.d.ts +2 -0
- package/dist/tokens.d.ts.map +1 -0
- package/dist/tokens.js +101 -0
- package/dist/tokens.js.map +1 -0
- package/dist/vocabulary.d.ts +11 -1
- package/dist/vocabulary.d.ts.map +1 -1
- package/dist/vocabulary.js +24 -0
- package/dist/vocabulary.js.map +1 -1
- package/dist/web.d.ts.map +1 -1
- package/dist/web.js +2 -0
- package/dist/web.js.map +1 -1
- package/docs/specs/cli.md +12 -5
- package/docs/specs/plugins.md +488 -0
- package/docs/specs/rest.md +11 -9
- package/package.json +26 -8
- package/skills/building-a-console/SKILL.md +25 -26
- package/skills/building-a-console/references/configuring.md +40 -0
- package/skills/building-a-console/references/the-default-console.md +1 -1
- package/skills/building-a-console/references/the-look-from-a-website.md +5 -5
- package/skills/building-a-plugin/SKILL.md +137 -0
- package/skills/deploying-a-console/SKILL.md +24 -26
- package/skills/deploying-a-console/references/access.md +13 -9
- package/skills/deploying-a-console/references/resources.md +25 -10
- package/skills/deploying-a-console/references/running-it-again.md +15 -0
- package/skills/deploying-a-console/references/sizing.md +2 -0
- package/skills/planning-the-board/SKILL.md +96 -0
- package/skills/planning-the-board/references/a-task.md +36 -0
- package/skills/planning-the-board/references/setting-up.md +44 -0
- package/skills/working-the-board/SKILL.md +43 -34
- package/skills/working-the-board/references/the-pack.md +19 -0
- package/src/api.ts +12 -0
- package/src/cli/cli.ts +737 -55
- package/src/cli/format.ts +368 -10
- package/src/cli/help.ts +50 -6
- package/src/cli/plugin-check.ts +497 -0
- package/src/cli/plugin-cli.ts +237 -0
- package/src/cli/plugin-init.ts +257 -0
- package/src/cli/plugin-main.ts +30 -0
- package/src/client.ts +322 -9
- package/src/compat.ts +2 -2
- package/src/components/board.tsx +62 -14
- package/src/components/comments.tsx +1 -0
- package/src/components/decision-form.tsx +92 -11
- package/src/components/decision-list.tsx +71 -2
- package/src/components/event-feed.tsx +42 -1
- package/src/components/my-decisions.tsx +4 -1
- package/src/components/plugin-frame.tsx +437 -0
- package/src/components/plugin-settings.tsx +1111 -0
- package/src/components/shell.tsx +82 -14
- package/src/components/task-view.tsx +2 -1
- package/src/components/workspace.tsx +18 -0
- package/src/console.tsx +304 -31
- package/src/data.ts +59 -11
- package/src/i18n/en.ts +175 -0
- package/src/i18n/ko.ts +155 -0
- package/src/index.ts +12 -0
- package/src/limits.ts +2 -0
- package/src/plugin/args.ts +526 -0
- package/src/plugin/bridge.ts +314 -0
- package/src/plugin/capabilities.ts +150 -0
- package/src/plugin/context.ts +421 -0
- package/src/plugin/define.ts +792 -0
- package/src/plugin/definition-error.ts +19 -0
- package/src/plugin/limits.ts +70 -0
- package/src/plugin/load-worker.ts +50 -0
- package/src/plugin/load.ts +82 -0
- package/src/plugin/manifest.ts +561 -0
- package/src/plugin/refusals.ts +94 -0
- package/src/plugin/rest-schemas.ts +354 -0
- package/src/plugin/sandbox.ts +123 -0
- package/src/plugin/testing.ts +612 -0
- package/src/plugin/web-react.ts +45 -0
- package/src/plugin/web.ts +403 -0
- package/src/plugin-nav.ts +132 -0
- package/src/plugin-testing.ts +10 -0
- package/src/plugin-web-react.ts +4 -0
- package/src/plugin-web.ts +35 -0
- package/src/plugin.ts +126 -0
- package/src/router.ts +73 -0
- package/src/routes.ts +7 -0
- package/src/schemas.ts +115 -18
- package/src/styles/console.css +330 -1
- package/src/tokens.ts +101 -0
- package/src/vocabulary.ts +30 -0
- package/src/web.ts +2 -0
- package/template/plugin/.gitignore +2 -0
- package/template/plugin/README.md +26 -0
- package/template/plugin/SKILLCDN.md +13 -0
- package/template/plugin/build.mjs +40 -0
- package/template/plugin/console-plugin.json +50 -0
- package/template/plugin/package.json +27 -0
- package/template/plugin/skills/__key__/SKILL.md +23 -0
- package/template/plugin/src/check.test.ts +34 -0
- package/template/plugin/src/server/index.test.ts +41 -0
- package/template/plugin/src/server/index.ts +72 -0
- package/template/plugin/src/web/index.css +51 -0
- package/template/plugin/src/web/index.ts +115 -0
- package/template/plugin/tsconfig.json +17 -0
- package/skills/working-the-board/references/setting-up.md +0 -3
- /package/skills/{working-the-board → planning-the-board}/references/project-rules.md +0 -0
package/dist/console.js
CHANGED
|
@@ -14,6 +14,8 @@ import { MyDecisions } from "./components/my-decisions.js";
|
|
|
14
14
|
import { PackTokenWays } from "./components/pack-token.js";
|
|
15
15
|
import { PAGE_SIZE } from "./components/paged.js";
|
|
16
16
|
import { ListingForm, PeopleList } from "./components/people.js";
|
|
17
|
+
import { PluginFrame, PluginWidgets } from "./components/plugin-frame.js";
|
|
18
|
+
import { PluginSettingsList, PluginSettingsView } from "./components/plugin-settings.js";
|
|
17
19
|
import { MemberList, ProjectForm, ProjectList, ProjectMark, } from "./components/projects.js";
|
|
18
20
|
import { RemotePicturesContext } from "./components/remote-pictures.js";
|
|
19
21
|
import { GoalTimeline } from "./components/roadmap.js";
|
|
@@ -33,7 +35,8 @@ import { useConsoleData } from "./data.js";
|
|
|
33
35
|
import { monthOf, today } from "./dates.js";
|
|
34
36
|
import { DocsPage } from "./docs-page.js";
|
|
35
37
|
import { chooseLanguage, DEFAULT_LANGUAGES, LanguageContext, useWords, } from "./i18n/index.js";
|
|
36
|
-
import {
|
|
38
|
+
import { pluginNavItems, pluginPagesAt, pluginWordOf } from "./plugin-nav.js";
|
|
39
|
+
import { boardHref, calendarHref, customPageHref, decisionHref, decisionsHref, docHref, goalHref, matchRoute, newDecisionHref, newGoalHref, newTaskHref, PATHS, personAgentsHref, personWorkHref, pluginHref, pluginSettingsHref, projectHref, projectSettingsHref, roadmapHref, settingsHref, signInFailureOf, taskHref, withoutSignInParam, workHref, } from "./router.js";
|
|
37
40
|
import { projectPath } from "./routes.js";
|
|
38
41
|
import { errorWords, useAction } from "./use-action.js";
|
|
39
42
|
export const DEFAULT_COMPONENTS = {
|
|
@@ -163,6 +166,12 @@ function useFollowLinks(navigation) {
|
|
|
163
166
|
}, [navigation]);
|
|
164
167
|
}
|
|
165
168
|
/** The key of the project a route is on, or nothing. */
|
|
169
|
+
/** The files chosen or pasted on a page, as the client sends them: each by its name, its bytes and its type where the browser knows one. */
|
|
170
|
+
const uploadsOf = (files) => files.map((file) => ({
|
|
171
|
+
name: file.name,
|
|
172
|
+
bytes: file,
|
|
173
|
+
...(file.type === "" ? {} : { contentType: file.type }),
|
|
174
|
+
}));
|
|
166
175
|
const projectOf = (route) => "project" in route ? route.project : undefined;
|
|
167
176
|
/** The field the pages lie on, for a page without the shell: signing in, and the wait before it. */
|
|
168
177
|
function Ground(props) {
|
|
@@ -192,17 +201,87 @@ function NotWithToken() {
|
|
|
192
201
|
}
|
|
193
202
|
function ProjectsPage(props) {
|
|
194
203
|
const words = useWords().projects;
|
|
195
|
-
const { data, components, navigation } = props;
|
|
204
|
+
const { data, components, navigation, client, language } = props;
|
|
205
|
+
const me = data.me;
|
|
206
|
+
/** The plugins' widgets at a place of this page (ADR-0054), for the person's roles. */
|
|
207
|
+
const widgets = (place) => me === undefined ? null : (_jsx(PluginWidgets, { plugins: data.plugins, place: place, me: me, language: language, client: client, navigation: navigation, nameOf: (name) => pluginWordOf(name, language) }));
|
|
196
208
|
const { busy, error, act } = useAction();
|
|
197
209
|
const href = (project) => projectHref(project.key);
|
|
198
210
|
// A project is made by an administrator (ADR-0045): a member sees the list alone, the form's
|
|
199
211
|
// address included.
|
|
200
212
|
const administrator = data.me?.person?.role === "admin";
|
|
201
213
|
const making = props.making && administrator;
|
|
202
|
-
return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "sc-page-head", children: [_jsx("h1", { className: "sc-page-title", children: words.title }), administrator && !making && (_jsx(LinkButton, { href: PATHS.newProject, variant: "primary", children: words.newProject }))] }), error !== undefined && _jsx(Callout, { tone: "danger", children: error }), making && (_jsx("section", { className: "sc-panel sc-panel-form", "aria-label": words.form.aria, children: _jsx(ProjectForm, { busy: busy, skillsSource: data.me?.workspace.skills.source, organizationAddress: data.me?.workspace.skills.address ?? null, onSubmit: (input, icon) => void act(async () => {
|
|
214
|
+
return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "sc-page-head", children: [_jsx("h1", { className: "sc-page-title", children: words.title }), administrator && !making && (_jsx(LinkButton, { href: PATHS.newProject, variant: "primary", children: words.newProject }))] }), error !== undefined && _jsx(Callout, { tone: "danger", children: error }), widgets("home:top"), making && (_jsx("section", { className: "sc-panel sc-panel-form", "aria-label": words.form.aria, children: _jsx(ProjectForm, { busy: busy, skillsSource: data.me?.workspace.skills.source, organizationAddress: data.me?.workspace.skills.address ?? null, onSubmit: (input, icon) => void act(async () => {
|
|
203
215
|
const made = await data.actions.createProject(input, icon instanceof File ? uploadOf(icon) : undefined);
|
|
204
216
|
navigation.replace(projectHref(made.key));
|
|
205
|
-
}), onCancel: () => navigation.back(PATHS.projects) }) })), _jsx(components.ProjectList, { projects: data.projects, projectHref: href, onOpen: (project) => navigation.go(href(project)), empty: _jsx(EmptyState, { title: words.empty.title, body: administrator ? words.empty.body : words.empty.bodyMember, action: administrator ? (_jsx(LinkButton, { href: PATHS.newProject, children: words.newProject })) : undefined }) })] }));
|
|
217
|
+
}), onCancel: () => navigation.back(PATHS.projects) }) })), _jsx(components.ProjectList, { projects: data.projects, projectHref: href, onOpen: (project) => navigation.go(href(project)), empty: _jsx(EmptyState, { title: words.empty.title, body: administrator ? words.empty.body : words.empty.bodyMember, action: administrator ? (_jsx(LinkButton, { href: PATHS.newProject, children: words.newProject })) : undefined }) }), widgets("home:bottom")] }));
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* A plugin's page (ADR-0054): the sub-tabs of its pages at the level, where it has several, above
|
|
221
|
+
* the frame of the one shown, the first when the address names none. Nothing for a plugin the
|
|
222
|
+
* person has no page of, or that is not on the project.
|
|
223
|
+
*/
|
|
224
|
+
function PluginPage(props) {
|
|
225
|
+
const words = useWords();
|
|
226
|
+
const { route, data, project, client, language, navigation } = props;
|
|
227
|
+
const plugin = data.plugins.find((candidate) => candidate.key === route.plugin && candidate.state === "enabled");
|
|
228
|
+
const bound = route.level === "workspace" ||
|
|
229
|
+
data.projectPlugins.some((candidate) => candidate.key === route.plugin);
|
|
230
|
+
const pages = plugin === undefined ? [] : pluginPagesAt(plugin, route.level);
|
|
231
|
+
const page = route.page === undefined ? pages[0] : pages.find((p) => p.key === route.page);
|
|
232
|
+
if (plugin === undefined || !bound || page === undefined || data.me === undefined) {
|
|
233
|
+
return _jsx(EmptyState, { title: words.plugins.noPage.title, body: words.plugins.noPage.body });
|
|
234
|
+
}
|
|
235
|
+
const projectKey = route.level === "project" ? route.project : undefined;
|
|
236
|
+
return (_jsxs(_Fragment, { children: [pages.length > 1 && (_jsx("nav", { className: "sc-subtabs", "aria-label": pluginWordOf(plugin.name, language), children: pages.map((candidate) => (_jsx("a", { href: pluginHref(plugin.key, candidate.key, projectKey), className: candidate.key === page.key ? "sc-tab sc-tab-current" : "sc-tab", "aria-current": candidate.key === page.key ? "page" : undefined, children: pluginWordOf(candidate.name, language) }, candidate.key))) })), _jsx(PluginFrame, { plugin: plugin, page: page.key, project: project, path: route.rest, me: data.me, language: language, client: client, navigation: navigation, events: project === undefined ? undefined : data.events, title: words.plugins.frame(pluginWordOf(page.name, language)) }, `${plugin.key}:${page.key}:${projectKey ?? ""}`)] }));
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* The plugins' settings (docs/specs/plugins.md, "The settings pages"): the list, or one plugin
|
|
240
|
+
* whole, read again after every change; for an administrator.
|
|
241
|
+
*/
|
|
242
|
+
function PluginSettingsPage(props) {
|
|
243
|
+
const words = useWords();
|
|
244
|
+
const { data, client, language, navigation } = props;
|
|
245
|
+
const settings = words.plugins.settings;
|
|
246
|
+
const administrator = data.me?.person?.role === "admin";
|
|
247
|
+
const [detail, setDetail] = useState(undefined);
|
|
248
|
+
const [failure, setFailure] = useState(undefined);
|
|
249
|
+
const key = props.plugin;
|
|
250
|
+
const read = useCallback(async () => {
|
|
251
|
+
if (key === undefined) {
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
try {
|
|
255
|
+
setDetail(await client.plugin(key).get());
|
|
256
|
+
setFailure(undefined);
|
|
257
|
+
}
|
|
258
|
+
catch (error) {
|
|
259
|
+
setFailure(error instanceof ApiError ? error.message : words.common.somethingWentWrong);
|
|
260
|
+
}
|
|
261
|
+
}, [client, key, words.common.somethingWentWrong]);
|
|
262
|
+
useEffect(() => {
|
|
263
|
+
setDetail(undefined);
|
|
264
|
+
void read();
|
|
265
|
+
}, [read]);
|
|
266
|
+
if (!administrator) {
|
|
267
|
+
return _jsx(NothingHere, {});
|
|
268
|
+
}
|
|
269
|
+
if (key === undefined) {
|
|
270
|
+
return (_jsxs(_Fragment, { children: [_jsx("div", { className: "sc-page-head", children: _jsx("h1", { className: "sc-page-title", children: settings.title }) }), _jsx(PluginSettingsList, { plugins: data.plugins, language: language, href: (plugin) => pluginSettingsHref(plugin.key) })] }));
|
|
271
|
+
}
|
|
272
|
+
if (failure !== undefined) {
|
|
273
|
+
return _jsx(EmptyState, { title: words.common.somethingWentWrong, body: failure });
|
|
274
|
+
}
|
|
275
|
+
if (detail === undefined) {
|
|
276
|
+
return (_jsx("div", { className: "sc-loading", children: _jsx(Spinner, { label: words.common.loading }) }));
|
|
277
|
+
}
|
|
278
|
+
return (_jsx(PluginSettingsView, { detail: detail, projects: data.projects, people: data.people, language: language, client: client, onChanged: async () => {
|
|
279
|
+
await read();
|
|
280
|
+
await data.actions.refreshPlugins();
|
|
281
|
+
}, onPurged: () => {
|
|
282
|
+
void data.actions.refreshPlugins();
|
|
283
|
+
navigation.replace(pluginSettingsHref());
|
|
284
|
+
} }));
|
|
206
285
|
}
|
|
207
286
|
/**
|
|
208
287
|
* The archive of the board (ADR-0029): the tasks put away, newest first, a page at a time from
|
|
@@ -348,8 +427,8 @@ function TaskPage(props) {
|
|
|
348
427
|
return (_jsx(components.TaskView, { task: task, people: data.people.filter(inWorkspace), tasks: data.tasks, parent: parent, findTasks: data.actions.findTasks, findGoals: data.actions.findGoals, decisions: data.decisions, runs: data.runs, comments: comments, history: history, categories: data.categories, goals: data.goals, taskHref: (candidate) => taskHref(key, candidate.number), decisionHref: (decisionId) => decisionHref(key, decisionId), goalHref: (goalId) => goalHref(key, goalId), fileHref: (fileId) => projectPath(key, "files", fileId), docHref: (path) => docHref(key, path), form: route.form, formHref: (form) => taskHref(key, task.number, form), onCancel: () => navigation.back(here), busy: busy, error: error, onChange: (target, patch) => void act(async () => {
|
|
349
428
|
await data.actions.updateTask(target.id, patch);
|
|
350
429
|
navigation.replace(here);
|
|
351
|
-
}), onMove: (target, state) => void act(() => data.actions.updateTask(target.id, { state })), onRaiseDecision: (input) => void act(async () => {
|
|
352
|
-
await data.actions.raiseDecision(input);
|
|
430
|
+
}), onMove: (target, state) => void act(() => data.actions.updateTask(target.id, { state })), onRaiseDecision: (input, files) => void act(async () => {
|
|
431
|
+
await data.actions.raiseDecision(input, uploadsOf(files));
|
|
353
432
|
navigation.replace(here);
|
|
354
433
|
}), onAnswer: (decision, input) => void act(() => data.actions.answerDecision(decision.id, input)), onUpdateDecision: (decision, patch) => void act(() => data.actions.updateDecision(decision.id, patch)), onAbandonRun: (run) => void act(() => data.actions.abandonRun(run.id)), onArchive: (target) => void act(async () => {
|
|
355
434
|
await data.actions.archiveTask(target.id);
|
|
@@ -357,14 +436,7 @@ function TaskPage(props) {
|
|
|
357
436
|
}), onRestore: (target) => void act(async () => {
|
|
358
437
|
setFetched(await data.actions.restoreTask(target.id));
|
|
359
438
|
}), onComment: (draft) => void act(async () => {
|
|
360
|
-
await data.actions.comment(task.id, {
|
|
361
|
-
body: draft.body,
|
|
362
|
-
files: draft.files.map((file) => ({
|
|
363
|
-
name: file.name,
|
|
364
|
-
bytes: file,
|
|
365
|
-
...(file.type === "" ? {} : { contentType: file.type }),
|
|
366
|
-
})),
|
|
367
|
-
});
|
|
439
|
+
await data.actions.comment(task.id, { body: draft.body, files: uploadsOf(draft.files) });
|
|
368
440
|
setComments(await taskComments(task.id));
|
|
369
441
|
}) }));
|
|
370
442
|
}
|
|
@@ -455,17 +527,17 @@ function ProjectPage(props) {
|
|
|
455
527
|
return (_jsx(DocsPage, { project: project, path: route.path, view: route.view, data: data, navigation: navigation }));
|
|
456
528
|
}
|
|
457
529
|
if (route.name === "decisions") {
|
|
458
|
-
return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "sc-page-head", children: [_jsx("h1", { className: "sc-page-title", children: words.decisions.title }), _jsx(LinkButton, { href: newDecisionHref(key), variant: "primary", children: words.decisions.raise })] }), error !== undefined && _jsx(Callout, { tone: "danger", children: error }), _jsx(components.DecisionList, { decisions: data.decisions, tasks: tasksById, taskHref: href, docHref: toDoc, decisionHref: (decision) => decisionHref(key, decision.id), page: route.page, pageHref: (page) => decisionsHref(key, page), onAnswer: onAnswer, onUpdate: onUpdate, busy: busy, empty: _jsx(EmptyState, { title: words.decisions.empty.title, body: words.decisions.empty.body }) })] }));
|
|
530
|
+
return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "sc-page-head", children: [_jsx("h1", { className: "sc-page-title", children: words.decisions.title }), _jsx(LinkButton, { href: newDecisionHref(key), variant: "primary", children: words.decisions.raise })] }), error !== undefined && _jsx(Callout, { tone: "danger", children: error }), _jsx(components.DecisionList, { decisions: data.decisions, tasks: tasksById, taskHref: href, docHref: toDoc, fileHref: (fileId) => projectPath(key, "files", fileId), decisionHref: (decision) => decisionHref(key, decision.id), page: route.page, pageHref: (page) => decisionsHref(key, page), onAnswer: onAnswer, onUpdate: onUpdate, busy: busy, empty: _jsx(EmptyState, { title: words.decisions.empty.title, body: words.decisions.empty.body }) })] }));
|
|
459
531
|
}
|
|
460
532
|
if (route.name === "new-decision") {
|
|
461
|
-
return (_jsxs(_Fragment, { children: [_jsx("div", { className: "sc-page-head", children: _jsx("h1", { className: "sc-page-title", children: words.decisions.raise }) }), error !== undefined && _jsx(Callout, { tone: "danger", children: error }), _jsx("section", { className: "sc-panel sc-panel-form", "aria-label": words.decisions.raiseAria, children: _jsx(DecisionForm, { findTasks: data.actions.findTasks, deciders: data.members.map((member) => member.person), me: data.me?.person ?? undefined, busy: busy, onSubmit: (input) => void act(async () => {
|
|
462
|
-
const made = await data.actions.raiseDecision(input);
|
|
533
|
+
return (_jsxs(_Fragment, { children: [_jsx("div", { className: "sc-page-head", children: _jsx("h1", { className: "sc-page-title", children: words.decisions.raise }) }), error !== undefined && _jsx(Callout, { tone: "danger", children: error }), _jsx("section", { className: "sc-panel sc-panel-form", "aria-label": words.decisions.raiseAria, children: _jsx(DecisionForm, { findTasks: data.actions.findTasks, deciders: data.members.map((member) => member.person), me: data.me?.person ?? undefined, busy: busy, onSubmit: (input, files) => void act(async () => {
|
|
534
|
+
const made = await data.actions.raiseDecision(input, uploadsOf(files));
|
|
463
535
|
navigation.replace(decisionHref(key, made.id));
|
|
464
536
|
}), onCancel: () => navigation.back(projectHref(key, "decisions")) }) })] }));
|
|
465
537
|
}
|
|
466
538
|
if (route.name === "decision") {
|
|
467
539
|
const decision = data.decisions.find((candidate) => candidate.id === route.id);
|
|
468
|
-
return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "sc-page-head", children: [_jsx("h1", { className: "sc-page-title", children: words.decisions.one }), _jsx(LinkButton, { href: projectHref(key, "decisions"), children: words.decisions.all })] }), error !== undefined && _jsx(Callout, { tone: "danger", children: error }), decision === undefined ? (_jsx(EmptyState, { title: words.decisions.noSuch.title, body: words.decisions.noSuch.body })) : (_jsx(DecisionCard, { decision: decision, task: decision.taskId === null ? undefined : tasksById.get(decision.taskId), taskHref: href, docHref: toDoc, onAnswer: onAnswer, onUpdate: onUpdate, busy: busy }))] }));
|
|
540
|
+
return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "sc-page-head", children: [_jsx("h1", { className: "sc-page-title", children: words.decisions.one }), _jsx(LinkButton, { href: projectHref(key, "decisions"), children: words.decisions.all })] }), error !== undefined && _jsx(Callout, { tone: "danger", children: error }), decision === undefined ? (_jsx(EmptyState, { title: words.decisions.noSuch.title, body: words.decisions.noSuch.body })) : (_jsx(DecisionCard, { decision: decision, task: decision.taskId === null ? undefined : tasksById.get(decision.taskId), taskHref: href, docHref: toDoc, fileHref: (fileId) => projectPath(key, "files", fileId), onAnswer: onAnswer, onUpdate: onUpdate, busy: busy }))] }));
|
|
469
541
|
}
|
|
470
542
|
if (route.name === "archive") {
|
|
471
543
|
return _jsx(ArchivePage, { project: project, data: data });
|
|
@@ -513,6 +585,9 @@ function ProjectPage(props) {
|
|
|
513
585
|
if (route.name === "settings") {
|
|
514
586
|
return (_jsx(ProjectSettingsPage, { route: route, project: project, data: data, navigation: navigation }));
|
|
515
587
|
}
|
|
588
|
+
if (route.name === "plugin") {
|
|
589
|
+
return (_jsx(PluginPage, { route: route, data: data, project: project, client: props.client, language: props.language, navigation: navigation }));
|
|
590
|
+
}
|
|
516
591
|
return _jsx(NothingHere, {});
|
|
517
592
|
}
|
|
518
593
|
/**
|
|
@@ -602,7 +677,7 @@ function ProjectSettingsPage(props) {
|
|
|
602
677
|
*/
|
|
603
678
|
function WorkspaceSettingsPage(props) {
|
|
604
679
|
const words = useWords();
|
|
605
|
-
const { form, data, navigation } = props;
|
|
680
|
+
const { form, data, navigation, language } = props;
|
|
606
681
|
const { busy, error, act } = useAction();
|
|
607
682
|
const administrator = data.me?.person?.role === "admin";
|
|
608
683
|
const workspace = data.me?.workspace;
|
|
@@ -662,11 +737,11 @@ function WorkspaceSettingsPage(props) {
|
|
|
662
737
|
navigation.replace(PATHS.settings);
|
|
663
738
|
}), onCancel: () => navigation.back(PATHS.settings) })] })] }));
|
|
664
739
|
}
|
|
665
|
-
return (_jsxs(_Fragment, { children: [head, error !== undefined && _jsx(Callout, { tone: "danger", children: error }), workspace !== undefined && (_jsxs("section", { className: "sc-panel", "aria-label": words.settings.workspace.aria, children: [_jsxs("div", { className: "sc-section-head", children: [_jsx("h2", { className: "sc-section-title", children: words.settings.workspace.title }), administrator && (_jsx("a", { className: "sc-button sc-button-secondary sc-button-sm", href: settingsHref("workspace"), children: words.common.edit }))] }), _jsx(WorkspaceSettingsView, { workspace: workspace })] })), _jsxs("section", { className: "sc-panel", "aria-label": words.rules.title, children: [_jsx("h2", { className: "sc-section-title", children: words.rules.title }), rules === undefined ? (_jsx(Spinner, { label: words.rules.loading })) : (_jsx(RulesView, { rules: rules, scope: "workspace", editHref: administrator ? settingsHref("rules") : undefined, onArchive: administrator
|
|
740
|
+
return (_jsxs(_Fragment, { children: [head, error !== undefined && _jsx(Callout, { tone: "danger", children: error }), workspace !== undefined && (_jsxs("section", { className: "sc-panel", "aria-label": words.settings.workspace.aria, children: [_jsxs("div", { className: "sc-section-head", children: [_jsx("h2", { className: "sc-section-title", children: words.settings.workspace.title }), administrator && (_jsx("a", { className: "sc-button sc-button-secondary sc-button-sm", href: settingsHref("workspace"), children: words.common.edit }))] }), _jsx(WorkspaceSettingsView, { workspace: workspace, console: data.me?.console })] })), _jsxs("section", { className: "sc-panel", "aria-label": words.rules.title, children: [_jsx("h2", { className: "sc-section-title", children: words.rules.title }), rules === undefined ? (_jsx(Spinner, { label: words.rules.loading })) : (_jsx(RulesView, { rules: rules, scope: "workspace", editHref: administrator ? settingsHref("rules") : undefined, onArchive: administrator
|
|
666
741
|
? () => void act(async () => {
|
|
667
742
|
setRules(await data.actions.archiveRules());
|
|
668
743
|
})
|
|
669
|
-
: undefined, busy: busy }))] }), _jsxs("section", { className: "sc-panel", "aria-label": words.settings.categories, children: [_jsx("h2", { className: "sc-section-title", children: words.settings.categories }), data.categories.length > 0 && (_jsx("p", { className: "sc-category-chips", children: data.categories.map((category) => (_jsx(CategoryBadge, { category: category }, category.key))) })), _jsx(LinkButton, { href: PATHS.categories, children: words.settings.manageCategories })] }), skills !== undefined && (_jsxs("section", { className: "sc-panel", "aria-label": words.settings.skills, children: [_jsx("h2", { className: "sc-section-title", children: words.settings.skills }), _jsxs("dl", { className: "sc-facts sc-facts-plain", children: [_jsxs("div", { children: [_jsx("dt", { children: words.settings.skillsSource }), _jsx("dd", { children: _jsx("a", { href: skills.source, target: "_blank", rel: "noopener noreferrer", children: skills.source }) })] }), _jsxs("div", { children: [_jsx("dt", { children: words.settings.skillsAddress }), _jsx("dd", { children: skills.address === null ? (words.settings.noSkillsAddress) : (_jsx("a", { href: `${skills.source}${skills.address}`, target: "_blank", rel: "noopener noreferrer", children: _jsx("code", { children: skills.address }) })) })] }), skills.address !== null && (_jsxs("div", { children: [_jsx("dt", { children: words.settings.skillsToken }), _jsxs("dd", { children: [skills.packToken == null ? (_jsx("span", { className: "sc-muted", children: words.projects.settings.packTokenNone })) : (_jsxs(_Fragment, { children: [words.projects.settings.packTokenSet, " ", _jsx(Time, { iso: skills.packToken.setAt })] })), administrator && (_jsxs(_Fragment, { children: [" ", _jsx("a", { href: settingsHref("pack-token"), children: skills.packToken == null
|
|
744
|
+
: undefined, busy: busy }))] }), administrator && (_jsxs("section", { className: "sc-panel", "aria-label": words.plugins.settings.title, children: [_jsx("h2", { className: "sc-section-title", children: words.plugins.settings.title }), data.plugins.length === 0 ? (_jsx("p", { className: "sc-settings-hint", children: words.plugins.settings.empty.body })) : (_jsx(PluginSettingsList, { plugins: data.plugins, language: language, href: (plugin) => pluginSettingsHref(plugin.key) }))] })), _jsxs("section", { className: "sc-panel", "aria-label": words.settings.categories, children: [_jsx("h2", { className: "sc-section-title", children: words.settings.categories }), data.categories.length > 0 && (_jsx("p", { className: "sc-category-chips", children: data.categories.map((category) => (_jsx(CategoryBadge, { category: category }, category.key))) })), _jsx(LinkButton, { href: PATHS.categories, children: words.settings.manageCategories })] }), skills !== undefined && (_jsxs("section", { className: "sc-panel", "aria-label": words.settings.skills, children: [_jsx("h2", { className: "sc-section-title", children: words.settings.skills }), _jsxs("dl", { className: "sc-facts sc-facts-plain", children: [_jsxs("div", { children: [_jsx("dt", { children: words.settings.skillsSource }), _jsx("dd", { children: _jsx("a", { href: skills.source, target: "_blank", rel: "noopener noreferrer", children: skills.source }) })] }), _jsxs("div", { children: [_jsx("dt", { children: words.settings.skillsAddress }), _jsx("dd", { children: skills.address === null ? (words.settings.noSkillsAddress) : (_jsx("a", { href: `${skills.source}${skills.address}`, target: "_blank", rel: "noopener noreferrer", children: _jsx("code", { children: skills.address }) })) })] }), skills.address !== null && (_jsxs("div", { children: [_jsx("dt", { children: words.settings.skillsToken }), _jsxs("dd", { children: [skills.packToken == null ? (_jsx("span", { className: "sc-muted", children: words.projects.settings.packTokenNone })) : (_jsxs(_Fragment, { children: [words.projects.settings.packTokenSet, " ", _jsx(Time, { iso: skills.packToken.setAt })] })), administrator && (_jsxs(_Fragment, { children: [" ", _jsx("a", { href: settingsHref("pack-token"), children: skills.packToken == null
|
|
670
745
|
? words.projects.settings.packTokenAdd
|
|
671
746
|
: words.projects.settings.packTokenEdit })] }))] })] }))] }), _jsx("p", { className: "sc-muted", children: words.settings.skillsFromConfiguration })] }))] }));
|
|
672
747
|
}
|
|
@@ -813,7 +888,7 @@ function MyDecisionsPage(props) {
|
|
|
813
888
|
addressed.reload();
|
|
814
889
|
raised.reload();
|
|
815
890
|
});
|
|
816
|
-
return (_jsxs(_Fragment, { children: [_jsx("div", { className: "sc-page-head", children: _jsx("h1", { className: "sc-page-title", children: words.myDecisions.title }) }), problem !== undefined && _jsx(Callout, { tone: "danger", children: problem }), addressed.items === undefined || raised.items === undefined ? (problem === undefined && (_jsx("div", { className: "sc-loading", children: _jsx(Spinner, { label: words.myDecisions.loading }) }))) : addressed.items.length === 0 && raised.items.length === 0 ? (_jsx(EmptyState, { title: words.myDecisions.empty.title, body: words.myDecisions.empty.body })) : (_jsx(MyDecisions, { addressed: { items: addressed.items, more: addressed.more, onMore: addressed.readMore }, raised: { items: raised.items, more: raised.more, onMore: raised.readMore }, decisionHref: decisionHref, onAnswer: onAnswer, busy: busy || addressed.busy || raised.busy }))] }));
|
|
891
|
+
return (_jsxs(_Fragment, { children: [_jsx("div", { className: "sc-page-head", children: _jsx("h1", { className: "sc-page-title", children: words.myDecisions.title }) }), problem !== undefined && _jsx(Callout, { tone: "danger", children: problem }), addressed.items === undefined || raised.items === undefined ? (problem === undefined && (_jsx("div", { className: "sc-loading", children: _jsx(Spinner, { label: words.myDecisions.loading }) }))) : addressed.items.length === 0 && raised.items.length === 0 ? (_jsx(EmptyState, { title: words.myDecisions.empty.title, body: words.myDecisions.empty.body })) : (_jsx(MyDecisions, { addressed: { items: addressed.items, more: addressed.more, onMore: addressed.readMore }, raised: { items: raised.items, more: raised.more, onMore: raised.readMore }, decisionHref: decisionHref, fileHref: (projectKey, fileId) => projectPath(projectKey, "files", fileId), onAnswer: onAnswer, busy: busy || addressed.busy || raised.busy }))] }));
|
|
817
892
|
}
|
|
818
893
|
function WorkPage(props) {
|
|
819
894
|
const words = useWords();
|
|
@@ -832,9 +907,15 @@ function PersonWorkPage(props) {
|
|
|
832
907
|
}
|
|
833
908
|
function WorkspacePage(props) {
|
|
834
909
|
const words = useWords();
|
|
835
|
-
const { route, data, components, navigation } = props;
|
|
910
|
+
const { route, data, components, navigation, client, language } = props;
|
|
836
911
|
const [fresh, setFresh] = useState(undefined);
|
|
837
912
|
const { busy, error, act } = useAction();
|
|
913
|
+
if (route.name === "plugin" && route.level === "workspace") {
|
|
914
|
+
return (_jsx(PluginPage, { route: route, data: data, project: undefined, client: client, language: language, navigation: navigation }));
|
|
915
|
+
}
|
|
916
|
+
if (route.name === "plugins-settings") {
|
|
917
|
+
return (_jsx(PluginSettingsPage, { plugin: route.plugin, data: data, client: client, language: language, navigation: navigation }));
|
|
918
|
+
}
|
|
838
919
|
if (route.name === "work") {
|
|
839
920
|
return _jsx(WorkPage, { data: data, components: components, week: route.week });
|
|
840
921
|
}
|
|
@@ -845,7 +926,7 @@ function WorkspacePage(props) {
|
|
|
845
926
|
return _jsx(PersonWorkPage, { id: route.id, data: data, components: components, week: route.week });
|
|
846
927
|
}
|
|
847
928
|
if (route.name === "workspace-settings") {
|
|
848
|
-
return _jsx(WorkspaceSettingsPage, { form: route.form, data: data, navigation: navigation });
|
|
929
|
+
return (_jsx(WorkspaceSettingsPage, { form: route.form, data: data, navigation: navigation, language: language }));
|
|
849
930
|
}
|
|
850
931
|
if (route.name === "categories") {
|
|
851
932
|
const me = data.me?.person ?? undefined;
|
|
@@ -903,6 +984,7 @@ export function createConsole(config = {}) {
|
|
|
903
984
|
const fallbackTitle = config.title ?? "Console";
|
|
904
985
|
const languages = config.languages ?? DEFAULT_LANGUAGES;
|
|
905
986
|
const pages = config.pages ?? [];
|
|
987
|
+
// biome-ignore lint/correctness/noComponentHookFactories: createConsole runs once, when a console is built, never during a render; App is that console's one root component, closing over its config.
|
|
906
988
|
function App(props) {
|
|
907
989
|
const { location, navigation } = useNavigation(props.initialPath);
|
|
908
990
|
useFollowLinks(navigation);
|
|
@@ -949,6 +1031,7 @@ export function createConsole(config = {}) {
|
|
|
949
1031
|
href: PATHS.decisions,
|
|
950
1032
|
label: words.nav.myDecisions,
|
|
951
1033
|
current: route.name === "my-decisions",
|
|
1034
|
+
count: data.me?.decisions?.waiting,
|
|
952
1035
|
},
|
|
953
1036
|
{
|
|
954
1037
|
href: PATHS.people,
|
|
@@ -966,13 +1049,6 @@ export function createConsole(config = {}) {
|
|
|
966
1049
|
current: route.name === "agents" || route.name === "new-token",
|
|
967
1050
|
},
|
|
968
1051
|
]),
|
|
969
|
-
// The settings are read by everyone: the rules every agent follows, the categories and
|
|
970
|
-
// what the colours mean, where the skills come from; kept by an administrator.
|
|
971
|
-
{
|
|
972
|
-
href: PATHS.settings,
|
|
973
|
-
label: words.nav.settings,
|
|
974
|
-
current: route.name === "workspace-settings" || route.name === "categories",
|
|
975
|
-
},
|
|
976
1052
|
...pages
|
|
977
1053
|
.filter((candidate) => candidate.level === "workspace")
|
|
978
1054
|
.map((candidate) => ({
|
|
@@ -982,6 +1058,26 @@ export function createConsole(config = {}) {
|
|
|
982
1058
|
route.level === "workspace" &&
|
|
983
1059
|
route.page === candidate.key,
|
|
984
1060
|
})),
|
|
1061
|
+
// The plugins' tabs (ADR-0054): the groups that hold a plugin the person has a page of.
|
|
1062
|
+
...pluginNavItems({
|
|
1063
|
+
plugins: data.plugins,
|
|
1064
|
+
level: "workspace",
|
|
1065
|
+
current: {
|
|
1066
|
+
plugin: route.name === "plugin" && route.level === "workspace" ? route.plugin : undefined,
|
|
1067
|
+
},
|
|
1068
|
+
words,
|
|
1069
|
+
language: pack.tag,
|
|
1070
|
+
}),
|
|
1071
|
+
// The settings are read by everyone: the rules every agent follows, the categories and
|
|
1072
|
+
// what the colours mean, where the skills come from, the plugins; kept by an
|
|
1073
|
+
// administrator. Last, after the organization's own tabs and the plugins'.
|
|
1074
|
+
{
|
|
1075
|
+
href: PATHS.settings,
|
|
1076
|
+
label: words.nav.settings,
|
|
1077
|
+
current: route.name === "workspace-settings" ||
|
|
1078
|
+
route.name === "categories" ||
|
|
1079
|
+
route.name === "plugins-settings",
|
|
1080
|
+
},
|
|
985
1081
|
];
|
|
986
1082
|
const nav = projectKey === undefined
|
|
987
1083
|
? workspaceNav
|
|
@@ -1029,12 +1125,6 @@ export function createConsole(config = {}) {
|
|
|
1029
1125
|
label: words.nav.members,
|
|
1030
1126
|
current: route.name === "members",
|
|
1031
1127
|
},
|
|
1032
|
-
// Read by every member: what the project is, and what its agents are asked (ADR-0023).
|
|
1033
|
-
{
|
|
1034
|
-
href: projectHref(projectKey, "settings"),
|
|
1035
|
-
label: words.nav.settings,
|
|
1036
|
-
current: route.name === "settings",
|
|
1037
|
-
},
|
|
1038
1128
|
...pages
|
|
1039
1129
|
.filter((candidate) => candidate.level === "project")
|
|
1040
1130
|
.map((candidate) => ({
|
|
@@ -1044,6 +1134,23 @@ export function createConsole(config = {}) {
|
|
|
1044
1134
|
route.level === "project" &&
|
|
1045
1135
|
route.page === candidate.key,
|
|
1046
1136
|
})),
|
|
1137
|
+
...pluginNavItems({
|
|
1138
|
+
plugins: data.plugins,
|
|
1139
|
+
level: "project",
|
|
1140
|
+
project: { key: projectKey, plugins: data.projectPlugins },
|
|
1141
|
+
current: {
|
|
1142
|
+
plugin: route.name === "plugin" && route.level === "project" ? route.plugin : undefined,
|
|
1143
|
+
},
|
|
1144
|
+
words,
|
|
1145
|
+
language: pack.tag,
|
|
1146
|
+
}),
|
|
1147
|
+
// Read by every member: what the project is, and what its agents are asked
|
|
1148
|
+
// (ADR-0023). Last, after the organization's own tabs and the plugins'.
|
|
1149
|
+
{
|
|
1150
|
+
href: projectHref(projectKey, "settings"),
|
|
1151
|
+
label: words.nav.settings,
|
|
1152
|
+
current: route.name === "settings",
|
|
1153
|
+
},
|
|
1047
1154
|
];
|
|
1048
1155
|
/** A page of the console's own at the address, or nothing there. */
|
|
1049
1156
|
const customPageOf = (key, level) => {
|
|
@@ -1058,13 +1165,13 @@ export function createConsole(config = {}) {
|
|
|
1058
1165
|
page = _jsx(NotWithToken, {});
|
|
1059
1166
|
}
|
|
1060
1167
|
else if (route.name === "projects" || route.name === "new-project") {
|
|
1061
|
-
page = (_jsx(ProjectsPage, { data: data, components: components, navigation: navigation, making: route.name === "new-project" }));
|
|
1168
|
+
page = (_jsx(ProjectsPage, { data: data, components: components, navigation: navigation, client: client, language: pack.tag, making: route.name === "new-project" }));
|
|
1062
1169
|
}
|
|
1063
1170
|
else if (route.name === "custom" && route.level === "workspace") {
|
|
1064
1171
|
page = customPageOf(route.page, "workspace");
|
|
1065
1172
|
}
|
|
1066
1173
|
else if (projectKey === undefined) {
|
|
1067
|
-
page = (_jsx(WorkspacePage, { route: route, data: data, components: components, navigation: navigation }));
|
|
1174
|
+
page = (_jsx(WorkspacePage, { route: route, data: data, components: components, navigation: navigation, client: client, language: pack.tag }));
|
|
1068
1175
|
}
|
|
1069
1176
|
else if (data.projectError !== undefined) {
|
|
1070
1177
|
page = (_jsx(EmptyState, { title: words.common.noSuchProject.title, body: words.common.noSuchProject.body, action: _jsx(LinkButton, { href: PATHS.projects, children: words.nav.projects }) }));
|
|
@@ -1076,7 +1183,7 @@ export function createConsole(config = {}) {
|
|
|
1076
1183
|
page = customPageOf(route.page, "project");
|
|
1077
1184
|
}
|
|
1078
1185
|
else {
|
|
1079
|
-
page = (_jsx(ProjectPage, { route: route, project: project, data: data, components: components, navigation: navigation }));
|
|
1186
|
+
page = (_jsx(ProjectPage, { route: route, project: project, data: data, components: components, navigation: navigation, client: client, language: pack.tag }));
|
|
1080
1187
|
}
|
|
1081
1188
|
content = (_jsx(components.Shell, { title: title, brand: config.brand, project: projectKey === undefined
|
|
1082
1189
|
? undefined
|
|
@@ -1092,7 +1199,11 @@ export function createConsole(config = {}) {
|
|
|
1092
1199
|
route.name === "calendar" ||
|
|
1093
1200
|
(route.name === "goal" && route.form === undefined) ||
|
|
1094
1201
|
(route.name === "custom" &&
|
|
1095
|
-
pages.some((candidate) => candidate.key === route.page && candidate.wide === true))
|
|
1202
|
+
pages.some((candidate) => candidate.key === route.page && candidate.wide === true)) ||
|
|
1203
|
+
(route.name === "plugin" &&
|
|
1204
|
+
data.plugins.some((candidate) => candidate.key === route.plugin &&
|
|
1205
|
+
pluginPagesAt(candidate, route.level).some((candidate, index) => candidate.wide &&
|
|
1206
|
+
(route.page === undefined ? index === 0 : candidate.key === route.page)))), onNavigate: (href) => navigation.go(href), onSignOut: viaToken ? undefined : () => void data.actions.signOut(), children: page }));
|
|
1096
1207
|
}
|
|
1097
1208
|
return (_jsx(LanguageContext.Provider, { value: pack, children: _jsx(RemotePicturesContext.Provider, { value: pictureSrc, children: content }) }));
|
|
1098
1209
|
}
|