@skillcdn/console 0.3.0 → 0.3.1

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.
Files changed (129) hide show
  1. package/README.md +3 -3
  2. package/dist/api.d.ts +2 -2
  3. package/dist/api.d.ts.map +1 -1
  4. package/dist/api.js +2 -2
  5. package/dist/api.js.map +1 -1
  6. package/dist/cli/cli.d.ts +1 -1
  7. package/dist/cli/cli.d.ts.map +1 -1
  8. package/dist/cli/cli.js +185 -28
  9. package/dist/cli/cli.js.map +1 -1
  10. package/dist/cli/credentials.d.ts +5 -0
  11. package/dist/cli/credentials.d.ts.map +1 -1
  12. package/dist/cli/credentials.js +2 -0
  13. package/dist/cli/credentials.js.map +1 -1
  14. package/dist/cli/directory.d.ts +7 -0
  15. package/dist/cli/directory.d.ts.map +1 -1
  16. package/dist/cli/directory.js +7 -0
  17. package/dist/cli/directory.js.map +1 -1
  18. package/dist/cli/format.d.ts +10 -1
  19. package/dist/cli/format.d.ts.map +1 -1
  20. package/dist/cli/format.js +67 -13
  21. package/dist/cli/format.js.map +1 -1
  22. package/dist/cli/help.d.ts.map +1 -1
  23. package/dist/cli/help.js +30 -13
  24. package/dist/cli/help.js.map +1 -1
  25. package/dist/client.d.ts +26 -1
  26. package/dist/client.d.ts.map +1 -1
  27. package/dist/client.js +14 -1
  28. package/dist/client.js.map +1 -1
  29. package/dist/components/calendar.d.ts +5 -1
  30. package/dist/components/calendar.d.ts.map +1 -1
  31. package/dist/components/calendar.js +3 -3
  32. package/dist/components/calendar.js.map +1 -1
  33. package/dist/components/event-feed.d.ts.map +1 -1
  34. package/dist/components/event-feed.js +2 -0
  35. package/dist/components/event-feed.js.map +1 -1
  36. package/dist/components/pack-connect.d.ts +23 -0
  37. package/dist/components/pack-connect.d.ts.map +1 -0
  38. package/dist/components/pack-connect.js +86 -0
  39. package/dist/components/pack-connect.js.map +1 -0
  40. package/dist/components/pack-token.d.ts +27 -0
  41. package/dist/components/pack-token.d.ts.map +1 -0
  42. package/dist/components/pack-token.js +11 -0
  43. package/dist/components/pack-token.js.map +1 -0
  44. package/dist/components/projects.d.ts +13 -0
  45. package/dist/components/projects.d.ts.map +1 -1
  46. package/dist/components/projects.js +37 -5
  47. package/dist/components/projects.js.map +1 -1
  48. package/dist/components/work.d.ts +3 -1
  49. package/dist/components/work.d.ts.map +1 -1
  50. package/dist/components/work.js +1 -1
  51. package/dist/components/work.js.map +1 -1
  52. package/dist/components/workspace.d.ts +46 -0
  53. package/dist/components/workspace.d.ts.map +1 -0
  54. package/dist/components/workspace.js +124 -0
  55. package/dist/components/workspace.js.map +1 -0
  56. package/dist/console.css +156 -0
  57. package/dist/console.d.ts.map +1 -1
  58. package/dist/console.js +60 -21
  59. package/dist/console.js.map +1 -1
  60. package/dist/data.d.ts +16 -1
  61. package/dist/data.d.ts.map +1 -1
  62. package/dist/data.js +37 -0
  63. package/dist/data.js.map +1 -1
  64. package/dist/dates.d.ts +12 -2
  65. package/dist/dates.d.ts.map +1 -1
  66. package/dist/dates.js +20 -2
  67. package/dist/dates.js.map +1 -1
  68. package/dist/i18n/en.d.ts +53 -0
  69. package/dist/i18n/en.d.ts.map +1 -1
  70. package/dist/i18n/en.js +65 -8
  71. package/dist/i18n/en.js.map +1 -1
  72. package/dist/i18n/ko.d.ts.map +1 -1
  73. package/dist/i18n/ko.js +60 -7
  74. package/dist/i18n/ko.js.map +1 -1
  75. package/dist/index.d.ts +3 -0
  76. package/dist/index.d.ts.map +1 -1
  77. package/dist/index.js +3 -0
  78. package/dist/index.js.map +1 -1
  79. package/dist/router.d.ts +4 -4
  80. package/dist/router.d.ts.map +1 -1
  81. package/dist/router.js +11 -2
  82. package/dist/router.js.map +1 -1
  83. package/dist/routes.d.ts +4 -0
  84. package/dist/routes.d.ts.map +1 -1
  85. package/dist/routes.js +4 -0
  86. package/dist/routes.js.map +1 -1
  87. package/dist/schemas.d.ts +182 -2
  88. package/dist/schemas.d.ts.map +1 -1
  89. package/dist/schemas.js +110 -13
  90. package/dist/schemas.js.map +1 -1
  91. package/dist/vocabulary.d.ts +19 -1
  92. package/dist/vocabulary.d.ts.map +1 -1
  93. package/dist/vocabulary.js +16 -0
  94. package/dist/vocabulary.js.map +1 -1
  95. package/docs/specs/cli.md +16 -11
  96. package/docs/specs/rest.md +31 -8
  97. package/package.json +2 -2
  98. package/skills/building-a-console/SKILL.md +5 -5
  99. package/skills/building-a-console/references/the-look-from-a-website.md +39 -0
  100. package/skills/deploying-a-console/SKILL.md +8 -7
  101. package/skills/working-the-board/SKILL.md +2 -2
  102. package/skills/working-the-board/references/setting-up.md +1 -1
  103. package/skills/working-the-board/references/terms.md +2 -0
  104. package/skills/working-the-board/references/the-sentence.md +1 -1
  105. package/src/api.ts +16 -0
  106. package/src/cli/cli.ts +253 -33
  107. package/src/cli/credentials.ts +7 -0
  108. package/src/cli/directory.ts +9 -0
  109. package/src/cli/format.ts +72 -13
  110. package/src/cli/help.ts +36 -13
  111. package/src/client.ts +84 -0
  112. package/src/components/calendar.tsx +8 -2
  113. package/src/components/event-feed.tsx +2 -0
  114. package/src/components/pack-connect.tsx +179 -0
  115. package/src/components/pack-token.tsx +74 -0
  116. package/src/components/projects.tsx +108 -9
  117. package/src/components/work.tsx +4 -1
  118. package/src/components/workspace.tsx +298 -0
  119. package/src/console.tsx +173 -29
  120. package/src/data.ts +57 -0
  121. package/src/dates.ts +23 -2
  122. package/src/i18n/en.ts +76 -8
  123. package/src/i18n/ko.ts +67 -7
  124. package/src/index.ts +16 -0
  125. package/src/router.ts +17 -5
  126. package/src/routes.ts +4 -0
  127. package/src/schemas.ts +129 -12
  128. package/src/styles/console.css +156 -0
  129. package/src/vocabulary.ts +25 -0
