@mdbase-dev/ui 0.1.0-beta.125 → 0.1.0-beta.147

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 (77) hide show
  1. package/README.md +159 -0
  2. package/css/brand.css +10 -10
  3. package/css/collections.css +978 -0
  4. package/css/controls.css +220 -43
  5. package/css/feedback.css +20 -20
  6. package/css/fonts.css +2 -3
  7. package/css/palette.css +10 -10
  8. package/css/screens.css +58 -16
  9. package/css/tokens.css +43 -3
  10. package/dist/AppSwitcher.js +187 -33
  11. package/dist/Checkbox.d.ts +14 -0
  12. package/dist/Checkbox.js +32 -0
  13. package/dist/CommandPalette.d.ts +4 -2
  14. package/dist/CommandPalette.js +275 -103
  15. package/dist/Dialog.js +72 -25
  16. package/dist/Feedback.js +763 -229
  17. package/dist/FeedbackMarkup.d.ts +1 -1
  18. package/dist/FeedbackMarkup.js +326 -125
  19. package/dist/FeedbackVerification.js +115 -68
  20. package/dist/SaveNotice.js +71 -28
  21. package/dist/Select.js +183 -135
  22. package/dist/SelectList.js +59 -14
  23. package/dist/ThemeSelect.js +55 -4
  24. package/dist/apps.d.ts +1 -0
  25. package/dist/apps.js +50 -29
  26. package/dist/brand.js +251 -68
  27. package/dist/codemirror.js +116 -87
  28. package/dist/collections/CollectionGate.d.ts +52 -0
  29. package/dist/collections/CollectionGate.js +456 -0
  30. package/dist/collections/CollectionSaveWarning.d.ts +10 -0
  31. package/dist/collections/CollectionSaveWarning.js +28 -0
  32. package/dist/collections/CollectionSwitcher.d.ts +26 -0
  33. package/dist/collections/CollectionSwitcher.js +579 -0
  34. package/dist/collections/SetupReview.d.ts +9 -0
  35. package/dist/collections/SetupReview.js +175 -0
  36. package/dist/collections/copy.d.ts +100 -0
  37. package/dist/collections/copy.js +937 -0
  38. package/dist/collections/dialogs.d.ts +27 -0
  39. package/dist/collections/dialogs.js +169 -0
  40. package/dist/collections/model.d.ts +146 -0
  41. package/dist/collections/model.js +337 -0
  42. package/dist/collections/mount.d.ts +18 -0
  43. package/dist/collections/mount.js +56 -0
  44. package/dist/collections/parts.d.ts +86 -0
  45. package/dist/collections/parts.js +439 -0
  46. package/dist/collections/testing.d.ts +19 -0
  47. package/dist/collections/testing.js +39 -0
  48. package/dist/collections/use-collection-ui.d.ts +140 -0
  49. package/dist/collections/use-collection-ui.js +236 -0
  50. package/dist/collections.d.ts +19 -0
  51. package/dist/collections.js +13 -0
  52. package/dist/feedback-data.d.ts +13 -12
  53. package/dist/feedback-data.js +365 -168
  54. package/dist/flock.d.ts +63 -0
  55. package/dist/flock.js +140 -0
  56. package/dist/i18n.d.ts +6 -0
  57. package/dist/i18n.js +71 -0
  58. package/dist/locales/de/messages.json +1 -0
  59. package/dist/locales/en/messages.json +1 -0
  60. package/dist/locales/es/messages.json +1 -0
  61. package/dist/locales/fr/messages.json +1 -0
  62. package/dist/locales/it/messages.json +1 -0
  63. package/dist/locales/ja/messages.json +1 -0
  64. package/dist/locales/ko/messages.json +1 -0
  65. package/dist/locales/pt/messages.json +1 -0
  66. package/dist/locales/ru/messages.json +1 -0
  67. package/dist/locales/zh/messages.json +1 -0
  68. package/dist/mark-activity.js +82 -75
  69. package/dist/permission-selection.js +27 -17
  70. package/dist/popover.js +138 -130
  71. package/dist/screens.d.ts +20 -3
  72. package/dist/screens.js +275 -6
  73. package/dist/select-model.js +34 -28
  74. package/dist/text-diff.d.ts +1 -0
  75. package/dist/text-diff.js +106 -74
  76. package/dist/theme.js +34 -40
  77. package/package.json +53 -8
