convex-feedback-ui 0.1.8 → 0.2.0-beta.0
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 +30 -1
- package/dist/.tsbuildinfo +1 -1
- package/dist/native/expo/ExpoFeedbackBody.d.ts +1 -1
- package/dist/native/expo/ExpoFeedbackBody.d.ts.map +1 -1
- package/dist/native/expo/ExpoFeedbackBody.js +2 -2
- package/dist/native/expo/ExpoFeedbackBody.js.map +1 -1
- package/dist/native/expo/FeedbackRoutes.d.ts.map +1 -1
- package/dist/native/expo/FeedbackRoutes.js +17 -9
- package/dist/native/expo/FeedbackRoutes.js.map +1 -1
- package/dist/native/expo/FeedbackScreen.d.ts +1 -1
- package/dist/native/expo/FeedbackScreen.d.ts.map +1 -1
- package/dist/native/expo/FeedbackScreen.js +2 -2
- package/dist/native/expo/FeedbackScreen.js.map +1 -1
- package/dist/native/expo/FeedbackStack.d.ts +1 -1
- package/dist/native/expo/FeedbackStack.d.ts.map +1 -1
- package/dist/native/expo/FeedbackStack.js +15 -8
- package/dist/native/expo/FeedbackStack.js.map +1 -1
- package/dist/native/expo/FeedbackStackLayout.d.ts +1 -1
- package/dist/native/expo/FeedbackStackLayout.d.ts.map +1 -1
- package/dist/native/expo/FeedbackStackLayout.js +7 -2
- package/dist/native/expo/FeedbackStackLayout.js.map +1 -1
- package/dist/native/expo/index.d.ts +1 -0
- package/dist/native/expo/index.d.ts.map +1 -1
- package/dist/native/expo/index.js +1 -0
- package/dist/native/expo/index.js.map +1 -1
- package/dist/native/expo/types.d.ts +13 -0
- package/dist/native/expo/types.d.ts.map +1 -1
- package/dist/native/native/FeedbackScreen.d.ts +1 -1
- package/dist/native/native/FeedbackScreen.d.ts.map +1 -1
- package/dist/native/native/FeedbackScreen.js +2 -2
- package/dist/native/native/FeedbackScreen.js.map +1 -1
- package/dist/native/native/index.d.ts +1 -0
- package/dist/native/native/index.d.ts.map +1 -1
- package/dist/native/native/index.js +1 -0
- package/dist/native/native/index.js.map +1 -1
- package/dist/native/shared/helpers.d.ts +6 -1
- package/dist/native/shared/helpers.d.ts.map +1 -1
- package/dist/native/shared/helpers.js +33 -0
- package/dist/native/shared/helpers.js.map +1 -1
- package/dist/native/shared/ui/BodyContent.d.ts.map +1 -1
- package/dist/native/shared/ui/BodyContent.js +8 -2
- package/dist/native/shared/ui/BodyContent.js.map +1 -1
- package/dist/native/shared/ui/Button.d.ts +2 -1
- package/dist/native/shared/ui/Button.d.ts.map +1 -1
- package/dist/native/shared/ui/Button.js +3 -2
- package/dist/native/shared/ui/Button.js.map +1 -1
- package/dist/native/shared/ui/CommentBranch.d.ts.map +1 -1
- package/dist/native/shared/ui/CommentBranch.js +33 -11
- package/dist/native/shared/ui/CommentBranch.js.map +1 -1
- package/dist/native/shared/ui/EntryCard.d.ts.map +1 -1
- package/dist/native/shared/ui/EntryCard.js +13 -1
- package/dist/native/shared/ui/EntryCard.js.map +1 -1
- package/dist/native/shared/ui/EntryDetail.d.ts.map +1 -1
- package/dist/native/shared/ui/EntryDetail.js +23 -5
- package/dist/native/shared/ui/EntryDetail.js.map +1 -1
- package/dist/native/shared/ui/FeedbackScreenHeader.d.ts.map +1 -1
- package/dist/native/shared/ui/FeedbackScreenHeader.js +7 -2
- package/dist/native/shared/ui/FeedbackScreenHeader.js.map +1 -1
- package/dist/native/shared/ui/FeedbackScreenList.d.ts.map +1 -1
- package/dist/native/shared/ui/FeedbackScreenList.js +16 -8
- package/dist/native/shared/ui/FeedbackScreenList.js.map +1 -1
- package/dist/native/shared/ui/NewEntry.d.ts.map +1 -1
- package/dist/native/shared/ui/NewEntry.js +13 -11
- package/dist/native/shared/ui/NewEntry.js.map +1 -1
- package/dist/native/shared/ui/RoadmapScreen.d.ts +3 -0
- package/dist/native/shared/ui/RoadmapScreen.d.ts.map +1 -0
- package/dist/native/shared/ui/RoadmapScreen.js +73 -0
- package/dist/native/shared/ui/RoadmapScreen.js.map +1 -0
- package/dist/react/action.d.ts +14 -0
- package/dist/react/action.d.ts.map +1 -0
- package/dist/react/action.js +38 -0
- package/dist/react/action.js.map +1 -0
- package/dist/react/index.d.ts +1 -0
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +1 -0
- package/dist/react/index.js.map +1 -1
- package/dist/react/roadmap.d.ts +3 -0
- package/dist/react/roadmap.d.ts.map +1 -0
- package/dist/react/roadmap.js +59 -0
- package/dist/react/roadmap.js.map +1 -0
- package/dist/react/screen.d.ts +1 -1
- package/dist/react/screen.d.ts.map +1 -1
- package/dist/react/screen.js +99 -42
- package/dist/react/screen.js.map +1 -1
- package/dist/react/styles.css +42 -0
- package/dist/shared/context/FeedbackBodyProvider.d.ts +1 -1
- package/dist/shared/context/FeedbackBodyProvider.d.ts.map +1 -1
- package/dist/shared/context/FeedbackBodyProvider.js +8 -2
- package/dist/shared/context/FeedbackBodyProvider.js.map +1 -1
- package/dist/shared/helpers.d.ts +6 -0
- package/dist/shared/helpers.d.ts.map +1 -1
- package/dist/shared/helpers.js +12 -0
- package/dist/shared/helpers.js.map +1 -1
- package/dist/shared/types/index.d.ts +1 -0
- package/dist/shared/types/index.d.ts.map +1 -1
- package/dist/shared/types/messages.d.ts +1 -1
- package/dist/shared/types/messages.d.ts.map +1 -1
- package/dist/shared/types/roadmap.d.ts +17 -0
- package/dist/shared/types/roadmap.d.ts.map +1 -0
- package/dist/shared/types/roadmap.js +2 -0
- package/dist/shared/types/roadmap.js.map +1 -0
- package/dist/shared/types/screen.d.ts +10 -1
- package/dist/shared/types/screen.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/native/expo/ExpoFeedbackBody.tsx +2 -0
- package/src/native/expo/FeedbackRoutes.tsx +54 -30
- package/src/native/expo/FeedbackScreen.tsx +2 -0
- package/src/native/expo/FeedbackStack.tsx +46 -27
- package/src/native/expo/FeedbackStackLayout.tsx +11 -1
- package/src/native/expo/README.md +15 -0
- package/src/native/expo/index.ts +1 -0
- package/src/native/expo/types.ts +12 -0
- package/src/native/native/FeedbackScreen.tsx +2 -0
- package/src/native/native/README.md +4 -0
- package/src/native/native/index.ts +1 -0
- package/src/native/shared/helpers.ts +38 -1
- package/src/native/shared/ui/BodyContent.tsx +15 -2
- package/src/native/shared/ui/Button.tsx +4 -0
- package/src/native/shared/ui/CommentBranch.tsx +58 -15
- package/src/native/shared/ui/EntryCard.tsx +21 -3
- package/src/native/shared/ui/EntryDetail.tsx +42 -8
- package/src/native/shared/ui/FeedbackScreenHeader.tsx +9 -1
- package/src/native/shared/ui/FeedbackScreenList.tsx +28 -13
- package/src/native/shared/ui/NewEntry.tsx +25 -12
- package/src/native/shared/ui/RoadmapScreen.tsx +345 -0
- package/src/react/README.md +1 -1
- package/src/react/action.tsx +56 -0
- package/src/react/index.ts +1 -0
- package/src/react/roadmap.tsx +303 -0
- package/src/react/screen.tsx +199 -75
- package/src/react/styles.css +42 -0
- package/src/shared/context/FeedbackBodyProvider.tsx +9 -1
- package/src/shared/helpers.ts +16 -0
- package/src/shared/types/index.ts +1 -0
- package/src/shared/types/messages.ts +1 -1
- package/src/shared/types/roadmap.ts +25 -0
- package/src/shared/types/screen.ts +12 -1
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import { Pressable, ScrollView, Text, View } from "react-native";
|
|
4
|
+
import { FeedbackProvider, useFeedbackUi, } from "../../../shared/context/FeedbackProvider.js";
|
|
5
|
+
import { allowAuthenticatedAction } from "../../../shared/helpers.js";
|
|
6
|
+
import { useNativeAction } from "../helpers.js";
|
|
7
|
+
import { Button } from "./Button.js";
|
|
8
|
+
import { FeedbackBoard, FeedbackEntry } from "./primitives.js";
|
|
9
|
+
export function RoadmapScreen({ hooks, messages, theme, unstyled, onEntryOpen, onUnauthenticated, pageSize, entryPageSize, ...colors }) {
|
|
10
|
+
return (_jsx(FeedbackProvider, { messages: messages, theme: theme, unstyled: unstyled, children: _jsx(RoadmapScreenInner, { hooks: hooks, onEntryOpen: onEntryOpen, onUnauthenticated: onUnauthenticated, pageSize: pageSize ?? hooks.pageSizes.roadmap, entryPageSize: entryPageSize ?? hooks.pageSizes.entries, ...colors }) }));
|
|
11
|
+
}
|
|
12
|
+
function RoadmapScreenInner({ hooks, onEntryOpen, onUnauthenticated, pageSize, entryPageSize, ...colors }) {
|
|
13
|
+
const { messages, theme } = useFeedbackUi();
|
|
14
|
+
const [query, setQuery] = useState("");
|
|
15
|
+
const [selectedId, setSelectedId] = useState(null);
|
|
16
|
+
const roadmap = hooks.useRoadmap();
|
|
17
|
+
const search = hooks.useSearchRoadmap(query);
|
|
18
|
+
const searching = query.trim().length > 0;
|
|
19
|
+
const items = searching ? (search ?? []) : roadmap.results;
|
|
20
|
+
const selected = items.find((item) => item.id === selectedId) ?? null;
|
|
21
|
+
if (selected !== null) {
|
|
22
|
+
return (_jsx(FeedbackBoard.Root, { ...colors, children: _jsx(ScrollView, { contentContainerStyle: { gap: theme.spacing, padding: theme.spacing }, children: _jsx(RoadmapDetail, { item: selected, hooks: hooks, entryPageSize: entryPageSize, onEntryOpen: onEntryOpen, onUnauthenticated: onUnauthenticated, onBack: () => setSelectedId(null) }) }) }));
|
|
23
|
+
}
|
|
24
|
+
const loading = searching
|
|
25
|
+
? search === undefined
|
|
26
|
+
: roadmap.status === "LoadingFirstPage";
|
|
27
|
+
return (_jsxs(FeedbackBoard.Root, { ...colors, children: [_jsxs(FeedbackBoard.Header, { style: { gap: theme.spacing, padding: theme.spacing }, children: [_jsx(FeedbackBoard.Title, { children: "Roadmap" }), _jsx(Text, { style: { color: theme.colors.mutedText }, children: "See what is planned, in progress, and shipped." }), _jsx(FeedbackBoard.Search, { value: query, onValueChange: setQuery, placeholder: "Search roadmap" })] }), loading ? (_jsx(FeedbackBoard.State, { children: _jsx(Text, { style: { color: theme.colors.mutedText }, children: messages.board.loading }) })) : items.length === 0 ? (_jsx(FeedbackBoard.State, { children: _jsx(Text, { style: { color: theme.colors.mutedText }, children: searching ? "No roadmap items found." : "No roadmap items yet." }) })) : (_jsx(FeedbackBoard.List, { contentContainerStyle: { padding: theme.spacing }, children: items.map((item) => (_jsx(RoadmapCard, { item: item, onOpen: () => setSelectedId(item.id) }, item.id))) })), !searching &&
|
|
28
|
+
(roadmap.status === "CanLoadMore" ||
|
|
29
|
+
roadmap.status === "LoadingMore") && (_jsx(Button, { label: messages.board.loadMore, disabled: roadmap.status === "LoadingMore", onPress: () => roadmap.loadMore(pageSize) }))] }));
|
|
30
|
+
}
|
|
31
|
+
function RoadmapCard({ item, onOpen, }) {
|
|
32
|
+
const { theme } = useFeedbackUi();
|
|
33
|
+
return (_jsxs(Pressable, { onPress: onOpen, style: { gap: 5, padding: 12 }, children: [_jsxs(View, { style: {
|
|
34
|
+
flexDirection: "row",
|
|
35
|
+
justifyContent: "space-between",
|
|
36
|
+
gap: 8,
|
|
37
|
+
}, children: [_jsx(Text, { style: {
|
|
38
|
+
color: theme.colors.mutedText,
|
|
39
|
+
fontSize: 12,
|
|
40
|
+
fontWeight: "600",
|
|
41
|
+
}, children: item.status.replaceAll("_", " ") }), _jsxs(Text, { style: { color: theme.colors.mutedText, fontSize: 12 }, children: [item.feedbackCount, " linked"] })] }), _jsx(Text, { style: { color: theme.colors.text, fontSize: 16, fontWeight: "700" }, children: item.title }), item.description && (_jsx(Text, { style: { color: theme.colors.mutedText, lineHeight: 20 }, children: item.description }))] }));
|
|
42
|
+
}
|
|
43
|
+
function RoadmapDetail({ item, hooks, entryPageSize, onEntryOpen, onUnauthenticated, onBack, }) {
|
|
44
|
+
const { messages, theme } = useFeedbackUi();
|
|
45
|
+
const feedback = hooks.useRoadmapFeedback(item.id);
|
|
46
|
+
return (_jsxs(View, { style: { gap: theme.spacing }, children: [_jsx(Button, { label: messages.entry.back, onPress: onBack }), _jsxs(View, { style: { gap: 6 }, children: [_jsxs(Text, { style: {
|
|
47
|
+
color: theme.colors.mutedText,
|
|
48
|
+
fontSize: 12,
|
|
49
|
+
fontWeight: "600",
|
|
50
|
+
}, children: [item.status.replaceAll("_", " "), " \u00B7 Position ", item.position] }), _jsx(Text, { style: { color: theme.colors.text, fontSize: 23, fontWeight: "700" }, children: item.title }), _jsx(Text, { style: { color: theme.colors.mutedText, lineHeight: 21 }, children: item.description ?? "No description." })] }), _jsxs(View, { style: { gap: 4 }, children: [_jsx(RoadmapField, { label: "ID", value: item.id }), _jsx(RoadmapField, { label: "Linked feedback", value: String(item.feedbackCount) }), _jsx(RoadmapField, { label: "Created", value: new Date(item.createdAt).toLocaleString() }), _jsx(RoadmapField, { label: "Updated", value: new Date(item.updatedAt).toLocaleString() }), _jsx(RoadmapField, { label: "Document created", value: new Date(item.creationTime).toLocaleString() })] }), _jsx(Text, { style: { color: theme.colors.text, fontSize: 18, fontWeight: "700" }, children: "Attached feedback" }), feedback.status === "LoadingFirstPage" ? (_jsx(Text, { style: { color: theme.colors.mutedText }, children: messages.board.loading })) : feedback.results.length === 0 ? (_jsx(Text, { style: { color: theme.colors.mutedText }, children: "No feedback attached." })) : (_jsx(View, { style: { gap: 8 }, children: feedback.results.map((entry) => (_jsx(RoadmapEntry, { entry: entry, hooks: hooks, onOpen: onEntryOpen, onUnauthenticated: onUnauthenticated }, entry.id))) })), (feedback.status === "CanLoadMore" ||
|
|
51
|
+
feedback.status === "LoadingMore") && (_jsx(Button, { label: messages.comments.loadMore, disabled: feedback.status === "LoadingMore", onPress: () => feedback.loadMore(entryPageSize) }))] }));
|
|
52
|
+
}
|
|
53
|
+
function RoadmapField({ label, value }) {
|
|
54
|
+
const { theme } = useFeedbackUi();
|
|
55
|
+
return (_jsxs(View, { style: { flexDirection: "row", gap: 8 }, children: [_jsxs(Text, { style: { color: theme.colors.mutedText, fontWeight: "600" }, children: [label, ":"] }), _jsx(Text, { style: { flex: 1, color: theme.colors.text }, children: value })] }));
|
|
56
|
+
}
|
|
57
|
+
function RoadmapEntry({ entry, hooks, onOpen, onUnauthenticated, }) {
|
|
58
|
+
const { isAuthenticated } = useFeedbackAuth(hooks);
|
|
59
|
+
const setUpvote = hooks.useSetEntryUpvote();
|
|
60
|
+
const action = useNativeAction();
|
|
61
|
+
const toggle = (desiredState) => {
|
|
62
|
+
if (!allowAuthenticatedAction(isAuthenticated, onUnauthenticated) ||
|
|
63
|
+
action.pending) {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
void action.run(() => setUpvote({ entryId: entry.id, desiredState }), "Could not update vote");
|
|
67
|
+
};
|
|
68
|
+
return (_jsxs(FeedbackEntry.Root, { entry: entry, children: [_jsx(FeedbackEntry.Upvote, { disabled: isAuthenticated === undefined || action.pending, onToggle: toggle }), _jsx(Pressable, { onPress: onOpen === undefined ? undefined : () => onOpen(entry.id), accessibilityRole: onOpen === undefined ? undefined : "button", style: { flex: 1, minWidth: 0 }, children: _jsx(FeedbackEntry.Content, { children: _jsxs(View, { style: { gap: 5 }, children: [_jsxs(View, { style: { flexDirection: "row", gap: 8 }, children: [_jsx(FeedbackEntry.Kind, {}), _jsx(FeedbackEntry.Status, {})] }), _jsx(FeedbackEntry.Title, {}), _jsx(FeedbackEntry.Body, {}), _jsx(FeedbackEntry.CommentCount, {})] }) }) })] }));
|
|
69
|
+
}
|
|
70
|
+
function useFeedbackAuth(hooks) {
|
|
71
|
+
return { isAuthenticated: hooks.useIsAuthenticated() };
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=RoadmapScreen.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RoadmapScreen.js","sourceRoot":"","sources":["../../../../src/native/shared/ui/RoadmapScreen.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface FeedbackActionFailure {
|
|
2
|
+
message: string;
|
|
3
|
+
retry: () => void;
|
|
4
|
+
}
|
|
5
|
+
/** Runs a UI mutation and exposes a single retryable failure state. */
|
|
6
|
+
export declare function useFeedbackAction(): {
|
|
7
|
+
pending: boolean;
|
|
8
|
+
failure: FeedbackActionFailure | null;
|
|
9
|
+
run: <T>(action: () => Promise<T>, retryAction?: () => Promise<unknown>) => Promise<T | undefined>;
|
|
10
|
+
};
|
|
11
|
+
export declare function FeedbackActionError({ failure, }: {
|
|
12
|
+
failure: FeedbackActionFailure | null;
|
|
13
|
+
}): import("react").JSX.Element | null;
|
|
14
|
+
//# sourceMappingURL=action.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"action.d.ts","sourceRoot":"","sources":["../../src/react/action.tsx"],"names":[],"mappings":"AAEA,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAMD,uEAAuE;AACvE,wBAAgB,iBAAiB;;;UAIZ,CAAC,UACV,MAAM,OAAO,CAAC,CAAC,CAAC,gBACX,MAAM,OAAO,CAAC,OAAO,CAAC,KAClC,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;EAoB1B;AAED,wBAAgB,mBAAmB,CAAC,EAClC,OAAO,GACR,EAAE;IACD,OAAO,EAAE,qBAAqB,GAAG,IAAI,CAAC;CACvC,sCAUA"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
function messageForError(error) {
|
|
4
|
+
return error instanceof Error ? error.message : "Something went wrong.";
|
|
5
|
+
}
|
|
6
|
+
/** Runs a UI mutation and exposes a single retryable failure state. */
|
|
7
|
+
export function useFeedbackAction() {
|
|
8
|
+
const [pending, setPending] = useState(false);
|
|
9
|
+
const [failure, setFailure] = useState(null);
|
|
10
|
+
const run = async (action, retryAction = action) => {
|
|
11
|
+
if (pending)
|
|
12
|
+
return undefined;
|
|
13
|
+
setPending(true);
|
|
14
|
+
setFailure(null);
|
|
15
|
+
try {
|
|
16
|
+
return await action();
|
|
17
|
+
}
|
|
18
|
+
catch (error) {
|
|
19
|
+
setFailure({
|
|
20
|
+
message: messageForError(error),
|
|
21
|
+
retry: () => {
|
|
22
|
+
void run(retryAction, retryAction);
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
return undefined;
|
|
26
|
+
}
|
|
27
|
+
finally {
|
|
28
|
+
setPending(false);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
return { pending, failure, run };
|
|
32
|
+
}
|
|
33
|
+
export function FeedbackActionError({ failure, }) {
|
|
34
|
+
if (failure === null)
|
|
35
|
+
return null;
|
|
36
|
+
return (_jsxs("div", { className: "cf-action-error", role: "alert", children: [_jsx("span", { children: failure.message }), _jsx("button", { type: "button", className: "cf-button", onClick: failure.retry, children: "Retry" })] }));
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=action.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"action.js","sourceRoot":"","sources":["../../src/react/action.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAOjC,SAAS,eAAe,CAAC,KAAc;IACrC,OAAO,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,uBAAuB,CAAC;AAC1E,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,iBAAiB;IAC/B,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC9C,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAA+B,IAAI,CAAC,CAAC;IAE3E,MAAM,GAAG,GAAG,KAAK,EACf,MAAwB,EACxB,cAAsC,MAAM,EACpB,EAAE;QAC1B,IAAI,OAAO;YAAE,OAAO,SAAS,CAAC;QAC9B,UAAU,CAAC,IAAI,CAAC,CAAC;QACjB,UAAU,CAAC,IAAI,CAAC,CAAC;QACjB,IAAI,CAAC;YACH,OAAO,MAAM,MAAM,EAAE,CAAC;QACxB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,UAAU,CAAC;gBACT,OAAO,EAAE,eAAe,CAAC,KAAK,CAAC;gBAC/B,KAAK,EAAE,GAAG,EAAE;oBACV,KAAK,GAAG,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;gBACrC,CAAC;aACF,CAAC,CAAC;YACH,OAAO,SAAS,CAAC;QACnB,CAAC;gBAAS,CAAC;YACT,UAAU,CAAC,KAAK,CAAC,CAAC;QACpB,CAAC;IACH,CAAC,CAAC;IAEF,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC;AACnC,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,EAClC,OAAO,GAGR;IACC,IAAI,OAAO,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAClC,OAAO,CACL,eAAK,SAAS,EAAC,iBAAiB,EAAC,IAAI,EAAC,OAAO,aAC3C,yBAAO,OAAO,CAAC,OAAO,GAAQ,EAC9B,iBAAQ,IAAI,EAAC,QAAQ,EAAC,SAAS,EAAC,WAAW,EAAC,OAAO,EAAE,OAAO,CAAC,KAAK,sBAEzD,IACL,CACP,CAAC;AACJ,CAAC"}
|
package/dist/react/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,mBAAmB,iBAAiB,CAAC;AACrC,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,mBAAmB,iBAAiB,CAAC;AACrC,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC"}
|
package/dist/react/index.js
CHANGED
package/dist/react/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AAEnC,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AAEnC,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { RoadmapScreenProps } from "../shared/types/index.js";
|
|
2
|
+
export declare function RoadmapScreen({ hooks, messages, theme, unstyled, onEntryOpen, onUnauthenticated, pageSize, entryPageSize, ...colors }: RoadmapScreenProps): import("react").JSX.Element;
|
|
3
|
+
//# sourceMappingURL=roadmap.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"roadmap.d.ts","sourceRoot":"","sources":["../../src/react/roadmap.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAInE,wBAAgB,aAAa,CAAC,EAC5B,KAAK,EACL,QAAQ,EACR,KAAK,EACL,QAAQ,EACR,WAAW,EACX,iBAAiB,EACjB,QAAQ,EACR,aAAa,EACb,GAAG,MAAM,EACV,EAAE,kBAAkB,+BAepB"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
import { FeedbackProvider, useFeedbackUi, } from "../shared/context/FeedbackProvider.js";
|
|
5
|
+
import { allowAuthenticatedAction } from "../shared/helpers.js";
|
|
6
|
+
import { FeedbackActionError, useFeedbackAction } from "./action.js";
|
|
7
|
+
import { FeedbackBoard, FeedbackEntry } from "./primitives.js";
|
|
8
|
+
export function RoadmapScreen({ hooks, messages, theme, unstyled, onEntryOpen, onUnauthenticated, pageSize, entryPageSize, ...colors }) {
|
|
9
|
+
const resolvedPageSize = pageSize ?? hooks.pageSizes.roadmap;
|
|
10
|
+
const resolvedEntryPageSize = entryPageSize ?? hooks.pageSizes.entries;
|
|
11
|
+
return (_jsx(FeedbackProvider, { messages: messages, theme: theme, unstyled: unstyled, children: _jsx(RoadmapScreenInner, { hooks: hooks, onEntryOpen: onEntryOpen, onUnauthenticated: onUnauthenticated, pageSize: resolvedPageSize, entryPageSize: resolvedEntryPageSize, ...colors }) }));
|
|
12
|
+
}
|
|
13
|
+
function RoadmapScreenInner({ hooks, onEntryOpen, onUnauthenticated, pageSize, entryPageSize, ...colors }) {
|
|
14
|
+
const { messages } = useFeedbackUi();
|
|
15
|
+
const [query, setQuery] = useState("");
|
|
16
|
+
const [selectedId, setSelectedId] = useState(null);
|
|
17
|
+
const roadmap = hooks.useRoadmap();
|
|
18
|
+
const search = hooks.useSearchRoadmap(query);
|
|
19
|
+
const searching = query.trim().length > 0;
|
|
20
|
+
const items = searching ? (search ?? []) : roadmap.results;
|
|
21
|
+
const selected = items.find((item) => item.id === selectedId) ?? null;
|
|
22
|
+
if (selected !== null) {
|
|
23
|
+
return (_jsx(FeedbackBoard.Root, { ...colors, children: _jsx(RoadmapDetail, { item: selected, hooks: hooks, entryPageSize: entryPageSize, onEntryOpen: onEntryOpen, onUnauthenticated: onUnauthenticated, onBack: () => setSelectedId(null) }) }));
|
|
24
|
+
}
|
|
25
|
+
const loading = searching
|
|
26
|
+
? search === undefined
|
|
27
|
+
: roadmap.status === "LoadingFirstPage";
|
|
28
|
+
return (_jsxs(FeedbackBoard.Root, { ...colors, children: [_jsx(FeedbackBoard.Header, { children: _jsxs("div", { children: [_jsx(FeedbackBoard.Title, { children: "Roadmap" }), _jsx("p", { className: "cf-board__subtitle", children: "See what is planned, in progress, and shipped." })] }) }), _jsx(FeedbackBoard.Search, { value: query, onValueChange: setQuery, placeholder: "Search roadmap\u2026" }), loading ? (_jsx(FeedbackBoard.State, { children: messages.board.loading })) : items.length === 0 ? (_jsx(FeedbackBoard.State, { children: searching ? "No roadmap items found." : "No roadmap items yet." })) : (_jsx(FeedbackBoard.List, { children: items.map((item) => (_jsx(RoadmapCard, { item: item, onOpen: () => setSelectedId(item.id) }, item.id))) })), !searching &&
|
|
29
|
+
(roadmap.status === "CanLoadMore" ||
|
|
30
|
+
roadmap.status === "LoadingMore") && (_jsx("button", { type: "button", className: "cf-button", disabled: roadmap.status === "LoadingMore", onClick: () => roadmap.loadMore(pageSize), children: messages.board.loadMore }))] }));
|
|
31
|
+
}
|
|
32
|
+
function RoadmapCard({ item, onOpen, }) {
|
|
33
|
+
return (_jsx("button", { type: "button", className: "cf-entry cf-roadmap-card", onClick: onOpen, children: _jsxs("span", { className: "cf-entry__content", children: [_jsxs("span", { className: "cf-entry__meta", children: [_jsx("span", { className: "cf-entry__kind", children: item.status.replaceAll("_", " ") }), _jsxs("span", { className: "cf-status", children: [item.feedbackCount, " linked"] })] }), _jsx("strong", { className: "cf-entry__title", children: item.title }), item.description && (_jsx("span", { className: "cf-entry__body", children: item.description }))] }) }));
|
|
34
|
+
}
|
|
35
|
+
function RoadmapDetail({ item, hooks, entryPageSize, onEntryOpen, onUnauthenticated, onBack, }) {
|
|
36
|
+
const { messages } = useFeedbackUi();
|
|
37
|
+
const feedback = hooks.useRoadmapFeedback(item.id);
|
|
38
|
+
return (_jsxs("div", { className: "cf-detail", children: [_jsx("button", { type: "button", className: "cf-button cf-button--link", onClick: onBack, children: messages.entry.back }), _jsxs("header", { children: [_jsxs("div", { className: "cf-entry__meta", children: [_jsx("span", { className: "cf-entry__kind", children: item.status.replaceAll("_", " ") }), _jsxs("span", { className: "cf-status", children: ["Position ", item.position] })] }), _jsx("h2", { className: "cf-board__title", children: item.title }), _jsx("p", { className: "cf-entry__body", children: item.description ?? "No description." })] }), _jsxs("dl", { className: "cf-roadmap-meta", children: [_jsxs("div", { children: [_jsx("dt", { children: "ID" }), _jsx("dd", { children: item.id })] }), _jsxs("div", { children: [_jsx("dt", { children: "Linked feedback" }), _jsx("dd", { children: item.feedbackCount })] }), _jsxs("div", { children: [_jsx("dt", { children: "Created" }), _jsx("dd", { children: new Date(item.createdAt).toLocaleString() })] }), _jsxs("div", { children: [_jsx("dt", { children: "Updated" }), _jsx("dd", { children: new Date(item.updatedAt).toLocaleString() })] }), _jsxs("div", { children: [_jsx("dt", { children: "Document created" }), _jsx("dd", { children: new Date(item.creationTime).toLocaleString() })] })] }), _jsxs("section", { className: "cf-discussion", children: [_jsx("h3", { children: "Attached feedback" }), feedback.status === "LoadingFirstPage" ? (_jsx("p", { className: "cf-state", children: messages.board.loading })) : feedback.results.length === 0 ? (_jsx("p", { className: "cf-state", children: "No feedback attached." })) : (_jsx("div", { className: "cf-comments", children: feedback.results.map((entry) => (_jsx(RoadmapEntry, { entry: entry, hooks: hooks, onOpen: onEntryOpen, onUnauthenticated: onUnauthenticated }, entry.id))) })), (feedback.status === "CanLoadMore" ||
|
|
39
|
+
feedback.status === "LoadingMore") && (_jsx("button", { type: "button", className: "cf-button", disabled: feedback.status === "LoadingMore", onClick: () => feedback.loadMore(entryPageSize), children: messages.comments.loadMore }))] })] }));
|
|
40
|
+
}
|
|
41
|
+
function RoadmapEntry({ entry, hooks, onOpen, onUnauthenticated, }) {
|
|
42
|
+
const isAuthenticated = hooks.useIsAuthenticated();
|
|
43
|
+
const setUpvote = hooks.useSetEntryUpvote();
|
|
44
|
+
const action = useFeedbackAction();
|
|
45
|
+
const toggle = (desiredState) => {
|
|
46
|
+
if (!allowAuthenticatedAction(isAuthenticated, onUnauthenticated) ||
|
|
47
|
+
action.pending) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
void action.run(() => setUpvote({ entryId: entry.id, desiredState }));
|
|
51
|
+
};
|
|
52
|
+
return (_jsxs(_Fragment, { children: [_jsxs(FeedbackEntry.Root, { entry: entry, children: [_jsx(FeedbackEntry.Upvote, { disabled: isAuthenticated === undefined || action.pending, onToggle: toggle }), _jsxs(FeedbackEntry.Content, { onClick: () => onOpen?.(entry.id), onKeyDown: (event) => {
|
|
53
|
+
if (event.key === "Enter" || event.key === " ") {
|
|
54
|
+
event.preventDefault();
|
|
55
|
+
onOpen?.(entry.id);
|
|
56
|
+
}
|
|
57
|
+
}, role: onOpen === undefined ? undefined : "button", tabIndex: onOpen === undefined ? undefined : 0, children: [_jsxs("div", { className: "cf-entry__meta", children: [_jsx(FeedbackEntry.Kind, {}), _jsx(FeedbackEntry.Status, {}), _jsx(FeedbackEntry.CommentCount, {})] }), _jsx(FeedbackEntry.Title, {}), _jsx(FeedbackEntry.Body, {})] })] }), _jsx(FeedbackActionError, { failure: action.failure })] }));
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=roadmap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"roadmap.js","sourceRoot":"","sources":["../../src/react/roadmap.tsx"],"names":[],"mappings":"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"}
|
package/dist/react/screen.d.ts
CHANGED
|
@@ -2,5 +2,5 @@ import type { FeedbackScreenRootProps } from "../shared/types/";
|
|
|
2
2
|
export interface FeedbackScreenProps extends FeedbackScreenRootProps {
|
|
3
3
|
className?: string | undefined;
|
|
4
4
|
}
|
|
5
|
-
export declare function FeedbackScreen({ hooks, messages, theme, unstyled, entrySort, commentSort, enabledKinds, maxCommentDepth, transformComments, renderActor, debounceDuration, collectMetadata, emptyState, loading, ...props }: FeedbackScreenProps): import("react").JSX.Element;
|
|
5
|
+
export declare function FeedbackScreen({ hooks, messages, theme, unstyled, entrySort, commentSort, enabledKinds, maxCommentDepth, transformComments, renderActor, onUnauthenticated, debounceDuration, collectMetadata, emptyState, loading, ...props }: FeedbackScreenProps): import("react").JSX.Element;
|
|
6
6
|
//# sourceMappingURL=screen.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"screen.d.ts","sourceRoot":"","sources":["../../src/react/screen.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"screen.d.ts","sourceRoot":"","sources":["../../src/react/screen.tsx"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAOV,uBAAuB,EACxB,MAAM,kBAAkB,CAAC;AAkB1B,MAAM,WAAW,mBAAoB,SAAQ,uBAAuB;IAClE,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAChC;AAED,wBAAgB,cAAc,CAAC,EAC7B,KAAK,EACL,QAAQ,EACR,KAAK,EACL,QAAQ,EACR,SAAiB,EACjB,WAAmB,EACnB,YAAyB,EACzB,eAAmB,EACnB,iBAAiB,EACjB,WAAW,EACX,iBAAiB,EACjB,gBAAsB,EACtB,eAAe,EACf,UAAU,EACV,OAAO,EACP,GAAG,KAAK,EACT,EAAE,mBAAmB,+BAsBrB"}
|
package/dist/react/screen.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
3
|
import { useMemo, useState } from "react";
|
|
4
4
|
import { FeedbackBodyProvider, useFeedbackBody, } from "../shared/context/FeedbackBodyProvider.js";
|
|
5
5
|
import { FeedbackProvider, useFeedbackUi, } from "../shared/context/FeedbackProvider";
|
|
6
|
-
import { createEntryLabel, entryStatusChoices } from "../shared/helpers.js";
|
|
6
|
+
import { allowAuthenticatedAction, createEntryLabel, entryStatusChoices, } from "../shared/helpers.js";
|
|
7
7
|
import { Comment, ChoiceChips, FeedbackBoard, FeedbackEntry, FeedbackForm, } from "./primitives.js";
|
|
8
|
+
import { FeedbackActionError, useFeedbackAction } from "./action.js";
|
|
8
9
|
import { collectWebMetadata } from "./metadata.js";
|
|
9
10
|
import { collectEntryMetadata, formatMetadataKey } from "../shared/metadata.js";
|
|
10
11
|
const entryKinds = [
|
|
@@ -12,11 +13,11 @@ const entryKinds = [
|
|
|
12
13
|
"feature_request",
|
|
13
14
|
"bug_report",
|
|
14
15
|
];
|
|
15
|
-
export function FeedbackScreen({ hooks, messages, theme, unstyled, entrySort = "top", commentSort = "top", enabledKinds = entryKinds, maxCommentDepth = 5, transformComments, renderActor, debounceDuration = 300, collectMetadata, emptyState, loading, ...props }) {
|
|
16
|
-
return (_jsx(FeedbackProvider, { messages: messages, theme: theme, unstyled: unstyled, children: _jsx(FeedbackBodyProvider, { hooks: hooks, entrySort: entrySort, commentSort: commentSort, enabledKinds: enabledKinds, maxCommentDepth: maxCommentDepth, debounceDuration: debounceDuration, collectMetadata: collectMetadata, emptyState: emptyState, loading: loading, collectStandardMetadata: collectWebMetadata, transformComments: transformComments, renderActor: renderActor, children: _jsx(FeedbackScreenInner, { ...props }) }) }));
|
|
16
|
+
export function FeedbackScreen({ hooks, messages, theme, unstyled, entrySort = "top", commentSort = "top", enabledKinds = entryKinds, maxCommentDepth = 5, transformComments, renderActor, onUnauthenticated, debounceDuration = 300, collectMetadata, emptyState, loading, ...props }) {
|
|
17
|
+
return (_jsx(FeedbackProvider, { messages: messages, theme: theme, unstyled: unstyled, children: _jsx(FeedbackBodyProvider, { hooks: hooks, entrySort: entrySort, commentSort: commentSort, enabledKinds: enabledKinds, maxCommentDepth: maxCommentDepth, debounceDuration: debounceDuration, collectMetadata: collectMetadata, emptyState: emptyState, loading: loading, collectStandardMetadata: collectWebMetadata, transformComments: transformComments, renderActor: renderActor, onUnauthenticated: onUnauthenticated, children: _jsx(FeedbackScreenInner, { ...props }) }) }));
|
|
17
18
|
}
|
|
18
19
|
function FeedbackScreenInner({ className, ...colors }) {
|
|
19
|
-
const { hooks, entrySort, enabledKinds, showForm, setShowForm, setSelectedEntryId, selectedEntryId, statusFilter, setStatusFilter, query, setQuery, debouncedQuery, emptyState, loading: loadingIndicator, } = useFeedbackBody();
|
|
20
|
+
const { hooks, entrySort, enabledKinds, showForm, setShowForm, setSelectedEntryId, selectedEntryId, statusFilter, setStatusFilter, query, setQuery, debouncedQuery, emptyState, loading: loadingIndicator, isAuthenticated, onUnauthenticated, } = useFeedbackBody();
|
|
20
21
|
const { messages } = useFeedbackUi();
|
|
21
22
|
const list = hooks.useEntries({
|
|
22
23
|
sort: entrySort,
|
|
@@ -31,37 +32,59 @@ function FeedbackScreenInner({ className, ...colors }) {
|
|
|
31
32
|
if (selectedEntryId !== null) {
|
|
32
33
|
return (_jsx(FeedbackBoard.Root, { className: className, ...colors, children: _jsx(EntryDetail, { entryId: selectedEntryId, onBack: () => setSelectedEntryId(null) }) }));
|
|
33
34
|
}
|
|
34
|
-
const
|
|
35
|
+
const normalizedQuery = query.trim();
|
|
36
|
+
const normalizedDebouncedQuery = debouncedQuery.trim();
|
|
37
|
+
const searching = normalizedQuery.length > 0;
|
|
35
38
|
const entries = searching ? searchResults : list.results;
|
|
36
39
|
const isLoading = searching
|
|
37
|
-
?
|
|
40
|
+
? normalizedQuery !== normalizedDebouncedQuery ||
|
|
41
|
+
searchResults === undefined
|
|
38
42
|
: list.status === "LoadingFirstPage";
|
|
39
|
-
return (_jsxs(FeedbackBoard.Root, { className: className, ...colors, children: [_jsxs(FeedbackBoard.Header, { children: [_jsxs("div", { children: [_jsx(FeedbackBoard.Title, {}), _jsx("p", { className: "cf-board__subtitle", children: messages.board.subtitle }), _jsx(ChoiceChips, { "aria-label": messages.board.statusFilter, options: entryStatusChoices(messages), value: statusFilter, onValueChange: setStatusFilter })] }), _jsx("button", { type: "button", className: "cf-button cf-button--primary",
|
|
43
|
+
return (_jsxs(FeedbackBoard.Root, { className: className, ...colors, children: [_jsxs(FeedbackBoard.Header, { children: [_jsxs("div", { children: [_jsx(FeedbackBoard.Title, {}), _jsx("p", { className: "cf-board__subtitle", children: messages.board.subtitle }), _jsx(ChoiceChips, { "aria-label": messages.board.statusFilter, options: entryStatusChoices(messages), value: statusFilter, onValueChange: setStatusFilter })] }), _jsx("button", { type: "button", className: "cf-button cf-button--primary", disabled: isAuthenticated === undefined, onClick: () => {
|
|
44
|
+
if (!allowAuthenticatedAction(isAuthenticated, onUnauthenticated)) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
setShowForm((current) => !current);
|
|
48
|
+
}, children: showForm
|
|
40
49
|
? messages.form.cancel
|
|
41
50
|
: createEntryLabel(enabledKinds, messages) })] }), showForm && (_jsx(CreateEntryForm, { onCreated: (entryId) => {
|
|
42
51
|
setShowForm(false);
|
|
43
52
|
setSelectedEntryId(entryId);
|
|
44
53
|
} })), _jsx(FeedbackBoard.Search, { value: query, onValueChange: setQuery }), isLoading ? (_jsx(FeedbackBoard.State, { children: loadingIndicator ?? (_jsx("span", { className: "cf-state__message", children: messages.board.loading })) })) : entries !== undefined && entries.length === 0 ? (_jsxs(FeedbackBoard.State, { children: [emptyState, _jsx("span", { className: "cf-state__message", children: searching
|
|
45
54
|
? messages.board.noSearchResults
|
|
46
|
-
: messages.board.noEntries }), _jsx("button", { type: "button", className: "cf-button cf-button--primary",
|
|
55
|
+
: messages.board.noEntries }), _jsx("button", { type: "button", className: "cf-button cf-button--primary", disabled: isAuthenticated === undefined, onClick: () => {
|
|
56
|
+
if (allowAuthenticatedAction(isAuthenticated, onUnauthenticated)) {
|
|
57
|
+
setShowForm(true);
|
|
58
|
+
}
|
|
59
|
+
}, children: createEntryLabel(enabledKinds, messages) })] })) : (_jsx(FeedbackBoard.List, { children: (entries ?? []).map((entry) => (_jsx(EntryCard, { entry: entry, hooks: hooks, onOpen: () => setSelectedEntryId(entry.id) }, entry.id))) })), !searching &&
|
|
60
|
+
(list.status === "CanLoadMore" || list.status === "LoadingMore") && (_jsx("button", { type: "button", className: "cf-button", disabled: list.status === "LoadingMore", onClick: () => list.loadMore(hooks.pageSizes.entries), children: messages.board.loadMore }))] }));
|
|
47
61
|
}
|
|
48
62
|
function EntryCard({ entry, hooks, onOpen }) {
|
|
63
|
+
const { isAuthenticated, onUnauthenticated } = useFeedbackBody();
|
|
49
64
|
const setUpvote = hooks.useSetEntryUpvote();
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
65
|
+
const action = useFeedbackAction();
|
|
66
|
+
const toggleUpvote = (desiredState) => {
|
|
67
|
+
if (!allowAuthenticatedAction(isAuthenticated, onUnauthenticated) ||
|
|
68
|
+
action.pending) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
void action.run(() => setUpvote({ entryId: entry.id, desiredState }));
|
|
72
|
+
};
|
|
73
|
+
return (_jsxs(_Fragment, { children: [_jsxs(FeedbackEntry.Root, { entry: entry, children: [_jsx(FeedbackEntry.Upvote, { disabled: isAuthenticated === undefined || action.pending, onToggle: toggleUpvote }), _jsxs(FeedbackEntry.Content, { onClick: onOpen, onKeyDown: (event) => {
|
|
74
|
+
if (event.key === "Enter" || event.key === " ") {
|
|
75
|
+
event.preventDefault();
|
|
76
|
+
onOpen();
|
|
77
|
+
}
|
|
78
|
+
}, role: "button", tabIndex: 0, children: [_jsxs("div", { className: "cf-entry__meta", children: [_jsx(FeedbackEntry.Kind, {}), _jsx(FeedbackEntry.Status, {}), _jsx(FeedbackEntry.CommentCount, {})] }), _jsx(FeedbackEntry.Title, {}), _jsx(FeedbackEntry.Body, {})] })] }), _jsx(FeedbackActionError, { failure: action.failure })] }));
|
|
56
79
|
}
|
|
57
80
|
function CreateEntryForm({ onCreated }) {
|
|
58
|
-
const { hooks, enabledKinds, collectMetadata, collectStandardMetadata } = useFeedbackBody();
|
|
81
|
+
const { hooks, enabledKinds, collectMetadata, collectStandardMetadata, isAuthenticated, onUnauthenticated, } = useFeedbackBody();
|
|
59
82
|
const { messages } = useFeedbackUi();
|
|
60
83
|
const [kind, setKind] = useState(enabledKinds[0] ?? "feedback");
|
|
61
84
|
const [title, setTitle] = useState("");
|
|
62
85
|
const [body, setBody] = useState("");
|
|
63
|
-
const [submitting, setSubmitting] = useState(false);
|
|
64
86
|
const createEntry = hooks.useCreateEntry();
|
|
87
|
+
const action = useFeedbackAction();
|
|
65
88
|
const similar = hooks.useSimilarEntries({ title, body, kind });
|
|
66
89
|
const [confirmingDuplicate, setConfirmingDuplicate] = useState(false);
|
|
67
90
|
const submit = (event) => {
|
|
@@ -78,10 +101,11 @@ function CreateEntryForm({ onCreated }) {
|
|
|
78
101
|
void create();
|
|
79
102
|
};
|
|
80
103
|
const create = async () => {
|
|
81
|
-
if (
|
|
104
|
+
if (action.pending)
|
|
82
105
|
return;
|
|
83
|
-
|
|
84
|
-
|
|
106
|
+
if (!allowAuthenticatedAction(isAuthenticated, onUnauthenticated))
|
|
107
|
+
return;
|
|
108
|
+
await action.run(async () => {
|
|
85
109
|
const metadata = await collectEntryMetadata(collectMetadata, kind, collectStandardMetadata);
|
|
86
110
|
const entryId = await createEntry({
|
|
87
111
|
kind,
|
|
@@ -90,10 +114,7 @@ function CreateEntryForm({ onCreated }) {
|
|
|
90
114
|
...(metadata === undefined ? {} : { metadata }),
|
|
91
115
|
});
|
|
92
116
|
onCreated(entryId);
|
|
93
|
-
}
|
|
94
|
-
finally {
|
|
95
|
-
setSubmitting(false);
|
|
96
|
-
}
|
|
117
|
+
});
|
|
97
118
|
};
|
|
98
119
|
const suggestions = useMemo(() => {
|
|
99
120
|
if (similar === undefined)
|
|
@@ -105,7 +126,7 @@ function CreateEntryForm({ onCreated }) {
|
|
|
105
126
|
label: messages.kinds[value],
|
|
106
127
|
})), value: kind, onValueChange: setKind })] })), _jsxs("label", { className: "cf-field", children: [_jsx("span", { children: messages.form.title }), _jsx(FeedbackForm.Input, { value: title, onChange: (event) => setTitle(event.currentTarget.value), placeholder: messages.form.titlePlaceholder, required: true })] }), _jsxs("label", { className: "cf-field", children: [_jsx("span", { children: messages.form.body }), _jsx(FeedbackForm.Textarea, { value: body, onChange: (event) => setBody(event.currentTarget.value), placeholder: messages.form.bodyPlaceholder, rows: 5, required: true })] }), suggestions.length > 0 && (_jsxs("aside", { className: "cf-duplicates", children: [_jsx("strong", { children: similar?.exact.length
|
|
107
128
|
? messages.form.exactDuplicate
|
|
108
|
-
: messages.form.possibleDuplicates }), _jsx("div", { className: "cf-duplicates__list", children: suggestions.map((entry) => (_jsxs("div", { className: "cf-duplicate", children: [_jsxs("div", { className: "cf-entry__meta", children: [_jsx("span", { className: "cf-entry__kind", children: messages.kinds[entry.kind] }), _jsx("span", { className: "cf-status", children: messages.statuses[entry.status] })] }), _jsx("strong", { children: entry.title }), _jsx("span", { className: "cf-duplicate__body", children: entry.body }), _jsxs("span", { className: "cf-duplicate__meta", children: ["\u25B2 ", entry.upvoteCount, " \u00B7", " ", messages.entry.comments(entry.commentCount)] })] }, entry.id))) })] })), _jsx(FeedbackForm.Submit, { submitting:
|
|
129
|
+
: messages.form.possibleDuplicates }), _jsx("div", { className: "cf-duplicates__list", children: suggestions.map((entry) => (_jsxs("div", { className: "cf-duplicate", children: [_jsxs("div", { className: "cf-entry__meta", children: [_jsx("span", { className: "cf-entry__kind", children: messages.kinds[entry.kind] }), _jsx("span", { className: "cf-status", children: messages.statuses[entry.status] })] }), _jsx("strong", { children: entry.title }), _jsx("span", { className: "cf-duplicate__body", children: entry.body }), _jsxs("span", { className: "cf-duplicate__meta", children: ["\u25B2 ", entry.upvoteCount, " \u00B7", " ", messages.entry.comments(entry.commentCount)] })] }, entry.id))) })] })), _jsx(FeedbackForm.Submit, { submitting: action.pending, disabled: confirmingDuplicate || action.pending || isAuthenticated === undefined }), _jsx(FeedbackActionError, { failure: action.failure }), confirmingDuplicate && (_jsx("div", { className: "cf-confirm-backdrop", children: _jsxs("div", { className: "cf-confirm", role: "alertdialog", "aria-modal": "true", "aria-labelledby": "cf-duplicate-confirm-title", children: [_jsx("strong", { id: "cf-duplicate-confirm-title", children: similar?.exact.length
|
|
109
130
|
? messages.form.exactDuplicate
|
|
110
131
|
: messages.form.possibleDuplicates }), _jsx("p", { children: messages.form.duplicateWarning }), _jsxs("div", { className: "cf-inline-actions", children: [_jsx("button", { type: "button", className: "cf-button", onClick: () => setConfirmingDuplicate(false), children: messages.form.cancel }), _jsx("button", { type: "button", className: "cf-button cf-button--primary", onClick: () => {
|
|
111
132
|
setConfirmingDuplicate(false);
|
|
@@ -113,7 +134,7 @@ function CreateEntryForm({ onCreated }) {
|
|
|
113
134
|
}, children: messages.form.submitAnyway })] })] }) }))] }));
|
|
114
135
|
}
|
|
115
136
|
function EntryDetail({ entryId, onBack }) {
|
|
116
|
-
const { hooks, commentSort, transformComments } = useFeedbackBody();
|
|
137
|
+
const { hooks, commentSort, transformComments, isAuthenticated, onUnauthenticated, } = useFeedbackBody();
|
|
117
138
|
const { messages } = useFeedbackUi();
|
|
118
139
|
const entry = hooks.useEntry(entryId);
|
|
119
140
|
const setUpvote = hooks.useSetEntryUpvote();
|
|
@@ -121,19 +142,35 @@ function EntryDetail({ entryId, onBack }) {
|
|
|
121
142
|
const createComment = hooks.useCreateComment();
|
|
122
143
|
const [body, setBody] = useState("");
|
|
123
144
|
const [showMetadata, setShowMetadata] = useState(false);
|
|
145
|
+
const upvoteAction = useFeedbackAction();
|
|
146
|
+
const commentAction = useFeedbackAction();
|
|
147
|
+
const toggleUpvote = (desiredState) => {
|
|
148
|
+
if (!allowAuthenticatedAction(isAuthenticated, onUnauthenticated) ||
|
|
149
|
+
upvoteAction.pending) {
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
void upvoteAction.run(() => setUpvote({ entryId, desiredState }));
|
|
153
|
+
};
|
|
124
154
|
const visibleComments = useMemo(() => transformComments?.(comments.results) ?? comments.results, [comments.results, transformComments]);
|
|
125
155
|
if (entry === undefined)
|
|
126
156
|
return _jsx("p", { className: "cf-state", children: messages.board.loading });
|
|
127
157
|
if (entry === null)
|
|
128
158
|
return (_jsx("button", { type: "button", className: "cf-button", onClick: onBack, children: messages.entry.back }));
|
|
129
|
-
return (_jsxs("div", { className: "cf-detail", children: [_jsx("button", { type: "button", className: "cf-button cf-button--link", onClick: onBack, children: messages.entry.back }), _jsxs(FeedbackEntry.Root, { entry: entry, children: [_jsx(FeedbackEntry.Upvote, {
|
|
159
|
+
return (_jsxs("div", { className: "cf-detail", children: [_jsx("button", { type: "button", className: "cf-button cf-button--link", onClick: onBack, children: messages.entry.back }), _jsxs(FeedbackEntry.Root, { entry: entry, children: [_jsx(FeedbackEntry.Upvote, { disabled: isAuthenticated === undefined || upvoteAction.pending, onToggle: toggleUpvote }), _jsxs(FeedbackEntry.Content, { children: [_jsxs("div", { className: "cf-entry__meta", children: [_jsx(FeedbackEntry.Status, {}), _jsx(FeedbackEntry.CommentCount, {})] }), _jsx(FeedbackEntry.Title, {}), _jsx(FeedbackEntry.Body, {})] })] }), _jsx(FeedbackActionError, { failure: upvoteAction.failure }), entry.metadata !== undefined && (_jsx("div", { children: _jsx("button", { type: "button", className: "cf-button", onClick: () => setShowMetadata(true), children: messages.metadata.view }) })), showMetadata && entry.metadata !== undefined && (_jsx(MetadataDialog, { metadata: entry.metadata, onClose: () => setShowMetadata(false) })), _jsxs("section", { className: "cf-discussion", children: [_jsx("h3", { children: messages.comments.title }), _jsxs(FeedbackForm.Root, { onSubmit: (event) => {
|
|
130
160
|
event.preventDefault();
|
|
131
161
|
if (body.trim().length === 0)
|
|
132
162
|
return;
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
163
|
+
if (!allowAuthenticatedAction(isAuthenticated, onUnauthenticated) ||
|
|
164
|
+
commentAction.pending) {
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
void commentAction.run(async () => {
|
|
168
|
+
await createComment({ entryId, body });
|
|
169
|
+
setBody("");
|
|
170
|
+
});
|
|
171
|
+
}, children: [_jsx(FeedbackForm.Textarea, { value: body, onChange: (event) => setBody(event.currentTarget.value), placeholder: messages.comments.placeholder, rows: 3 }), _jsx("button", { type: "submit", className: "cf-button cf-button--primary", disabled: isAuthenticated === undefined || commentAction.pending, children: messages.comments.submit })] }), _jsx(FeedbackActionError, { failure: commentAction.failure }), comments.status === "LoadingFirstPage" && (_jsx("p", { className: "cf-state", children: messages.board.loading })), comments.status !== "LoadingFirstPage" &&
|
|
172
|
+
visibleComments.length === 0 && (_jsx("p", { className: "cf-state", children: messages.comments.noComments })), _jsx("div", { className: "cf-comments", children: visibleComments.map((comment) => (_jsx(CommentBranch, { comment: comment, entryId: entryId }, comment.id))) }), (comments.status === "CanLoadMore" ||
|
|
173
|
+
comments.status === "LoadingMore") && (_jsx("button", { type: "button", className: "cf-button", disabled: comments.status === "LoadingMore", onClick: () => comments.loadMore(hooks.pageSizes.comments), children: messages.comments.loadMore }))] })] }));
|
|
137
174
|
}
|
|
138
175
|
function MetadataDialog({ metadata, onClose, }) {
|
|
139
176
|
const { messages } = useFeedbackUi();
|
|
@@ -145,26 +182,45 @@ function MetadataDialog({ metadata, onClose, }) {
|
|
|
145
182
|
return (_jsx("div", { className: "cf-confirm-backdrop", onMouseDown: onClose, children: _jsxs("div", { className: "cf-confirm cf-metadata-dialog", role: "dialog", "aria-modal": "true", "aria-labelledby": "cf-metadata-title", onMouseDown: (event) => event.stopPropagation(), children: [_jsx("h3", { id: "cf-metadata-title", children: messages.metadata.title }), hasValues ? (sections.map(([label, values]) => values === undefined || Object.keys(values).length === 0 ? null : (_jsxs("section", { className: "cf-metadata-section", children: [_jsx("h4", { children: label }), _jsx("dl", { children: Object.entries(values).map(([key, value]) => (_jsxs("div", { className: "cf-metadata-row", children: [_jsx("dt", { children: formatMetadataKey(key) }), _jsx("dd", { children: String(value) })] }, key))) })] }, label)))) : (_jsx("p", { children: messages.metadata.empty })), _jsx("div", { className: "cf-inline-actions", children: _jsx("button", { type: "button", className: "cf-button", onClick: onClose, children: messages.metadata.close }) })] }) }));
|
|
146
183
|
}
|
|
147
184
|
function CommentBranch({ comment, entryId }) {
|
|
148
|
-
const { hooks, maxCommentDepth, renderActor } = useFeedbackBody();
|
|
185
|
+
const { hooks, maxCommentDepth, renderActor, isAuthenticated, onUnauthenticated, } = useFeedbackBody();
|
|
149
186
|
const { messages } = useFeedbackUi();
|
|
150
187
|
const [expanded, setExpanded] = useState(false);
|
|
151
188
|
const [replying, setReplying] = useState(false);
|
|
152
189
|
const [replyBody, setReplyBody] = useState("");
|
|
153
190
|
const setLike = hooks.useSetCommentLike();
|
|
154
191
|
const createComment = hooks.useCreateComment();
|
|
155
|
-
|
|
192
|
+
const likeAction = useFeedbackAction();
|
|
193
|
+
const replyAction = useFeedbackAction();
|
|
194
|
+
const toggleLike = (desiredState) => {
|
|
195
|
+
if (!allowAuthenticatedAction(isAuthenticated, onUnauthenticated) ||
|
|
196
|
+
likeAction.pending) {
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
void likeAction.run(() => setLike({ commentId: comment.id, desiredState }));
|
|
200
|
+
};
|
|
201
|
+
return (_jsxs(Comment.Root, { comment: comment, children: [renderActor === undefined ? null : (_jsx("div", { className: "cf-comment__author", children: renderActor(comment.actorId) })), _jsx(Comment.Body, {}), _jsxs("div", { className: "cf-comment__toolbar", children: [_jsx(Comment.Like, { disabled: isAuthenticated === undefined || likeAction.pending, onToggle: toggleLike }), comment.body !== null && comment.depth < maxCommentDepth && (_jsx(Comment.Reply, { disabled: isAuthenticated === undefined || replyAction.pending, onActivate: () => {
|
|
202
|
+
if (allowAuthenticatedAction(isAuthenticated, onUnauthenticated)) {
|
|
203
|
+
setReplying((value) => !value);
|
|
204
|
+
}
|
|
205
|
+
} })), _jsx(Comment.RepliesButton, { expanded: expanded, onExpandedChange: setExpanded })] }), _jsx(FeedbackActionError, { failure: likeAction.failure }), replying && (_jsxs(FeedbackForm.Root, { onSubmit: (event) => {
|
|
156
206
|
event.preventDefault();
|
|
157
207
|
if (replyBody.trim().length === 0)
|
|
158
208
|
return;
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
209
|
+
if (!allowAuthenticatedAction(isAuthenticated, onUnauthenticated) ||
|
|
210
|
+
replyAction.pending) {
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
void replyAction.run(async () => {
|
|
214
|
+
await createComment({
|
|
215
|
+
entryId,
|
|
216
|
+
parentCommentId: comment.id,
|
|
217
|
+
body: replyBody,
|
|
218
|
+
});
|
|
219
|
+
setReplyBody("");
|
|
220
|
+
setReplying(false);
|
|
221
|
+
setExpanded(true);
|
|
163
222
|
});
|
|
164
|
-
|
|
165
|
-
setReplying(false);
|
|
166
|
-
setExpanded(true);
|
|
167
|
-
}, children: [_jsx(FeedbackForm.Textarea, { value: replyBody, onChange: (event) => setReplyBody(event.currentTarget.value), placeholder: messages.comments.placeholder, rows: 2 }), _jsxs("div", { className: "cf-inline-actions", children: [_jsx("button", { type: "submit", className: "cf-button cf-button--primary", children: messages.comments.reply }), _jsx("button", { type: "button", className: "cf-button", onClick: () => setReplying(false), children: messages.comments.cancelReply })] })] })), expanded && _jsx(ReplyList, { entryId: entryId, parentCommentId: comment.id })] }));
|
|
223
|
+
}, children: [_jsx(FeedbackForm.Textarea, { value: replyBody, onChange: (event) => setReplyBody(event.currentTarget.value), placeholder: messages.comments.placeholder, rows: 2 }), _jsxs("div", { className: "cf-inline-actions", children: [_jsx("button", { type: "submit", className: "cf-button cf-button--primary", disabled: isAuthenticated === undefined || replyAction.pending, children: messages.comments.reply }), _jsx("button", { type: "button", className: "cf-button", onClick: () => setReplying(false), children: messages.comments.cancelReply })] })] })), _jsx(FeedbackActionError, { failure: replyAction.failure }), expanded && _jsx(ReplyList, { entryId: entryId, parentCommentId: comment.id })] }));
|
|
168
224
|
}
|
|
169
225
|
function ReplyList({ entryId, parentCommentId }) {
|
|
170
226
|
const { hooks, commentSort, transformComments } = useFeedbackBody();
|
|
@@ -175,6 +231,7 @@ function ReplyList({ entryId, parentCommentId }) {
|
|
|
175
231
|
sort: commentSort,
|
|
176
232
|
});
|
|
177
233
|
const visibleReplies = useMemo(() => transformComments?.(replies.results) ?? replies.results, [replies.results, transformComments]);
|
|
178
|
-
return (_jsxs(Comment.Children, { children: [replies.status === "LoadingFirstPage" && (_jsx("p", { className: "cf-state", children: messages.board.loading })), visibleReplies.map((reply) => (_jsx(CommentBranch, { comment: reply, entryId: entryId }, reply.id))), replies.status === "CanLoadMore"
|
|
234
|
+
return (_jsxs(Comment.Children, { children: [replies.status === "LoadingFirstPage" && (_jsx("p", { className: "cf-state", children: messages.board.loading })), visibleReplies.map((reply) => (_jsx(CommentBranch, { comment: reply, entryId: entryId }, reply.id))), (replies.status === "CanLoadMore" ||
|
|
235
|
+
replies.status === "LoadingMore") && (_jsx("button", { type: "button", className: "cf-button", disabled: replies.status === "LoadingMore", onClick: () => replies.loadMore(hooks.pageSizes.replies), children: messages.comments.loadMore }))] }));
|
|
179
236
|
}
|
|
180
237
|
//# sourceMappingURL=screen.js.map
|