package/dist/console.css CHANGED
@@ -1177,6 +1177,7 @@ table {
1177
1177
  display: grid;
1178
1178
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
1179
1179
  gap: var(--sc-space-4);
1180
+ align-items: start;
1180
1181
  }
1181
1182
 
1182
1183
  .sc-input {
@@ -4130,3 +4131,158 @@ table {
4130
4131
  .sc-goal-view-list {
4131
4132
  display: block;
4132
4133
  }
4134
+
4135
+ /* The workspace's settings (ADR-0035): each setting a row, its name beside its value; on the form,
4136
+ its name and its hint beside a control of a bounded width, so that a short choice is not a
4137
+ field as wide as the page. */
4138
+ .sc-settings-list {
4139
+ display: grid;
4140
+ margin: 0;
4141
+ font-size: var(--sc-text-sm);
4142
+ }
4143
+
4144
+ .sc-settings-item {
4145
+ display: grid;
4146
+ grid-template-columns: minmax(8rem, 14rem) minmax(0, 1fr);
4147
+ gap: var(--sc-space-1) var(--sc-space-5);
4148
+ padding: var(--sc-space-3) 0;
4149
+ border-top: var(--sc-border);
4150
+ }
4151
+
4152
+ .sc-settings-item:first-child {
4153
+ padding-top: 0;
4154
+ border-top: 0;
4155
+ }
4156
+
4157
+ .sc-settings-item:last-child {
4158
+ padding-bottom: 0;
4159
+ }
4160
+
4161
+ .sc-settings-item dt {
4162
+ color: var(--sc-color-text-muted);
4163
+ }
4164
+
4165
+ .sc-settings-item dd {
4166
+ margin: 0;
4167
+ }
4168
+
4169
+ .sc-settings-note {
4170
+ margin-left: var(--sc-space-3);
4171
+ color: var(--sc-color-text-muted);
4172
+ }
4173
+
4174
+ .sc-settings-form {
4175
+ gap: 0;
4176
+ }
4177
+
4178
+ .sc-settings-row {
4179
+ display: grid;
4180
+ grid-template-columns: minmax(0, 1fr) minmax(14rem, 20rem);
4181
+ gap: var(--sc-space-3) var(--sc-space-6);
4182
+ align-items: start;
4183
+ padding: var(--sc-space-4) 0;
4184
+ border-top: var(--sc-border);
4185
+ }
4186
+
4187
+ .sc-settings-row:first-child {
4188
+ padding-top: 0;
4189
+ border-top: 0;
4190
+ }
4191
+
4192
+ .sc-settings-label {
4193
+ display: block;
4194
+ font-weight: var(--sc-weight-medium);
4195
+ }
4196
+
4197
+ .sc-settings-hint {
4198
+ max-width: var(--sc-width-prose);
4199
+ margin: var(--sc-space-1) 0 0;
4200
+ color: var(--sc-color-text-muted);
4201
+ font-size: var(--sc-text-sm);
4202
+ }
4203
+
4204
+ .sc-settings-control {
4205
+ display: grid;
4206
+ justify-items: start;
4207
+ gap: var(--sc-space-2);
4208
+ }
4209
+
4210
+ .sc-settings-control .sc-input {
4211
+ width: 100%;
4212
+ }
4213
+
4214
+ .sc-settings-form .sc-form-actions {
4215
+ padding-top: var(--sc-space-4);
4216
+ border-top: var(--sc-border);
4217
+ }
4218
+
4219
+ @media (max-width: 40rem) {
4220
+ .sc-settings-item,
4221
+ .sc-settings-row {
4222
+ grid-template-columns: minmax(0, 1fr);
4223
+ }
4224
+ }
4225
+
4226
+ /* The pack token (ADR-0028, ADR-0036): what it is for first, then the two ways to one side by
4227
+ side, each a card with its words before its controls, and the code shown large while the
4228
+ page waits for the approval. */
4229
+ .sc-pack-intro {
4230
+ max-width: var(--sc-width-prose);
4231
+ margin: 0 0 var(--sc-space-5);
4232
+ color: var(--sc-color-text-muted);
4233
+ font-size: var(--sc-text-sm);
4234
+ }
4235
+
4236
+ .sc-pack-ways {
4237
+ display: grid;
4238
+ grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr));
4239
+ gap: var(--sc-space-4);
4240
+ }
4241
+
4242
+ .sc-pack-way {
4243
+ display: grid;
4244
+ align-content: start;
4245
+ gap: var(--sc-space-3);
4246
+ padding: var(--sc-space-4);
4247
+ border: var(--sc-border);
4248
+ border-radius: var(--sc-radius-lg);
4249
+ background: var(--sc-color-sheet);
4250
+ }
4251
+
4252
+ .sc-pack-way-title {
4253
+ font-size: var(--sc-text-md);
4254
+ font-weight: var(--sc-weight-medium);
4255
+ }
4256
+
4257
+ .sc-pack-way .sc-field-hint {
4258
+ margin-top: 0;
4259
+ }
4260
+
4261
+ .sc-pack-connect {
4262
+ display: grid;
4263
+ gap: var(--sc-space-3);
4264
+ }
4265
+
4266
+ .sc-pack-connect-code {
4267
+ display: flex;
4268
+ flex-wrap: wrap;
4269
+ align-items: baseline;
4270
+ gap: var(--sc-space-3);
4271
+ }
4272
+
4273
+ .sc-pack-code {
4274
+ font-size: var(--sc-text-xl);
4275
+ letter-spacing: 0.12em;
4276
+ }
4277
+
4278
+ .sc-pack-connect-waiting {
4279
+ display: flex;
4280
+ align-items: center;
4281
+ gap: var(--sc-space-2);
4282
+ color: var(--sc-color-text-muted);
4283
+ font-size: var(--sc-text-sm);
4284
+ }
4285
+
4286
+ .sc-pack-actions {
4287
+ margin-top: var(--sc-space-5);
4288
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"console.d.ts","sourceRoot":"","sources":["../src/console.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"console.d.ts","sourceRoot":"","sources":["../src/console.tsx"],"names":[],"mappings":"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"}
package/dist/console.js CHANGED
@@ -10,9 +10,10 @@ import { DecisionForm } from "./components/decision-form.js";
10
10
  import { DecisionCard, DecisionList } from "./components/decision-list.js";
11
11
  import { EventFeed } from "./components/event-feed.js";
12
12
  import { GoalForm, GoalList, GoalView, goalMonth } from "./components/goals.js";
13
+ import { PackTokenWays } from "./components/pack-token.js";
13
14
  import { PAGE_SIZE } from "./components/paged.js";
14
15
  import { ListingForm, PeopleList } from "./components/people.js";
15
- import { MemberList, PackTokenForm, ProjectForm, ProjectList, ProjectMark, } from "./components/projects.js";
16
+ import { MemberList, ProjectForm, ProjectList, ProjectMark, } from "./components/projects.js";
16
17
  import { GoalTimeline } from "./components/roadmap.js";
17
18
  import { RulesForm, RulesView } from "./components/rules.js";
18
19
  import { isPlainClick, Shell, } from "./components/shell.js";
@@ -24,6 +25,7 @@ import { TaskView } from "./components/task-view.js";
24
25
  import { NewToken, TokenForm, TokenList } from "./components/tokens.js";
25
26
  import { Button, Callout, CategoryBadge, EmptyState, personName, Spinner, StateBadge, Time, } from "./components/ui.js";
26
27
  import { WorkList } from "./components/work.js";
28
+ import { peopleVisibilityOf, WorkspaceSettingsForm, WorkspaceSettingsView, weekStartOf, } from "./components/workspace.js";
27
29
  import { ConnectPage } from "./connect-page.js";
28
30
  import { useConsoleData } from "./data.js";
29
31
  import { monthOf, today } from "./dates.js";
@@ -379,7 +381,7 @@ function ProjectPage(props) {
379
381
  const overdue = open.filter((task) => task.dueOn !== null && task.dueOn < now).sort(byDue);
380
382
  const unscheduled = open.filter((task) => task.dueOn === null).sort(byDue);
381
383
  const calendar = words.calendar;
382
- return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "sc-page-head", children: [_jsx("h1", { className: "sc-page-title", children: calendar.title }), _jsx(LinkButton, { href: newTaskHref(key), variant: "primary", children: words.board.writeTask })] }), data.tasks.length > 0 && (_jsx(BoardFilters, { filter: route.filter, categories: data.categories, goals: data.goals, people: data.people.filter(inWorkspace), me: me, shown: shown.length, total: data.tasks.length, onChange: (filter) => navigation.replace(calendarHref(key, route.month, filter)) })), _jsx(components.Calendar, { tasks: shown, month: month, today: now, categories: data.categories, goals: data.goals, taskHref: href, goalHref: (goal) => goalHref(key, goal.id), monthHref: (wanted) => calendarHref(key, wanted, route.filter) }), _jsxs("div", { className: "sc-calendar-below", children: [_jsxs("section", { className: "sc-task-section", "aria-label": calendar.overdue, children: [_jsxs("h2", { className: "sc-section-title", children: [calendar.overdue, " ", _jsx("span", { className: "sc-column-count", children: overdue.length })] }), _jsx(TaskList, { tasks: overdue, taskHref: href, today: now, showState: true, empty: _jsx("p", { className: "sc-muted", children: calendar.nothingOverdue }) })] }), _jsxs("section", { className: "sc-task-section", "aria-label": calendar.unscheduled, children: [_jsxs("h2", { className: "sc-section-title", children: [calendar.unscheduled, " ", _jsx("span", { className: "sc-column-count", children: unscheduled.length })] }), _jsx(TaskList, { tasks: unscheduled, taskHref: href, today: now, showState: true, empty: _jsx("p", { className: "sc-muted", children: calendar.allScheduled }) })] })] }), open.length > 0 && (_jsxs("section", { className: "sc-task-section", "aria-label": calendar.workload.title, children: [_jsx("h2", { className: "sc-section-title", children: calendar.workload.title }), _jsx(Workload, { tasks: shown, today: now, personHref: (person) => boardHref(key, person === undefined ? {} : { person: person.id }) })] }))] }));
384
+ return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "sc-page-head", children: [_jsx("h1", { className: "sc-page-title", children: calendar.title }), _jsx(LinkButton, { href: newTaskHref(key), variant: "primary", children: words.board.writeTask })] }), data.tasks.length > 0 && (_jsx(BoardFilters, { filter: route.filter, categories: data.categories, goals: data.goals, people: data.people.filter(inWorkspace), me: me, shown: shown.length, total: data.tasks.length, onChange: (filter) => navigation.replace(calendarHref(key, route.month, filter)) })), _jsx(components.Calendar, { tasks: shown, month: month, today: now, weekStart: weekStartOf(data.me?.workspace), categories: data.categories, goals: data.goals, taskHref: href, goalHref: (goal) => goalHref(key, goal.id), monthHref: (wanted) => calendarHref(key, wanted, route.filter) }), _jsxs("div", { className: "sc-calendar-below", children: [_jsxs("section", { className: "sc-task-section", "aria-label": calendar.overdue, children: [_jsxs("h2", { className: "sc-section-title", children: [calendar.overdue, " ", _jsx("span", { className: "sc-column-count", children: overdue.length })] }), _jsx(TaskList, { tasks: overdue, taskHref: href, today: now, showState: true, empty: _jsx("p", { className: "sc-muted", children: calendar.nothingOverdue }) })] }), _jsxs("section", { className: "sc-task-section", "aria-label": calendar.unscheduled, children: [_jsxs("h2", { className: "sc-section-title", children: [calendar.unscheduled, " ", _jsx("span", { className: "sc-column-count", children: unscheduled.length })] }), _jsx(TaskList, { tasks: unscheduled, taskHref: href, today: now, showState: true, empty: _jsx("p", { className: "sc-muted", children: calendar.allScheduled }) })] })] }), open.length > 0 && (_jsxs("section", { className: "sc-task-section", "aria-label": calendar.workload.title, children: [_jsx("h2", { className: "sc-section-title", children: calendar.workload.title }), _jsx(Workload, { tasks: shown, today: now, personHref: (person) => boardHref(key, person === undefined ? {} : { person: person.id }) })] }))] }));
383
385
  }