@@ -0,0 +1,175 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { describeError } from "@mdbase-dev/sdk/describe";
3
+ import { useEffect, useState } from "react";
4
+ import { actionNotice, problemControl } from "./model.js";
5
+ import { ActionButton, NoticeBlock } from "./parts.js";
6
+ /** Quiet re-plans after a transient refusal (about a minute in all). */
7
+ const TRANSIENT_REPLANS = 15;
8
+ /**
9
+ * Reviewable setup: `setup.plan()` (read-only, so it starts at once), then
10
+ * `setup.apply(plan)` only from the person's click. Never configures silently.
11
+ */
12
+ export function SetupReview({
13
+ ui
14
+ }) {
15
+ const {
16
+ mdbase
17
+ } = ui.options;
18
+ const [state, setState] = useState({
19
+ status: "planning",
20
+ notice: null
21
+ });
22
+ const [request, setRequest] = useState({
23
+ options: {},
24
+ notice: null
25
+ });
26
+ const [applying, setApplying] = useState(false);
27
+ useEffect(() => {
28
+ const controller = new AbortController();
29
+ let timer = null;
30
+ // A transient refusal (another tab is finishing setup, the SDK is busy)
31
+ // clears by itself: plan again quietly, with backoff, before giving up.
32
+ const attempt = n => {
33
+ mdbase.setup.plan({
34
+ ...request.options,
35
+ signal: controller.signal
36
+ }).then(plan => {
37
+ if (!controller.signal.aborted) setState({
38
+ status: "ready",
39
+ plan,
40
+ notice: request.notice
41
+ });
42
+ }, cause => {
43
+ if (controller.signal.aborted) return;
44
+ const described = describeError(cause);
45
+ if (described?.transient && n < TRANSIENT_REPLANS) {
46
+ timer = setTimeout(() => attempt(n + 1), described.retryAfterMs ?? Math.min(500 * 2 ** n, 5000));
47
+ return;
48
+ }
49
+ setState({
50
+ status: "failed",
51
+ notice: actionNotice(described)
52
+ });
53
+ });
54
+ };
55
+ attempt(0);
56
+ return () => {
57
+ controller.abort();
58
+ if (timer !== null) clearTimeout(timer);
59
+ };
60
+ }, [mdbase, request]);
61
+ const replan = (options, notice = null) => {
62
+ setState({
63
+ status: "planning",
64
+ notice: null
65
+ });
66
+ setRequest({
67
+ options,
68
+ notice
69
+ });
70
+ };
71
+ const apply = plan => {
72
+ setApplying(true);
73
+ mdbase.setup.apply(plan).then(result => {
74
+ setApplying(false);
75
+ if (result.outcome === "changed") replan(request.options, actionNotice(describeError("setup_changed")));
76
+ }, cause => {
77
+ setApplying(false);
78
+ const notice = actionNotice(describeError(cause));
79
+ setState(current => current.status === "ready" ? {
80
+ ...current,
81
+ notice
82
+ } : current);
83
+ });
84
+ };
85
+ if (state.status === "planning") {
86
+ return _jsxs("p", {
87
+ className: "mdbase-collections-progress",
88
+ role: "status",
89
+ children: [_jsx("span", {
90
+ className: "mdbase-collections-spinner",
91
+ "aria-hidden": "true"
92
+ }), ui.copy.setupChecking]
93
+ });
94
+ }
95
+ if (state.status === "failed") {
96
+ return _jsxs("div", {
97
+ className: "mdbase-collections-setup",
98
+ children: [state.notice && _jsx(NoticeBlock, {
99
+ notice: state.notice,
100
+ ui: ui
101
+ }), _jsx("div", {
102
+ className: "mdbase-collections-actions",
103
+ children: _jsx(ActionButton, {
104
+ tone: "primary",
105
+ onClick: () => replan(request.options),
106
+ children: ui.copy.tryAgain
107
+ })
108
+ })]
109
+ });
110
+ }
111
+ const {
112
+ plan
113
+ } = state;
114
+ const refusal = plan.refusal ? describeError(plan.refusal.code) : null;
115
+ const refusalNotice = refusal ? {
116
+ ...actionNotice(refusal),
117
+ control: problemControl(refusal, {
118
+ collectionId: null,
119
+ signedIn: true,
120
+ open: true
121
+ })
122
+ } : null;
123
+ const nothing = plan.status === "current" || plan.changes.length === 0 && plan.conflicts.length === 0;
124
+ const adoptable = Object.keys(plan.adoptable).length > 0;
125
+ return _jsxs("div", {
126
+ className: "mdbase-collections-setup",
127
+ children: [state.notice && _jsx(NoticeBlock, {
128
+ notice: state.notice,
129
+ ui: ui,
130
+ variant: "inline"
131
+ }), refusalNotice ? _jsx(NoticeBlock, {
132
+ notice: refusalNotice,
133
+ ui: ui
134
+ }) : _jsx("p", {
135
+ className: "mdbase-collections-setup-summary",
136
+ children: nothing ? ui.copy.setupNothing : plan.summary
137
+ }), plan.changes.length > 0 && _jsxs("section", {
138
+ className: "mdbase-collections-setup-section",
139
+ children: [_jsx("h3", {
140
+ children: ui.copy.setupChanges
141
+ }), _jsx("ul", {
142
+ className: "mdbase-collections-setup-list",
143
+ children: plan.changes.map(change => _jsx("li", {
144
+ children: change.message
145
+ }, `${change.kind}:${change.target}`))
146
+ })]
147
+ }), plan.conflicts.length > 0 && _jsxs("section", {
148
+ className: "mdbase-collections-setup-section",
149
+ children: [_jsx("h3", {
150
+ children: ui.copy.setupConflicts
151
+ }), _jsx("ul", {
152
+ className: "mdbase-collections-setup-list",
153
+ children: plan.conflicts.map(conflict => _jsx("li", {
154
+ children: conflict.message
155
+ }, conflict.target))
156
+ })]
157
+ }), _jsxs("div", {
158
+ className: "mdbase-collections-actions",
159
+ children: [!refusal && plan.canApply && _jsx(ActionButton, {
160
+ tone: "primary",
161
+ progress: applying ? ui.copy.setupApplying : null,
162
+ onClick: () => apply(plan),
163
+ children: nothing ? ui.copy.setupContinue : ui.copy.setupApply
164
+ }), adoptable && _jsx(ActionButton, {
165
+ tone: "secondary",
166
+ inert: applying,
167
+ onClick: () => replan({
168
+ ...request.options,
169
+ adopt: plan.adoptable
170
+ }),
171
+ children: ui.say("setupUseAppVersion")
172
+ })]
173
+ })]
174
+ });
175
+ }
@@ -0,0 +1,100 @@
1
+ import "../i18n.js";
2
+ /**
3
+ * The shared screens' own words. Problem titles and messages are the SDK's
4
+ * (`describeError`); these are headings, labels and confirmations around them.
5
+ * `{app}` is the app's name and `{collection}` a collection's name.
6
+ */
7
+ export declare const defaultCollectionCopy: {
8
+ readonly startingHeading: string;
9
+ readonly signedOutHeading: string;
10
+ readonly signedOutLead: string;
11
+ readonly signedOutNotice: string;
12
+ readonly signedOutIncomplete: string;
13
+ readonly signIn: string;
14
+ readonly authorizingHeading: string;
15
+ readonly authorizingSignIn: string;
16
+ readonly authorizingAdd: string;
17
+ readonly authorizingApprove: string;
18
+ readonly openWindowAgain: string;
19
+ readonly cancel: string;
20
+ readonly chooseHeading: string;
21
+ readonly yourCollections: string;
22
+ readonly emptyHeading: string;
23
+ readonly emptyLead: string;
24
+ readonly noCollectionAdded: string;
25
+ readonly accessNotGiven: string;
26
+ readonly addCollection: string;
27
+ readonly addPrivateCollection: string;
28
+ readonly addingCollection: string;
29
+ readonly manageAccess: string;
30
+ readonly signedInAs: string;
31
+ readonly signOut: string;
32
+ readonly signingOut: string;
33
+ readonly openingHeading: string;
34
+ readonly openingHeadingUnnamed: string;
35
+ readonly openingSlow: string;
36
+ readonly openingJoining: string;
37
+ readonly openingStore: string;
38
+ readonly openingLog: string;
39
+ readonly openingSyncing: string;
40
+ readonly openingSnapshot: string;
41
+ readonly openingReplaying: string;
42
+ readonly openingKey: string;
43
+ readonly openingRead: string;
44
+ readonly openingSetup: string;
45
+ readonly chooseAnother: string;
46
+ readonly approvalHeading: string;
47
+ readonly approvalHeadingUnnamed: string;
48
+ readonly approvalLead: string;
49
+ readonly approvalDeclined: string;
50
+ readonly reviewAccess: string;
51
+ readonly setupHeading: string;
52
+ readonly setupLead: string;
53
+ readonly setupChecking: string;
54
+ readonly setupNothing: string;
55
+ readonly setupApply: string;
56
+ readonly setupApplying: string;
57
+ readonly setupContinue: string;
58
+ readonly setupUseAppVersion: string;
59
+ readonly setupConflicts: string;
60
+ readonly setupChanges: string;
61
+ readonly tryAgain: string;
62
+ readonly problemHeading: string;
63
+ readonly problemHeadingUnnamed: string;
64
+ readonly unavailableHeading: string;
65
+ readonly closedHeading: string;
66
+ readonly closedLead: string;
67
+ readonly reload: string;
68
+ readonly thisCollection: string;
69
+ readonly roleOwner: string;
70
+ readonly roleEditor: string;
71
+ readonly roleViewer: string;
72
+ readonly rowOpening: string;
73
+ readonly openNow: string;
74
+ readonly idHint: string;
75
+ readonly privateCollection: string;
76
+ readonly privateCollectionHint: string;
77
+ readonly collectionLabel: string;
78
+ readonly collectionsLabel: string;
79
+ readonly switchCollection: string;
80
+ readonly switchCollectionNone: string;
81
+ readonly findCollection: string;
82
+ readonly noMatches: string;
83
+ readonly moreFor: string;
84
+ readonly removeFromList: string;
85
+ readonly deleteCollection: string;
86
+ readonly forgetTitle: string;
87
+ readonly forgetBody: string;
88
+ readonly forgetConfirm: string;
89
+ readonly deleteTitle: string;
90
+ readonly deleteBody: string;
91
+ readonly deleteTypeName: string;
92
+ readonly deleteConfirm: string;
93
+ readonly deleting: string;
94
+ readonly signOutAnyway: string;
95
+ readonly close: string;
96
+ };
97
+ export type CollectionCopyKey = keyof typeof defaultCollectionCopy;
98
+ export type CollectionCopy = Record<CollectionCopyKey, string>;
99
+ /** Replace `{name}` placeholders. Unknown placeholders stay as written. */
100
+ export declare function fill(template: string, values: Readonly<Record<string, string>>): string;