@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.
- package/README.md +159 -0
- package/css/brand.css +10 -10
- package/css/collections.css +978 -0
- package/css/controls.css +220 -43
- package/css/feedback.css +20 -20
- package/css/fonts.css +2 -3
- package/css/palette.css +10 -10
- package/css/screens.css +58 -16
- package/css/tokens.css +43 -3
- package/dist/AppSwitcher.js +187 -33
- package/dist/Checkbox.d.ts +14 -0
- package/dist/Checkbox.js +32 -0
- package/dist/CommandPalette.d.ts +4 -2
- package/dist/CommandPalette.js +275 -103
- package/dist/Dialog.js +72 -25
- package/dist/Feedback.js +763 -229
- package/dist/FeedbackMarkup.d.ts +1 -1
- package/dist/FeedbackMarkup.js +326 -125
- package/dist/FeedbackVerification.js +115 -68
- package/dist/SaveNotice.js +71 -28
- package/dist/Select.js +183 -135
- package/dist/SelectList.js +59 -14
- package/dist/ThemeSelect.js +55 -4
- package/dist/apps.d.ts +1 -0
- package/dist/apps.js +50 -29
- package/dist/brand.js +251 -68
- package/dist/codemirror.js +116 -87
- package/dist/collections/CollectionGate.d.ts +52 -0
- package/dist/collections/CollectionGate.js +456 -0
- package/dist/collections/CollectionSaveWarning.d.ts +10 -0
- package/dist/collections/CollectionSaveWarning.js +28 -0
- package/dist/collections/CollectionSwitcher.d.ts +26 -0
- package/dist/collections/CollectionSwitcher.js +579 -0
- package/dist/collections/SetupReview.d.ts +9 -0
- package/dist/collections/SetupReview.js +175 -0
- package/dist/collections/copy.d.ts +100 -0
- package/dist/collections/copy.js +937 -0
- package/dist/collections/dialogs.d.ts +27 -0
- package/dist/collections/dialogs.js +169 -0
- package/dist/collections/model.d.ts +146 -0
- package/dist/collections/model.js +337 -0
- package/dist/collections/mount.d.ts +18 -0
- package/dist/collections/mount.js +56 -0
- package/dist/collections/parts.d.ts +86 -0
- package/dist/collections/parts.js +439 -0
- package/dist/collections/testing.d.ts +19 -0
- package/dist/collections/testing.js +39 -0
- package/dist/collections/use-collection-ui.d.ts +140 -0
- package/dist/collections/use-collection-ui.js +236 -0
- package/dist/collections.d.ts +19 -0
- package/dist/collections.js +13 -0
- package/dist/feedback-data.d.ts +13 -12
- package/dist/feedback-data.js +365 -168
- package/dist/flock.d.ts +63 -0
- package/dist/flock.js +140 -0
- package/dist/i18n.d.ts +6 -0
- package/dist/i18n.js +71 -0
- package/dist/locales/de/messages.json +1 -0
- package/dist/locales/en/messages.json +1 -0
- package/dist/locales/es/messages.json +1 -0
- package/dist/locales/fr/messages.json +1 -0
- package/dist/locales/it/messages.json +1 -0
- package/dist/locales/ja/messages.json +1 -0
- package/dist/locales/ko/messages.json +1 -0
- package/dist/locales/pt/messages.json +1 -0
- package/dist/locales/ru/messages.json +1 -0
- package/dist/locales/zh/messages.json +1 -0
- package/dist/mark-activity.js +82 -75
- package/dist/permission-selection.js +27 -17
- package/dist/popover.js +138 -130
- package/dist/screens.d.ts +20 -3
- package/dist/screens.js +275 -6
- package/dist/select-model.js +34 -28
- package/dist/text-diff.d.ts +1 -0
- package/dist/text-diff.js +106 -74
- package/dist/theme.js +34 -40
- 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;
|