384
386
  if (route.name === "roadmap" || route.name === "new-goal") {
385
387
  const roadmap = words.roadmap;
@@ -425,7 +427,7 @@ function ProjectPage(props) {
425
427
  })
426
428
  : undefined, onArchiveTasks: owner && towards.some((task) => !OPEN_TASK_STATES.includes(task.state))
427
429
  ? () => void act(() => data.actions.archiveGoalTasks(goal.id))
428
- : undefined, busy: busy, view: route.view, viewHref: viewHref, board: _jsx(components.Board, { tasks: towards, taskHref: href, onOpen: (task) => navigation.go(href(task)), onMove: onMove, today: now, editHref: (task) => taskHref(key, task.number, "edit"), onEdit: (task) => navigation.go(taskHref(key, task.number, "edit")), onArchive: (task) => void act(() => data.actions.archiveTask(task.id)), empty: towards.length === 0 ? _jsx("p", { className: "sc-muted", children: roadmap.noTasks }) : undefined }), calendar: _jsx(components.Calendar, { tasks: towards, month: month, today: now, categories: data.categories, goals: [goal], taskHref: href, goalHref: (target) => goalHref(key, target.id), monthHref: (wanted) => goalHref(key, goal.id, { view: "calendar", month: wanted }) }) })] }));
430
+ : undefined, busy: busy, view: route.view, viewHref: viewHref, board: _jsx(components.Board, { tasks: towards, taskHref: href, onOpen: (task) => navigation.go(href(task)), onMove: onMove, today: now, editHref: (task) => taskHref(key, task.number, "edit"), onEdit: (task) => navigation.go(taskHref(key, task.number, "edit")), onArchive: (task) => void act(() => data.actions.archiveTask(task.id)), empty: towards.length === 0 ? _jsx("p", { className: "sc-muted", children: roadmap.noTasks }) : undefined }), calendar: _jsx(components.Calendar, { tasks: towards, month: month, today: now, weekStart: weekStartOf(data.me?.workspace), categories: data.categories, goals: [goal], taskHref: href, goalHref: (target) => goalHref(key, target.id), monthHref: (wanted) => goalHref(key, goal.id, { view: "calendar", month: wanted }) }) })] }));
429
431
  }
