@indietabletop/appkit 7.0.0-0 → 7.0.0-rc.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.
- package/lib/AppConfig/AppConfig.tsx +80 -0
- package/lib/AppConfig/formatters.tsx +48 -0
- package/lib/AuthCard/AuthCard.stories.ts +34 -0
- package/lib/AuthCard/AuthCard.tsx +64 -0
- package/lib/AuthCard/style.css.ts +49 -0
- package/lib/CacheProvider.tsx +20 -0
- package/lib/DialogTrigger/index.tsx +36 -0
- package/lib/DocumentTitle/DocumentTitle.tsx +10 -0
- package/lib/EnumMapper.ts +50 -0
- package/lib/ExternalLink.tsx +10 -0
- package/lib/FullscreenDismissBlocker.tsx +23 -0
- package/{dist/HistoryState.d.ts → lib/HistoryState.ts} +5 -2
- package/lib/IndieTabletopClubLogo.tsx +44 -0
- package/lib/IndieTabletopClubSymbol.tsx +37 -0
- package/lib/InfoPage/index.tsx +46 -0
- package/lib/InfoPage/pages.tsx +36 -0
- package/lib/InfoPage/style.css.ts +36 -0
- package/lib/Letterhead/index.tsx +85 -0
- package/lib/Letterhead/stories.tsx +41 -0
- package/lib/Letterhead/style.css.ts +152 -0
- package/lib/LetterheadForm/LetterheadReadonlyTextField.stories.tsx +17 -0
- package/lib/LetterheadForm/LetterheadSubmitError.stories.tsx +19 -0
- package/lib/LetterheadForm/LetterheadTextField.stories.tsx +19 -0
- package/lib/LetterheadForm/index.tsx +137 -0
- package/lib/LetterheadForm/style.css.ts +89 -0
- package/lib/ListView/ListView.stories.tsx +36 -0
- package/lib/ListView/ListView.tsx +80 -0
- package/lib/ListView/style.css.ts +90 -0
- package/lib/LoadingIndicator.tsx +40 -0
- package/lib/MiddotSeparated/MiddotSeparated.stories.ts +26 -0
- package/lib/MiddotSeparated/MiddotSeparated.tsx +26 -0
- package/lib/MiddotSeparated/style.css.ts +10 -0
- package/lib/ModalDialog/index.tsx +28 -0
- package/lib/ModalDialog/style.css.ts +88 -0
- package/lib/ModernIDB/Cursor.ts +91 -0
- package/lib/ModernIDB/ModernIDB.ts +337 -0
- package/lib/ModernIDB/ModernIDBError.ts +9 -0
- package/lib/ModernIDB/ObjectStore.ts +195 -0
- package/lib/ModernIDB/ObjectStoreIndex.ts +102 -0
- package/lib/ModernIDB/README.md +9 -0
- package/lib/ModernIDB/Transaction.ts +40 -0
- package/lib/ModernIDB/VersionChangeManager.ts +57 -0
- package/lib/ModernIDB/bindings/factory.tsx +165 -0
- package/lib/ModernIDB/bindings/index.ts +2 -0
- package/{dist/ModernIDB/bindings/types.d.ts → lib/ModernIDB/bindings/types.ts} +32 -13
- package/lib/ModernIDB/bindings/utils.tsx +32 -0
- package/lib/ModernIDB/index.ts +10 -0
- package/lib/ModernIDB/types.ts +120 -0
- package/lib/ModernIDB/utils.ts +51 -0
- package/lib/QRCode/QRCode.stories.tsx +41 -0
- package/lib/QRCode/QRCode.tsx +54 -0
- package/lib/QRCode/style.css.ts +23 -0
- package/lib/ReleaseInfo/index.tsx +29 -0
- package/lib/RichText/RichText.tsx +55 -0
- package/lib/RichText/style.css.ts +147 -0
- package/lib/RulesetResolver.ts +214 -0
- package/lib/SafariCheck/SafariCheck.stories.tsx +99 -0
- package/lib/SafariCheck/SafariCheck.tsx +273 -0
- package/lib/SafariCheck/addToDock.svg +13 -0
- package/lib/SafariCheck/addToHomeScreen.svg +12 -0
- package/lib/SafariCheck/safari.svg +32 -0
- package/lib/SafariCheck/shareIcon.svg +11 -0
- package/lib/SafariCheck/style.css.ts +106 -0
- package/lib/ServiceWorkerHandler.tsx +53 -0
- package/lib/ShareButton/ShareButton.stories.tsx +58 -0
- package/lib/ShareButton/ShareButton.tsx +153 -0
- package/lib/ShareButton/test.css.ts +3 -0
- package/lib/SubscribeCard/LetterheadInfoCard.tsx +23 -0
- package/lib/SubscribeCard/SubscribeByEmailCard.stories.tsx +69 -0
- package/lib/SubscribeCard/SubscribeByEmailCard.tsx +183 -0
- package/lib/SubscribeCard/SubscribeByPledgeCard.stories.tsx +133 -0
- package/lib/SubscribeCard/SubscribeByPledgeCard.tsx +127 -0
- package/lib/SubscribeCard/style.css.ts +14 -0
- package/lib/Sync/SyncIcon.stories.tsx +67 -0
- package/lib/Sync/SyncIcon.tsx +102 -0
- package/lib/Sync/SyncLog.tsx +222 -0
- package/lib/Sync/SyncLogList.stories.tsx +219 -0
- package/lib/Sync/style.css.ts +126 -0
- package/lib/account/AccountIcon.tsx +15 -0
- package/lib/account/AccountIssueView.tsx +44 -0
- package/lib/account/AlreadyLoggedInView.tsx +47 -0
- package/lib/account/CurrentUserFetcher.stories.tsx +292 -0
- package/lib/account/CurrentUserFetcher.tsx +118 -0
- package/lib/account/FailureFallbackView.tsx +36 -0
- package/lib/account/JoinCard.stories.tsx +257 -0
- package/lib/account/JoinCard.tsx +301 -0
- package/lib/account/LoadingView.tsx +14 -0
- package/lib/account/LoginCard.stories.tsx +288 -0
- package/lib/account/LoginCard.tsx +100 -0
- package/lib/account/LoginView.tsx +151 -0
- package/lib/account/NoConnectionView.tsx +34 -0
- package/lib/account/PasswordResetCard.stories.tsx +242 -0
- package/lib/account/PasswordResetCard.tsx +296 -0
- package/lib/account/UserMismatchView.tsx +62 -0
- package/lib/account/VerifyPage.tsx +195 -0
- package/lib/account/iconMask.svg +3 -0
- package/lib/account/style.css.ts +81 -0
- package/{dist/account/types.d.ts → lib/account/types.ts} +6 -3
- package/lib/account/useFetchCurrentUser.tsx +63 -0
- package/lib/account/useRedirectPath.ts +21 -0
- package/lib/animations.css.ts +17 -0
- package/lib/append-copy-to-text.ts +35 -0
- package/lib/async-op.ts +298 -0
- package/lib/atomic.css.ts +11 -0
- package/{dist/caught-value.d.ts → lib/caught-value.ts} +11 -1
- package/{dist/class-names.d.ts → lib/class-names.ts} +17 -6
- package/lib/client.ts +662 -0
- package/lib/common.css.ts +48 -0
- package/lib/copyrightRange.ts +10 -0
- package/lib/createSafeStorage.ts +91 -0
- package/lib/createStrictContext.ts +15 -0
- package/lib/failureMessages.ts +108 -0
- package/lib/form/FormSubmitButton.tsx +58 -0
- package/lib/form/SubmitErrorAlert.tsx +21 -0
- package/lib/form/style.css.ts +9 -0
- package/lib/globals.css.ts +62 -0
- package/lib/groupBy.ts +25 -0
- package/lib/hrefs.ts +48 -0
- package/lib/idToDate.ts +8 -0
- package/lib/ids.ts +6 -0
- package/lib/index.ts +78 -0
- package/lib/internal.css.ts +10 -0
- package/lib/layers.css.ts +3 -0
- package/lib/mailto.ts +40 -0
- package/lib/media.ts +50 -0
- package/lib/random.ts +19 -0
- package/lib/result/swr.ts +18 -0
- package/{dist/sleep.d.ts → lib/sleep.ts} +3 -1
- package/lib/store/index.tsx +292 -0
- package/lib/store/store.ts +482 -0
- package/lib/store/types.ts +45 -0
- package/lib/store/utils.ts +54 -0
- package/lib/storybook/decorators.tsx +10 -0
- package/lib/structs.ts +3 -0
- package/{dist/typeguards.d.ts → lib/typeguards.ts} +3 -1
- package/{dist/types.d.ts → lib/types.ts} +23 -12
- package/lib/unique.ts +24 -0
- package/lib/use-async-op.ts +16 -0
- package/lib/use-document-background-color.ts +16 -0
- package/lib/use-form.ts +78 -0
- package/lib/use-is-installed.ts +17 -0
- package/lib/use-media-query.ts +21 -0
- package/lib/use-reverting-state.ts +32 -0
- package/lib/use-scroll-restoration.ts +99 -0
- package/lib/useEnsureValue.ts +31 -0
- package/lib/useFetchJson.tsx +52 -0
- package/lib/useInvokeClient.ts +54 -0
- package/lib/useIsVisible.ts +27 -0
- package/lib/utm.ts +92 -0
- package/lib/validations.ts +25 -0
- package/lib/vars.css.ts +13 -0
- package/package.json +23 -29
- package/dist/AppConfig/AppConfig.d.ts +0 -29
- package/dist/AuthCard/AuthCard.d.ts +0 -10
- package/dist/AuthCard/AuthCard.stories.d.ts +0 -34
- package/dist/AuthCard/style.css.d.ts +0 -23
- package/dist/DialogTrigger/index.d.ts +0 -13
- package/dist/DocumentTitle/DocumentTitle.d.ts +0 -3
- package/dist/EnumMapper.d.ts +0 -25
- package/dist/ExternalLink.d.ts +0 -3
- package/dist/FullscreenDismissBlocker.d.ts +0 -5
- package/dist/IndieTabletopClubLogo.d.ts +0 -7
- package/dist/IndieTabletopClubSymbol.d.ts +0 -7
- package/dist/InfoPage/index.d.ts +0 -8
- package/dist/InfoPage/pages.d.ts +0 -2
- package/dist/InfoPage/style.css.d.ts +0 -5
- package/dist/Letterhead/index.d.ts +0 -19
- package/dist/Letterhead/stories.d.ts +0 -13
- package/dist/Letterhead/style.css.d.ts +0 -46
- package/dist/LetterheadForm/LetterheadReadonlyTextField.stories.d.ts +0 -17
- package/dist/LetterheadForm/LetterheadSubmitError.stories.d.ts +0 -11
- package/dist/LetterheadForm/LetterheadTextField.stories.d.ts +0 -336
- package/dist/LetterheadForm/index.d.ts +0 -44
- package/dist/LetterheadForm/style.css.d.ts +0 -8
- package/dist/LoadingIndicator.d.ts +0 -3
- package/dist/MiddotSeparated/MiddotSeparated.d.ts +0 -8
- package/dist/MiddotSeparated/MiddotSeparated.stories.d.ts +0 -586
- package/dist/MiddotSeparated/style.css.d.ts +0 -1
- package/dist/ModalDialog/index.d.ts +0 -12
- package/dist/ModalDialog/style.css.d.ts +0 -58
- package/dist/ModernIDB/Cursor.d.ts +0 -56
- package/dist/ModernIDB/ModernIDB.d.ts +0 -66
- package/dist/ModernIDB/ModernIDBError.d.ts +0 -3
- package/dist/ModernIDB/ObjectStore.d.ts +0 -112
- package/dist/ModernIDB/ObjectStoreIndex.d.ts +0 -53
- package/dist/ModernIDB/Transaction.d.ts +0 -16
- package/dist/ModernIDB/VersionChangeManager.d.ts +0 -30
- package/dist/ModernIDB/bindings/factory.d.ts +0 -12
- package/dist/ModernIDB/bindings/index.d.ts +0 -2
- package/dist/ModernIDB/bindings/utils.d.ts +0 -2
- package/dist/ModernIDB/index.d.ts +0 -10
- package/dist/ModernIDB/types.d.ts +0 -88
- package/dist/ModernIDB/utils.d.ts +0 -4
- package/dist/QRCode/QRCode.d.ts +0 -7
- package/dist/QRCode/QRCode.stories.d.ts +0 -33
- package/dist/QRCode/style.css.d.ts +0 -4
- package/dist/ReleaseInfo/index.d.ts +0 -5
- package/dist/RulesetResolver.d.ts +0 -87
- package/dist/SafariCheck/SafariCheck.d.ts +0 -23
- package/dist/SafariCheck/SafariCheck.stories.d.ts +0 -73
- package/dist/SafariCheck/style.css.d.ts +0 -17
- package/dist/ServiceWorkerHandler.d.ts +0 -11
- package/dist/ShareButton/ShareButton.d.ts +0 -57
- package/dist/ShareButton/ShareButton.stories.d.ts +0 -1577
- package/dist/ShareButton/test.css.d.ts +0 -1
- package/dist/SubscribeCard/LetterheadInfoCard.d.ts +0 -2
- package/dist/SubscribeCard/SubscribeByEmailCard.d.ts +0 -24
- package/dist/SubscribeCard/SubscribeByEmailCard.stories.d.ts +0 -10
- package/dist/SubscribeCard/SubscribeByPledgeCard.d.ts +0 -36
- package/dist/SubscribeCard/SubscribeByPledgeCard.stories.d.ts +0 -65
- package/dist/SubscribeCard/style.css.d.ts +0 -4
- package/dist/account/AccountIssueView.d.ts +0 -3
- package/dist/account/AlreadyLoggedInView.d.ts +0 -5
- package/dist/account/CurrentUserFetcher.d.ts +0 -20
- package/dist/account/CurrentUserFetcher.stories.d.ts +0 -136
- package/dist/account/FailureFallbackView.d.ts +0 -1
- package/dist/account/JoinCard.d.ts +0 -14
- package/dist/account/JoinCard.stories.d.ts +0 -143
- package/dist/account/LoadingView.d.ts +0 -1
- package/dist/account/LoginCard.d.ts +0 -39
- package/dist/account/LoginCard.stories.d.ts +0 -217
- package/dist/account/LoginView.d.ts +0 -10
- package/dist/account/NoConnectionView.d.ts +0 -4
- package/dist/account/PasswordResetCard.d.ts +0 -15
- package/dist/account/PasswordResetCard.stories.d.ts +0 -128
- package/dist/account/UserMismatchView.d.ts +0 -6
- package/dist/account/VerifyPage.d.ts +0 -13
- package/dist/account/style.css.d.ts +0 -10
- package/dist/account/useFetchCurrentUser.d.ts +0 -28
- package/dist/account/useRedirectPath.d.ts +0 -6
- package/dist/animations.css.d.ts +0 -3
- package/dist/append-copy-to-text.d.ts +0 -10
- package/dist/append-copy-to-text.test.d.ts +0 -1
- package/dist/appkit.css +0 -1
- package/dist/appkit.js +0 -10692
- package/dist/async-op.d.ts +0 -101
- package/dist/atomic.css.d.ts +0 -6
- package/dist/client.d.ts +0 -424
- package/dist/common.css.d.ts +0 -5
- package/dist/copyrightRange.d.ts +0 -1
- package/dist/copyrightRange.test.d.ts +0 -1
- package/dist/createSafeStorage.d.ts +0 -34
- package/dist/failureMessages.d.ts +0 -20
- package/dist/failureMessages.test.d.ts +0 -1
- package/dist/form/FormSubmitButton.d.ts +0 -17
- package/dist/form/SubmitErrorAlert.d.ts +0 -5
- package/dist/form/style.css.d.ts +0 -3
- package/dist/globals.css.d.ts +0 -0
- package/dist/groupBy.d.ts +0 -1
- package/dist/groupBy.test.d.ts +0 -1
- package/dist/hrefs.d.ts +0 -32
- package/dist/hrefs.test.d.ts +0 -1
- package/dist/idToDate.d.ts +0 -5
- package/dist/idToDate.test.d.ts +0 -1
- package/dist/ids.d.ts +0 -1
- package/dist/ids.test.d.ts +0 -1
- package/dist/index.d.ts +0 -64
- package/dist/internal.css.d.ts +0 -2
- package/dist/mailto.d.ts +0 -8
- package/dist/mailto.test.d.ts +0 -1
- package/dist/media.d.ts +0 -39
- package/dist/random.d.ts +0 -3
- package/dist/result/swr.d.ts +0 -4
- package/dist/store/index.d.ts +0 -237
- package/dist/store/store.d.ts +0 -144
- package/dist/store/types.d.ts +0 -49
- package/dist/store/utils.d.ts +0 -10
- package/dist/storybook/decorators.d.ts +0 -3
- package/dist/structs.d.ts +0 -1
- package/dist/typeguards.test.d.ts +0 -1
- package/dist/unique.d.ts +0 -10
- package/dist/unique.test.d.ts +0 -1
- package/dist/use-async-op.d.ts +0 -6
- package/dist/use-document-background-color.d.ts +0 -4
- package/dist/use-form.d.ts +0 -29
- package/dist/use-is-installed.d.ts +0 -8
- package/dist/use-media-query.d.ts +0 -1
- package/dist/use-reverting-state.d.ts +0 -5
- package/dist/use-scroll-restoration.d.ts +0 -25
- package/dist/useEnsureValue.d.ts +0 -6
- package/dist/useInvokeClient.d.ts +0 -25
- package/dist/useIsVisible.d.ts +0 -4
- package/dist/utm.d.ts +0 -58
- package/dist/utm.test.d.ts +0 -1
- package/dist/validations.d.ts +0 -3
- package/dist/vars.css.d.ts +0 -10
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { assignInlineVars } from "@vanilla-extract/dynamic";
|
|
2
|
+
import preview from "../../.storybook/preview.tsx";
|
|
3
|
+
import { SyncIcon } from "./SyncIcon.tsx";
|
|
4
|
+
import { syncTheme } from "./style.css.ts";
|
|
5
|
+
|
|
6
|
+
const meta = preview.meta({
|
|
7
|
+
title: "Components/SyncIcon",
|
|
8
|
+
component: SyncIcon,
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
export const Inactive = meta.story({
|
|
12
|
+
args: {
|
|
13
|
+
status: "INACTIVE",
|
|
14
|
+
},
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
export const Authenticating = meta.story({
|
|
18
|
+
args: {
|
|
19
|
+
status: "AUTHENTICATING",
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
export const Idle = meta.story({
|
|
24
|
+
args: {
|
|
25
|
+
status: "IDLE",
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
export const Error = meta.story({
|
|
30
|
+
args: {
|
|
31
|
+
status: "ERROR",
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
export const Syncing = meta.story({
|
|
36
|
+
args: {
|
|
37
|
+
status: "SYNCING",
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
export const Waiting = meta.story({
|
|
42
|
+
args: {
|
|
43
|
+
status: "WAITING",
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
export const Overrides = meta.story({
|
|
48
|
+
args: {
|
|
49
|
+
status: "AUTHENTICATING",
|
|
50
|
+
},
|
|
51
|
+
decorators: [
|
|
52
|
+
(Story) => {
|
|
53
|
+
return (
|
|
54
|
+
<div
|
|
55
|
+
style={assignInlineVars(syncTheme, {
|
|
56
|
+
idle: "black",
|
|
57
|
+
inactive: "black",
|
|
58
|
+
syncing: "black",
|
|
59
|
+
error: "black",
|
|
60
|
+
})}
|
|
61
|
+
>
|
|
62
|
+
<Story />
|
|
63
|
+
</div>
|
|
64
|
+
);
|
|
65
|
+
},
|
|
66
|
+
],
|
|
67
|
+
});
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { cx } from "../class-names.ts";
|
|
2
|
+
import type { SyncState } from "../store/index.tsx";
|
|
3
|
+
import { icon, syncTheme } from "./style.css.ts";
|
|
4
|
+
|
|
5
|
+
export { syncTheme };
|
|
6
|
+
|
|
7
|
+
function Icon(props: { variant: SyncState }) {
|
|
8
|
+
switch (props.variant) {
|
|
9
|
+
case "IDLE": {
|
|
10
|
+
return (
|
|
11
|
+
<g className={icon.group}>
|
|
12
|
+
<circle className={icon.idle} />
|
|
13
|
+
|
|
14
|
+
<path
|
|
15
|
+
d="M9.0026 14L16.0737 6.92893L14.6595 5.51472L9.0026 11.1716L6.17421 8.3431L4.75999 9.7574L9.0026 14Z"
|
|
16
|
+
className={icon.shape}
|
|
17
|
+
/>
|
|
18
|
+
</g>
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
case "AUTHENTICATING":
|
|
23
|
+
case "WAITING": {
|
|
24
|
+
return (
|
|
25
|
+
<g className={icon.group}>
|
|
26
|
+
<circle className={icon.syncing} />
|
|
27
|
+
|
|
28
|
+
<g>
|
|
29
|
+
<circle cx="14" cy="10" className={icon.bounce} />
|
|
30
|
+
<circle cx="10" cy="10" className={icon.bounce} />
|
|
31
|
+
<circle cx="6" cy="10" className={icon.bounce} />
|
|
32
|
+
</g>
|
|
33
|
+
</g>
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
case "SYNCING": {
|
|
38
|
+
return (
|
|
39
|
+
<g className={icon.group}>
|
|
40
|
+
<circle className={icon.idle} />
|
|
41
|
+
|
|
42
|
+
<path
|
|
43
|
+
d="M14.8201 15.0761C16.1628 13.8007 17 11.9981 17 10C17 6.13401 13.866 3 10 3C8.9391 3 7.9334 3.23599 7.03241 3.65834L8.0072 5.41292C8.6177 5.14729 9.2917 5 10 5C12.7614 5 15 7.23858 15 10H12L14.8201 15.0761ZM12.9676 16.3417L11.9928 14.5871C11.3823 14.8527 10.7083 15 10 15C7.23858 15 5 12.7614 5 10H8L5.17993 4.92387C3.83719 6.19929 3 8.0019 3 10C3 13.866 6.13401 17 10 17C11.0609 17 12.0666 16.764 12.9676 16.3417Z"
|
|
44
|
+
className={icon.shape}
|
|
45
|
+
/>
|
|
46
|
+
</g>
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
case "ERROR": {
|
|
51
|
+
return (
|
|
52
|
+
<g className={icon.group}>
|
|
53
|
+
<circle className={icon.error} />
|
|
54
|
+
|
|
55
|
+
<path
|
|
56
|
+
d="M10 8.58579L7.17157 5.75735L5.75736 7.17156L8.5858 9.99999L5.75736 12.8284L7.17157 14.2426L10 11.4142L12.8284 14.2426L14.2426 12.8284L11.4142 9.99999L14.2426 7.17156L12.8284 5.75735L10 8.58579Z"
|
|
57
|
+
className={icon.shape}
|
|
58
|
+
/>
|
|
59
|
+
</g>
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
case "INACTIVE": {
|
|
64
|
+
return (
|
|
65
|
+
<g className={icon.group}>
|
|
66
|
+
<circle className={icon.inactive} />
|
|
67
|
+
|
|
68
|
+
<path
|
|
69
|
+
d="M9 13V15H11V13H9ZM11 11.3551C12.4457 10.9248 13.5 9.5855 13.5 8C13.5 6.067 11.933 4.5 10 4.5C8.302 4.5 6.88637 5.70919 6.56731 7.31346L8.5288 7.70577C8.6656 7.01823 9.2723 6.5 10 6.5C10.8284 6.5 11.5 7.17157 11.5 8C11.5 8.8284 10.8284 9.5 10 9.5C9.4477 9.5 9 9.9477 9 10.5V12H11V11.3551Z"
|
|
70
|
+
className={icon.shape}
|
|
71
|
+
/>
|
|
72
|
+
</g>
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
default: {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export function SyncIcon(props: {
|
|
83
|
+
status: SyncState;
|
|
84
|
+
title?: string;
|
|
85
|
+
className?: string;
|
|
86
|
+
}) {
|
|
87
|
+
const { status, title } = props;
|
|
88
|
+
|
|
89
|
+
return (
|
|
90
|
+
<svg
|
|
91
|
+
{...cx(props, icon.container({ rotate: status === "SYNCING" }))}
|
|
92
|
+
width="20px"
|
|
93
|
+
height="20px"
|
|
94
|
+
viewBox="0 0 20 20"
|
|
95
|
+
version="1.1"
|
|
96
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
97
|
+
>
|
|
98
|
+
<title>{title}</title>
|
|
99
|
+
<Icon variant={status} />
|
|
100
|
+
</svg>
|
|
101
|
+
);
|
|
102
|
+
}
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Disclosure,
|
|
3
|
+
DisclosureContent,
|
|
4
|
+
DisclosureProvider,
|
|
5
|
+
} from "@ariakit/react";
|
|
6
|
+
import { useAppConfig } from "../AppConfig/AppConfig.tsx";
|
|
7
|
+
import {
|
|
8
|
+
useLastSuccessfulSyncTs,
|
|
9
|
+
useSyncLog,
|
|
10
|
+
useSyncState,
|
|
11
|
+
type SyncState,
|
|
12
|
+
} from "../store/index.tsx";
|
|
13
|
+
import type { SyncAttempt } from "../store/types.ts";
|
|
14
|
+
import type { FailurePayload } from "../types.ts";
|
|
15
|
+
import { log } from "./style.css.ts";
|
|
16
|
+
import { SyncIcon } from "./SyncIcon.tsx";
|
|
17
|
+
|
|
18
|
+
function SyncActionSuccess(props: {
|
|
19
|
+
heading: string;
|
|
20
|
+
items: { id: string; name: string; deleted: boolean }[];
|
|
21
|
+
}) {
|
|
22
|
+
const { heading, items } = props;
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<div>
|
|
26
|
+
<div>
|
|
27
|
+
<strong>{heading}</strong>
|
|
28
|
+
</div>
|
|
29
|
+
|
|
30
|
+
<div style={{ marginBlockStart: "0.25rem" }}>
|
|
31
|
+
{items.length > 0 ?
|
|
32
|
+
<ul
|
|
33
|
+
style={{
|
|
34
|
+
listStyle: "initial",
|
|
35
|
+
paddingInlineStart: "1.5rem",
|
|
36
|
+
}}
|
|
37
|
+
>
|
|
38
|
+
{items.map((item) => {
|
|
39
|
+
const name = item.name || "Unnamed item";
|
|
40
|
+
|
|
41
|
+
if (item.deleted) {
|
|
42
|
+
return (
|
|
43
|
+
<li key={item.id}>
|
|
44
|
+
Synced deletion of {name} (<code>{item.id}</code>)
|
|
45
|
+
</li>
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return (
|
|
50
|
+
<li key={item.id}>
|
|
51
|
+
Synced {name} (<code>{item.id}</code>)
|
|
52
|
+
</li>
|
|
53
|
+
);
|
|
54
|
+
})}
|
|
55
|
+
</ul>
|
|
56
|
+
: <div style={{ opacity: 0.5 }}>
|
|
57
|
+
<em>Everything up to date.</em>
|
|
58
|
+
</div>
|
|
59
|
+
}
|
|
60
|
+
</div>
|
|
61
|
+
</div>
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const failureToLabel: Record<FailurePayload["type"], string> = {
|
|
66
|
+
NETWORK_ERROR: "A network error occurred.",
|
|
67
|
+
API_ERROR: "Server responded with error ",
|
|
68
|
+
UNKNOWN_ERROR: "An unexpected error ocurred. Try restarting the app.",
|
|
69
|
+
VALIDATION_ERROR: "Data validation error occurred. Try restarting the app.",
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
function SyncActionFailure(props: {
|
|
73
|
+
heading: string;
|
|
74
|
+
failure: FailurePayload;
|
|
75
|
+
}) {
|
|
76
|
+
const { heading, failure } = props;
|
|
77
|
+
const label = failureToLabel[failure.type];
|
|
78
|
+
return (
|
|
79
|
+
<div>
|
|
80
|
+
{heading}
|
|
81
|
+
{": "}
|
|
82
|
+
{failure.type === "API_ERROR" ?
|
|
83
|
+
` ${label} ${failure.code}.`
|
|
84
|
+
: ` ${label}`}
|
|
85
|
+
</div>
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const syncStateToLabel: Record<SyncState, string> = {
|
|
90
|
+
WAITING: "Waiting for additional changes...",
|
|
91
|
+
IDLE: "Sync enabled. Waiting for changes.",
|
|
92
|
+
AUTHENTICATING: "Verifying identity...",
|
|
93
|
+
ERROR: "Last sync unsuccessful. Waiting for changes.",
|
|
94
|
+
INACTIVE: "Sync not enabled. Log in or join to enable.",
|
|
95
|
+
SYNCING: "Syncing...",
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
export function SyncLogList(props: {
|
|
99
|
+
syncState: SyncState;
|
|
100
|
+
syncLog: SyncAttempt[];
|
|
101
|
+
lastSuccessfulSyncTs: number | null;
|
|
102
|
+
}) {
|
|
103
|
+
const { syncLog, syncState, lastSuccessfulSyncTs } = props;
|
|
104
|
+
const { fmt } = useAppConfig();
|
|
105
|
+
|
|
106
|
+
return (
|
|
107
|
+
<div>
|
|
108
|
+
<div className={log.item}>
|
|
109
|
+
<SyncIcon status={syncState} />
|
|
110
|
+
|
|
111
|
+
<div>
|
|
112
|
+
<div>{syncStateToLabel[syncState]}</div>
|
|
113
|
+
|
|
114
|
+
<div className={log.itemTimestamp}>
|
|
115
|
+
{lastSuccessfulSyncTs ?
|
|
116
|
+
`Last successful sync at: ${fmt.dateTime(lastSuccessfulSyncTs)}`
|
|
117
|
+
: "Not synced yet."}
|
|
118
|
+
</div>
|
|
119
|
+
</div>
|
|
120
|
+
</div>
|
|
121
|
+
|
|
122
|
+
{syncLog.map((logItem) => {
|
|
123
|
+
const isFailure =
|
|
124
|
+
logItem.pull?.type === "FAILURE" || logItem.push?.type == "FAILURE";
|
|
125
|
+
|
|
126
|
+
const itemsSynced =
|
|
127
|
+
(logItem.pull?.type === "SUCCESS" ?
|
|
128
|
+
logItem.pull.value.pulled.length
|
|
129
|
+
: 0) +
|
|
130
|
+
(logItem.push?.type === "SUCCESS" ?
|
|
131
|
+
logItem.push.value.pushed.length + logItem.push.value.pulled.length
|
|
132
|
+
: 0);
|
|
133
|
+
|
|
134
|
+
return (
|
|
135
|
+
<DisclosureProvider key={logItem.startedTs}>
|
|
136
|
+
<Disclosure className={log.item}>
|
|
137
|
+
{isFailure ?
|
|
138
|
+
<>
|
|
139
|
+
<SyncIcon status="ERROR" />
|
|
140
|
+
<div>
|
|
141
|
+
Sync attempt failed
|
|
142
|
+
<div className={log.itemTimestamp}>
|
|
143
|
+
{fmt.dateTime(logItem.startedTs)}
|
|
144
|
+
</div>
|
|
145
|
+
</div>
|
|
146
|
+
</>
|
|
147
|
+
: <>
|
|
148
|
+
<SyncIcon status="IDLE" />
|
|
149
|
+
<div>
|
|
150
|
+
{"Sync successful. "}
|
|
151
|
+
{itemsSynced === 0 ?
|
|
152
|
+
"Everything up to date."
|
|
153
|
+
: fmt.plural(itemsSynced, {
|
|
154
|
+
one: "1 item synced.",
|
|
155
|
+
other: "# items synced.",
|
|
156
|
+
})
|
|
157
|
+
}
|
|
158
|
+
<div className={log.itemTimestamp}>
|
|
159
|
+
{fmt.dateTime(logItem.startedTs)}
|
|
160
|
+
</div>
|
|
161
|
+
</div>
|
|
162
|
+
</>
|
|
163
|
+
}
|
|
164
|
+
</Disclosure>
|
|
165
|
+
|
|
166
|
+
<DisclosureContent className={log.disclosureContent}>
|
|
167
|
+
{logItem.pull && (
|
|
168
|
+
<>
|
|
169
|
+
{logItem.pull.type === "SUCCESS" ?
|
|
170
|
+
<SyncActionSuccess
|
|
171
|
+
heading="Pull successful"
|
|
172
|
+
items={logItem.pull.value.pulled}
|
|
173
|
+
/>
|
|
174
|
+
: <SyncActionFailure
|
|
175
|
+
heading="Pull failed"
|
|
176
|
+
failure={logItem.pull.failure}
|
|
177
|
+
/>
|
|
178
|
+
}
|
|
179
|
+
</>
|
|
180
|
+
)}
|
|
181
|
+
|
|
182
|
+
{logItem.push && (
|
|
183
|
+
<>
|
|
184
|
+
{logItem.push.type === "SUCCESS" ?
|
|
185
|
+
<>
|
|
186
|
+
<SyncActionSuccess
|
|
187
|
+
heading="Push successful"
|
|
188
|
+
items={logItem.push.value.pushed}
|
|
189
|
+
/>
|
|
190
|
+
<SyncActionSuccess
|
|
191
|
+
heading="Patch successful"
|
|
192
|
+
items={logItem.push.value.pulled}
|
|
193
|
+
/>
|
|
194
|
+
</>
|
|
195
|
+
: <SyncActionFailure
|
|
196
|
+
heading="Push failed"
|
|
197
|
+
failure={logItem.push.failure}
|
|
198
|
+
/>
|
|
199
|
+
}
|
|
200
|
+
</>
|
|
201
|
+
)}
|
|
202
|
+
</DisclosureContent>
|
|
203
|
+
</DisclosureProvider>
|
|
204
|
+
);
|
|
205
|
+
})}
|
|
206
|
+
</div>
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
export function SyncLog() {
|
|
211
|
+
const syncState = useSyncState();
|
|
212
|
+
const syncLog = useSyncLog();
|
|
213
|
+
const lastSuccessfulSyncTs = useLastSuccessfulSyncTs();
|
|
214
|
+
|
|
215
|
+
return (
|
|
216
|
+
<SyncLogList
|
|
217
|
+
syncState={syncState}
|
|
218
|
+
syncLog={syncLog}
|
|
219
|
+
lastSuccessfulSyncTs={lastSuccessfulSyncTs}
|
|
220
|
+
/>
|
|
221
|
+
);
|
|
222
|
+
}
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
import preview from "../../.storybook/preview.tsx";
|
|
2
|
+
import { Failure, Success } from "../async-op.ts";
|
|
3
|
+
import { SyncLogList } from "./SyncLog.tsx";
|
|
4
|
+
|
|
5
|
+
const meta = preview.meta({
|
|
6
|
+
title: "Components/SyncLogList",
|
|
7
|
+
component: SyncLogList,
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
export const Inactive = meta.story({
|
|
11
|
+
args: {
|
|
12
|
+
syncState: "INACTIVE",
|
|
13
|
+
lastSuccessfulSyncTs: null,
|
|
14
|
+
syncLog: [],
|
|
15
|
+
},
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
export const Syncing = meta.story({
|
|
19
|
+
args: {
|
|
20
|
+
syncState: "SYNCING",
|
|
21
|
+
lastSuccessfulSyncTs: 1773753718052,
|
|
22
|
+
syncLog: [
|
|
23
|
+
{
|
|
24
|
+
startedTs: 1773753718052,
|
|
25
|
+
pull: null,
|
|
26
|
+
push: new Success({
|
|
27
|
+
pushed: [
|
|
28
|
+
{
|
|
29
|
+
id: "123",
|
|
30
|
+
name: "Test Item",
|
|
31
|
+
updatedTs: 1773753718052,
|
|
32
|
+
deleted: false,
|
|
33
|
+
},
|
|
34
|
+
],
|
|
35
|
+
pulled: [],
|
|
36
|
+
}),
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
export const Idle = meta.story({
|
|
43
|
+
args: {
|
|
44
|
+
syncState: "IDLE",
|
|
45
|
+
lastSuccessfulSyncTs: 1773753718052,
|
|
46
|
+
syncLog: [],
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
export const Waiting = meta.story({
|
|
51
|
+
args: {
|
|
52
|
+
syncState: "WAITING",
|
|
53
|
+
lastSuccessfulSyncTs: 1773753718052,
|
|
54
|
+
syncLog: [],
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
export const Authenticating = meta.story({
|
|
59
|
+
args: {
|
|
60
|
+
syncState: "AUTHENTICATING",
|
|
61
|
+
lastSuccessfulSyncTs: null,
|
|
62
|
+
syncLog: [],
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
export const Error = meta.story({
|
|
67
|
+
args: {
|
|
68
|
+
syncState: "ERROR",
|
|
69
|
+
lastSuccessfulSyncTs: 1773753718052,
|
|
70
|
+
syncLog: [
|
|
71
|
+
{
|
|
72
|
+
startedTs: 1773753718052,
|
|
73
|
+
pull: null,
|
|
74
|
+
push: new Failure({ type: "API_ERROR" as const, code: 500 }),
|
|
75
|
+
},
|
|
76
|
+
],
|
|
77
|
+
},
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
export const SuccessfulPullAndPush = meta.story({
|
|
81
|
+
args: {
|
|
82
|
+
syncState: "IDLE",
|
|
83
|
+
lastSuccessfulSyncTs: 1773753718052,
|
|
84
|
+
syncLog: [
|
|
85
|
+
{
|
|
86
|
+
startedTs: 1773753718052,
|
|
87
|
+
pull: new Success({
|
|
88
|
+
pulled: [
|
|
89
|
+
{
|
|
90
|
+
id: "p1",
|
|
91
|
+
name: "Pulled Item",
|
|
92
|
+
updatedTs: 1773753718052,
|
|
93
|
+
deleted: false,
|
|
94
|
+
},
|
|
95
|
+
],
|
|
96
|
+
}),
|
|
97
|
+
push: new Success({
|
|
98
|
+
pushed: [
|
|
99
|
+
{
|
|
100
|
+
id: "s1",
|
|
101
|
+
name: "Pushed Item",
|
|
102
|
+
updatedTs: 1773753718052,
|
|
103
|
+
deleted: false,
|
|
104
|
+
},
|
|
105
|
+
],
|
|
106
|
+
pulled: [
|
|
107
|
+
{
|
|
108
|
+
id: "s2",
|
|
109
|
+
name: "Patch Item",
|
|
110
|
+
updatedTs: 1773753718052,
|
|
111
|
+
deleted: false,
|
|
112
|
+
},
|
|
113
|
+
],
|
|
114
|
+
}),
|
|
115
|
+
},
|
|
116
|
+
],
|
|
117
|
+
},
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
export const AllUpToDate = meta.story({
|
|
121
|
+
args: {
|
|
122
|
+
syncState: "IDLE",
|
|
123
|
+
lastSuccessfulSyncTs: 1773753718052,
|
|
124
|
+
syncLog: [
|
|
125
|
+
{
|
|
126
|
+
startedTs: 1773753718052,
|
|
127
|
+
pull: new Success({ pulled: [] }),
|
|
128
|
+
push: new Success({ pushed: [], pulled: [] }),
|
|
129
|
+
},
|
|
130
|
+
],
|
|
131
|
+
},
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
export const PullFailure = meta.story({
|
|
135
|
+
args: {
|
|
136
|
+
syncState: "ERROR",
|
|
137
|
+
lastSuccessfulSyncTs: 1773753718052,
|
|
138
|
+
syncLog: [
|
|
139
|
+
{
|
|
140
|
+
startedTs: 1773753718052,
|
|
141
|
+
pull: new Failure({ type: "NETWORK_ERROR" as const }),
|
|
142
|
+
push: null,
|
|
143
|
+
},
|
|
144
|
+
],
|
|
145
|
+
},
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
export const DeletedAndUnnamedItems = meta.story({
|
|
149
|
+
args: {
|
|
150
|
+
syncState: "IDLE",
|
|
151
|
+
lastSuccessfulSyncTs: 1773753718052,
|
|
152
|
+
syncLog: [
|
|
153
|
+
{
|
|
154
|
+
startedTs: 1773753718052,
|
|
155
|
+
pull: null,
|
|
156
|
+
push: new Success({
|
|
157
|
+
pushed: [
|
|
158
|
+
{
|
|
159
|
+
id: "d1",
|
|
160
|
+
name: "Removed Campaign",
|
|
161
|
+
updatedTs: 1773753718052,
|
|
162
|
+
deleted: true,
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
id: "d2",
|
|
166
|
+
name: "",
|
|
167
|
+
updatedTs: 1773753718052,
|
|
168
|
+
deleted: false,
|
|
169
|
+
},
|
|
170
|
+
],
|
|
171
|
+
pulled: [],
|
|
172
|
+
}),
|
|
173
|
+
},
|
|
174
|
+
],
|
|
175
|
+
},
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
export const MultipleSyncEntries = meta.story({
|
|
179
|
+
args: {
|
|
180
|
+
syncState: "IDLE",
|
|
181
|
+
lastSuccessfulSyncTs: 1773753718052,
|
|
182
|
+
syncLog: [
|
|
183
|
+
{
|
|
184
|
+
startedTs: 1773753718052,
|
|
185
|
+
pull: new Success({ pulled: [] }),
|
|
186
|
+
push: new Success({ pushed: [], pulled: [] }),
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
startedTs: 1773753608052,
|
|
190
|
+
pull: new Success({
|
|
191
|
+
pulled: [
|
|
192
|
+
{
|
|
193
|
+
id: "m1",
|
|
194
|
+
name: "Synced Item",
|
|
195
|
+
updatedTs: 1773753608052,
|
|
196
|
+
deleted: false,
|
|
197
|
+
},
|
|
198
|
+
],
|
|
199
|
+
}),
|
|
200
|
+
push: new Success({
|
|
201
|
+
pushed: [
|
|
202
|
+
{
|
|
203
|
+
id: "m2",
|
|
204
|
+
name: "Pushed Item",
|
|
205
|
+
updatedTs: 1773753608052,
|
|
206
|
+
deleted: false,
|
|
207
|
+
},
|
|
208
|
+
],
|
|
209
|
+
pulled: [],
|
|
210
|
+
}),
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
startedTs: 1773753508052,
|
|
214
|
+
pull: new Failure({ type: "NETWORK_ERROR" as const }),
|
|
215
|
+
push: null,
|
|
216
|
+
},
|
|
217
|
+
],
|
|
218
|
+
},
|
|
219
|
+
});
|