430
432
  if (route.name === "docs") {
431
433
  return (_jsx(DocsPage, { project: project, path: route.path, view: route.view, data: data, navigation: navigation }));
@@ -472,9 +474,17 @@ function ProjectPage(props) {
472
474
  const me = data.me?.person ?? undefined;
473
475
  const configures = owner;
474
476
  const members = words.projects.members;
475
- return (_jsxs(_Fragment, { children: [_jsx("div", { className: "sc-page-head", children: _jsx("h1", { className: "sc-page-title", children: members.title }) }), _jsx("p", { className: "sc-lead", children: words.vocabulary.visibility[project.visibility] }), error !== undefined && _jsx(Callout, { tone: "danger", children: error }), _jsx(components.MemberList, { members: data.members, people: data.people.filter(inWorkspace), me: me, busy: busy, onAdd: configures ? (input) => void act(() => data.actions.addMember(input)) : undefined, onChangeRole: configures
477
+ // In a project open to the workspace everyone is a member already (ADR-0035): the list is
478
+ // everyone, nobody is added or removed, and an owner is made from a row. Where the People
479
+ // page shows a member only whom they share a project with, an owner lists someone the list
480
+ // does not show by their login.
481
+ const open = project.visibility === "workspace";
482
+ const narrowed = peopleVisibilityOf(data.me?.workspace) === "shared_projects" && me?.role !== "admin";
483
+ return (_jsxs(_Fragment, { children: [_jsx("div", { className: "sc-page-head", children: _jsx("h1", { className: "sc-page-title", children: members.title }) }), open && _jsx("p", { className: "sc-lead", children: members.open }), error !== undefined && _jsx(Callout, { tone: "danger", children: error }), _jsx(components.MemberList, { members: data.members, people: data.people.filter(inWorkspace), me: me, open: open, busy: busy, onAdd: configures && !open
484
+ ? (input) => void act(() => data.actions.addMember(input))
485
+ : undefined, lookup: configures && !open && narrowed ? (login) => data.actions.findPerson(login) : undefined, onChangeRole: configures
476
486
  ? (member, role) => void act(() => data.actions.updateMember(member.person.id, { role }))
477
- : undefined, onRemove: configures
487
+ : undefined, onRemove: configures && !open
478
488
  ? (member) => void act(() => data.actions.removeMember(member.person.id))
479
489
  : undefined, workHref: owner ? (member) => personWorkHref(member.person.id) : undefined, empty: _jsx(EmptyState, { title: members.empty.title, body: project.visibility === "workspace" ? members.empty.workspace : members.empty.private }) })] }));
480
490
  }
@@ -546,17 +556,17 @@ function ProjectSettingsPage(props) {
546
556
  if (!owner) {
547
557
  return _jsx(NothingHere, {});
548
558
  }
549
- return (_jsxs(_Fragment, { children: [head, error !== undefined && _jsx(Callout, { tone: "danger", children: error }), _jsx("section", { className: "sc-panel sc-panel-form", "aria-label": words.projects.packToken.aria, children: _jsx(PackTokenForm, { set: project.packToken !== null, busy: busy, onSubmit: (token) => void act(async () => {
550
- await data.actions.setPackToken(token);
559
+ return (_jsxs(_Fragment, { children: [head, error !== undefined && _jsx(Callout, { tone: "danger", children: error }), _jsx(PackTokenWays, { title: settings.packToken, intro: words.projects.packToken.intro, set: project.packToken !== null, setAt: project.packToken?.setAt, busy: busy, onStart: data.actions.connectPackToken, poll: data.actions.packTokenConnection, onCancelConnect: data.actions.cancelPackTokenConnection, onConnected: () => navigation.replace(here), onSubmit: (token) => void act(async () => {
560
+ await data.actions.setPackToken(token);
561
+ navigation.replace(here);
562
+ }), onRemove: project.packToken === null
563
+ ? undefined
564
+ : () => void act(async () => {
565
+ await data.actions.removePackToken();
551
566
  navigation.replace(here);
552
- }), onRemove: project.packToken === null
553
- ? undefined
554
- : () => void act(async () => {
555
- await data.actions.removePackToken();
556
- navigation.replace(here);
557
- }), onCancel: () => navigation.back(here) }) })] }));
567
+ }), onBack: () => navigation.back(here) })] }));
558
568
  }
559
- return (_jsxs(_Fragment, { children: [head, error !== undefined && _jsx(Callout, { tone: "danger", children: error }), _jsx("section", { className: "sc-panel", "aria-label": settings.aria, children: _jsxs("dl", { className: "sc-facts sc-facts-plain", children: [_jsxs("div", { children: [_jsx("dt", { children: form.name }), _jsx("dd", { children: project.name })] }), _jsxs("div", { children: [_jsx("dt", { children: form.key }), _jsx("dd", { children: _jsx("code", { className: "sc-project-key", children: project.key }) })] }), _jsxs("div", { children: [_jsx("dt", { children: form.whoIsMember }), _jsx("dd", { children: words.vocabulary.visibility[project.visibility] })] }), _jsxs("div", { children: [_jsx("dt", { children: form.skillsAddress }), _jsx("dd", { children: project.skillsAddress !== null ? (_jsxs("code", { children: [skills?.source ?? "", project.skillsAddress] })) : skills?.address != null ? (settings.organizationsSkills(skills.address)) : (settings.noSkills) })] }), _jsxs("div", { children: [_jsx("dt", { children: settings.packToken }), _jsxs("dd", { children: [project.packToken === null ? (_jsx("span", { className: "sc-muted", children: settings.packTokenNone })) : (_jsxs(_Fragment, { children: [settings.packTokenSet, " ", _jsx(Time, { iso: project.packToken.setAt })] })), owner && (_jsxs(_Fragment, { children: [" ", _jsx("a", { href: projectSettingsHref(key, "pack-token"), children: settings.packTokenEdit })] }))] })] }), _jsxs("div", { children: [_jsx("dt", { children: form.symbol }), _jsx("dd", { children: _jsx(ProjectMark, { project: project, size: "sm" }) })] }), project.description.length > 0 && (_jsxs("div", { className: "sc-facts-wide", children: [_jsx("dt", { children: form.description }), _jsx("dd", { children: project.description })] }))] }) }), _jsxs("section", { className: "sc-panel", "aria-label": words.rules.projectRules, children: [_jsx("h2", { className: "sc-section-title", children: words.rules.projectRules }), rules === undefined ? (_jsx(Spinner, { label: words.rules.loading })) : (_jsx(RulesView, { rules: rules.project, scope: "project", docHref: (path) => docHref(key, path), editHref: owner ? projectSettingsHref(key, "rules") : undefined, onArchive: owner
569
+ return (_jsxs(_Fragment, { children: [head, error !== undefined && _jsx(Callout, { tone: "danger", children: error }), _jsx("section", { className: "sc-panel", "aria-label": settings.aria, children: _jsxs("dl", { className: "sc-facts sc-facts-plain", children: [_jsxs("div", { children: [_jsx("dt", { children: form.name }), _jsx("dd", { children: project.name })] }), _jsxs("div", { children: [_jsx("dt", { children: form.key }), _jsx("dd", { children: _jsx("code", { className: "sc-project-key", children: project.key }) })] }), _jsxs("div", { children: [_jsx("dt", { children: form.whoIsMember }), _jsx("dd", { children: words.vocabulary.visibility[project.visibility] })] }), _jsxs("div", { children: [_jsx("dt", { children: form.skillsAddress }), _jsx("dd", { children: project.skillsAddress !== null ? (_jsxs("code", { children: [skills?.source ?? "", project.skillsAddress] })) : skills?.address != null ? (settings.organizationsSkills(skills.address)) : (settings.noSkills) })] }), _jsxs("div", { children: [_jsx("dt", { children: settings.packToken }), _jsxs("dd", { children: [project.packToken === null ? (_jsx("span", { className: "sc-muted", children: settings.packTokenNone })) : (_jsxs(_Fragment, { children: [settings.packTokenSet, " ", _jsx(Time, { iso: project.packToken.setAt })] })), owner && (_jsxs(_Fragment, { children: [" ", _jsx("a", { href: projectSettingsHref(key, "pack-token"), children: project.packToken === null ? settings.packTokenAdd : settings.packTokenEdit })] }))] })] }), _jsxs("div", { children: [_jsx("dt", { children: form.symbol }), _jsx("dd", { children: _jsx(ProjectMark, { project: project, size: "sm" }) })] }), project.description.length > 0 && (_jsxs("div", { className: "sc-facts-wide", children: [_jsx("dt", { children: form.description }), _jsx("dd", { children: project.description })] }))] }) }), _jsxs("section", { className: "sc-panel", "aria-label": words.rules.projectRules, children: [_jsx("h2", { className: "sc-section-title", children: words.rules.projectRules }), rules === undefined ? (_jsx(Spinner, { label: words.rules.loading })) : (_jsx(RulesView, { rules: rules.project, scope: "project", docHref: (path) => docHref(key, path), editHref: owner ? projectSettingsHref(key, "rules") : undefined, onArchive: owner
560
570
  ? () => void act(async () => {
561
571
  await data.actions.archiveDocument(RULES_PATH);
562
572
  setRules(await data.actions.projectRules());
@@ -573,7 +583,8 @@ function WorkspaceSettingsPage(props) {
573
583
  const { form, data, navigation } = props;
574
584
  const { busy, error, act } = useAction();
575
585
  const administrator = data.me?.person?.role === "admin";
576
- const skills = data.me?.workspace.skills;
586
+ const workspace = data.me?.workspace;
587
+ const skills = workspace?.skills;
577
588
  const [rules, setRules] = useState(undefined);
578
589
  useEffect(() => {
579
590
  const controller = new AbortController();
@@ -605,11 +616,37 @@ function WorkspaceSettingsPage(props) {
605
616
  navigation.replace(PATHS.settings);
606
617
  }) })) })] }));
607
618
  }
608
- return (_jsxs(_Fragment, { children: [head, error !== undefined && _jsx(Callout, { tone: "danger", children: error }), _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
619
+ if (form === "pack-token") {
620
+ if (!administrator || workspace === undefined) {
621
+ return _jsx(NothingHere, {});
622
+ }
623
+ const held = workspace.skills.packToken ?? null;
624
+ return (_jsxs(_Fragment, { children: [head, error !== undefined && _jsx(Callout, { tone: "danger", children: error }), _jsx(PackTokenWays, { title: words.settings.skillsToken, intro: words.settings.skillsTokenIntro, set: held !== null, setAt: held?.setAt, busy: busy, onStart: data.actions.connectWorkspacePackToken, poll: data.actions.workspacePackTokenConnection, onCancelConnect: data.actions.cancelWorkspacePackTokenConnection, onConnected: () => navigation.replace(PATHS.settings), onSubmit: (token) => void act(async () => {
625
+ await data.actions.setWorkspacePackToken(token);
626
+ navigation.replace(PATHS.settings);
627
+ }), onRemove: held === null
628
+ ? undefined
629
+ : () => void act(async () => {
630
+ await data.actions.removeWorkspacePackToken();
631
+ navigation.replace(PATHS.settings);
632
+ }), onBack: () => navigation.back(PATHS.settings) })] }));
633
+ }
634
+ if (form === "workspace") {
635
+ if (!administrator || workspace === undefined) {
636
+ return _jsx(NothingHere, {});
637
+ }
638
+ return (_jsxs(_Fragment, { children: [head, error !== undefined && _jsx(Callout, { tone: "danger", children: error }), _jsxs("section", { className: "sc-panel sc-panel-form", "aria-label": words.settings.workspace.aria, children: [_jsx("h2", { className: "sc-section-title", children: words.settings.workspace.title }), _jsx(WorkspaceSettingsForm, { workspace: workspace, busy: busy, onSubmit: (patch) => void act(async () => {
639
+ await data.actions.updateWorkspace(patch);
640
+ navigation.replace(PATHS.settings);
641
+ }), onCancel: () => navigation.back(PATHS.settings) })] })] }));
642
+ }
643
+ 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
609
644
  ? () => void act(async () => {
610
645
  setRules(await data.actions.archiveRules());
611
646
  })
612
- : 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 }) })) })] })] }), _jsx("p", { className: "sc-muted", children: words.settings.skillsFromConfiguration })] }))] }));
647
+ : 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
648
+ ? words.projects.settings.packTokenAdd
649
+ : words.projects.settings.packTokenEdit })] }))] })] }))] }), _jsx("p", { className: "sc-muted", children: words.settings.skillsFromConfiguration })] }))] }));
613
650
  }
614
651
  /** A file a person chose, as the client sends it: its name, its bytes and the type the browser says. */
615
652
  /** Whether a person is in: who a picker of assignees and of members offers (ADR-0022). */
@@ -695,13 +732,13 @@ function PlatePage(props) {
695
732
  }, [load, couldNotLoad, refused]);
696
733
  return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "sc-page-head", children: [_jsx("h1", { className: "sc-page-title", children: props.title }), props.aside] }), problem !== undefined && _jsx(Callout, { tone: "danger", children: problem }), forbidden && refused !== undefined ? (_jsx(EmptyState, { title: refused.title, body: refused.body, action: _jsx(LinkButton, { href: PATHS.work, children: words.nav.work }) })) : plate === undefined ? (problem === undefined && (_jsx("div", { className: "sc-loading", children: _jsx(Spinner, { label: props.loading }) }))) : plate.tasks.length === 0 &&
697
734
  (plate.closed?.length ?? 0) === 0 &&
698
- (plate.decisions?.length ?? 0) === 0 ? (_jsx(EmptyState, { title: props.empty.title, body: props.empty.body })) : (_jsx(components.WorkList, { work: plate, week: props.week, taskHref: (projectKey, task) => taskHref(projectKey, task.number), decisionHref: (projectKey, decisionId) => decisionHref(projectKey, decisionId), weekHref: props.weekHref }))] }));
735
+ (plate.decisions?.length ?? 0) === 0 ? (_jsx(EmptyState, { title: props.empty.title, body: props.empty.body })) : (_jsx(components.WorkList, { work: plate, week: props.week, weekStart: props.weekStart, taskHref: (projectKey, task) => taskHref(projectKey, task.number), decisionHref: (projectKey, decisionId) => decisionHref(projectKey, decisionId), weekHref: props.weekHref }))] }));
699
736
  }
700
737
  /** What is on the person's own plate, across their projects. */
701
738
  function WorkPage(props) {
702
739
  const words = useWords();
703
740
  const { work } = props.data.actions;
704
- return (_jsx(PlatePage, { components: props.components, load: work, title: words.work.title, week: props.week, weekHref: workHref, loading: words.work.loading, couldNotLoad: words.work.couldNotLoad, empty: words.work.empty }));
741
+ return (_jsx(PlatePage, { components: props.components, load: work, title: words.work.title, week: props.week, weekStart: weekStartOf(props.data.me?.workspace), weekHref: workHref, loading: words.work.loading, couldNotLoad: words.work.couldNotLoad, empty: words.work.empty }));
705
742
  }
706
743
  /** Another person's plate, for whoever oversees them: an administrator, or an owner of a project they are in. */
707
744
  function PersonWorkPage(props) {
@@ -711,7 +748,7 @@ function PersonWorkPage(props) {
711
748
  const name = person === undefined ? "?" : personName(person);
712
749
  const { personWork } = data.actions;
713
750
  const load = useCallback((signal) => personWork(id, signal), [personWork, id]);
714
- return (_jsx(PlatePage, { components: props.components, load: load, title: words.people.workOf(name), aside: _jsx(LinkButton, { href: PATHS.people, children: words.nav.people }), week: props.week, weekHref: (day) => personWorkHref(id, day), loading: words.people.loadingWork, couldNotLoad: words.people.couldNotLoadWork, empty: { title: words.people.noWork.title(name), body: words.people.noWork.body }, refused: words.people.notOverseen }));
751
+ return (_jsx(PlatePage, { components: props.components, load: load, title: words.people.workOf(name), aside: _jsx(LinkButton, { href: PATHS.people, children: words.nav.people }), week: props.week, weekStart: weekStartOf(data.me?.workspace), weekHref: (day) => personWorkHref(id, day), loading: words.people.loadingWork, couldNotLoad: words.people.couldNotLoadWork, empty: { title: words.people.noWork.title(name), body: words.people.noWork.body }, refused: words.people.notOverseen }));
715
752
  }
716
753
  function WorkspacePage(props) {
717
754
  const words = useWords();
@@ -745,7 +782,9 @@ function WorkspacePage(props) {
745
782
  const making = route.name === "new-listing" && administrator;
746
783
  // An owner sees the work of the people in their projects; the console refuses the rest.
747
784
  const oversees = administrator || data.projects.some((project) => project.role === "owner");
748
- return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "sc-page-head", children: [_jsx("h1", { className: "sc-page-title", children: words.people.title }), administrator && !making && (_jsx(LinkButton, { href: PATHS.newListing, variant: "primary", children: words.people.letIn }))] }), error !== undefined && _jsx(Callout, { tone: "danger", children: error }), making && (_jsx("section", { className: "sc-panel sc-panel-form", "aria-label": words.people.letInAria, children: _jsx(ListingForm, { providers: data.me?.signIn ?? [], busy: busy, onSubmit: (input) => void act(async () => {
785
+ // The list is what the policy shows (ADR-0035): everyone, or the people one shares a project with.
786
+ const narrowed = peopleVisibilityOf(data.me?.workspace) === "shared_projects" && !administrator;
787
+ return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "sc-page-head", children: [_jsx("h1", { className: "sc-page-title", children: words.people.title }), administrator && !making && (_jsx(LinkButton, { href: PATHS.newListing, variant: "primary", children: words.people.letIn }))] }), narrowed && _jsx("p", { className: "sc-lead", children: words.people.narrowed }), error !== undefined && _jsx(Callout, { tone: "danger", children: error }), making && (_jsx("section", { className: "sc-panel sc-panel-form", "aria-label": words.people.letInAria, children: _jsx(ListingForm, { providers: data.me?.signIn ?? [], busy: busy, onSubmit: (input) => void act(async () => {
749
788
  await data.actions.createListing(input);
750
789
  navigation.replace(PATHS.people);
751
790
  }), onCancel: () => navigation.back(PATHS.people) }) })), _jsx(components.PeopleList, { people: data.people, listed: data.listed, organization: data.organization, me: me, busy: busy, onChangeRole: administrator