@stackoverflow/backstage-plugin-stack-overflow-teams 1.5.0 → 1.6.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 +3 -3
- package/config.d.ts +1 -1
- package/package.json +4 -12
- package/dist/api/StackOverflowAPI.esm.js +0 -125
- package/dist/api/StackOverflowAPI.esm.js.map +0 -1
- package/dist/components/StackOverflow/StackOverflowMe.esm.js +0 -110
- package/dist/components/StackOverflow/StackOverflowMe.esm.js.map +0 -1
- package/dist/components/StackOverflow/StackOverflowPostQuestionModal.esm.js +0 -406
- package/dist/components/StackOverflow/StackOverflowPostQuestionModal.esm.js.map +0 -1
- package/dist/components/StackOverflow/StackOverflowPosts.esm.js +0 -402
- package/dist/components/StackOverflow/StackOverflowPosts.esm.js.map +0 -1
- package/dist/components/StackOverflow/StackOverflowSearchResultListItem.esm.js +0 -147
- package/dist/components/StackOverflow/StackOverflowSearchResultListItem.esm.js.map +0 -1
- package/dist/components/StackOverflow/StackOverflowTags.esm.js +0 -117
- package/dist/components/StackOverflow/StackOverflowTags.esm.js.map +0 -1
- package/dist/components/StackOverflow/StackOverflowUsers.esm.js +0 -193
- package/dist/components/StackOverflow/StackOverflowUsers.esm.js.map +0 -1
- package/dist/components/StackOverflow/TiptapEditor.esm.js +0 -308
- package/dist/components/StackOverflow/TiptapEditor.esm.js.map +0 -1
- package/dist/components/StackOverflow/hooks/useStackOverflowData.esm.js +0 -128
- package/dist/components/StackOverflow/hooks/useStackOverflowData.esm.js.map +0 -1
- package/dist/components/StackOverflow/hooks/useStackOverflowSearch.esm.js +0 -53
- package/dist/components/StackOverflow/hooks/useStackOverflowSearch.esm.js.map +0 -1
- package/dist/components/StackOverflow/hooks/useStackOverflowStyles.esm.js +0 -39
- package/dist/components/StackOverflow/hooks/useStackOverflowStyles.esm.js.map +0 -1
- package/dist/components/StackOverflowAuth/StackAuthCallback.esm.js +0 -47
- package/dist/components/StackOverflowAuth/StackAuthCallback.esm.js.map +0 -1
- package/dist/components/StackOverflowAuth/StackAuthFailed.esm.js +0 -35
- package/dist/components/StackOverflowAuth/StackAuthFailed.esm.js.map +0 -1
- package/dist/components/StackOverflowAuth/StackAuthLoading.esm.js +0 -20
- package/dist/components/StackOverflowAuth/StackAuthLoading.esm.js.map +0 -1
- package/dist/components/StackOverflowAuth/StackAuthStart.esm.js +0 -225
- package/dist/components/StackOverflowAuth/StackAuthStart.esm.js.map +0 -1
- package/dist/components/StackOverflowAuth/StackAuthSuccess.esm.js +0 -37
- package/dist/components/StackOverflowAuth/StackAuthSuccess.esm.js.map +0 -1
- package/dist/icons/LogoutIcon.esm.js +0 -24
- package/dist/icons/LogoutIcon.esm.js.map +0 -1
- package/dist/icons/StackOverflowIcon.esm.js +0 -25
- package/dist/icons/StackOverflowIcon.esm.js.map +0 -1
- package/dist/index.d.ts +0 -48
- package/dist/index.esm.js +0 -18
- package/dist/index.esm.js.map +0 -1
- package/dist/package.json.esm.js +0 -98
- package/dist/package.json.esm.js.map +0 -1
- package/dist/pages/StackOverflowHub.esm.js +0 -82
- package/dist/pages/StackOverflowHub.esm.js.map +0 -1
- package/dist/pages/StackOverflowTeamsPage.esm.js +0 -42
- package/dist/pages/StackOverflowTeamsPage.esm.js.map +0 -1
- package/dist/pages/index.esm.js +0 -3
- package/dist/pages/index.esm.js.map +0 -1
- package/dist/plugin.esm.js +0 -27
- package/dist/plugin.esm.js.map +0 -1
- package/dist/routes.esm.js +0 -8
- package/dist/routes.esm.js.map +0 -1
- package/dist/utils/decodeHtml.esm.js +0 -8
- package/dist/utils/decodeHtml.esm.js.map +0 -1
- package/dist/utils/getTimeAgo.esm.js +0 -30
- package/dist/utils/getTimeAgo.esm.js.map +0 -1
|
@@ -1,308 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { useEditor, EditorContent } from '@tiptap/react';
|
|
3
|
-
import StarterKit from '@tiptap/starter-kit';
|
|
4
|
-
import { Placeholder } from '@tiptap/extensions';
|
|
5
|
-
import Box from '@mui/material/Box';
|
|
6
|
-
import Paper from '@mui/material/Paper';
|
|
7
|
-
import Toolbar from '@mui/material/Toolbar';
|
|
8
|
-
import Divider from '@mui/material/Divider';
|
|
9
|
-
import Typography from '@mui/material/Typography';
|
|
10
|
-
import { useTheme } from '@mui/material/styles';
|
|
11
|
-
import { FormatBold, FormatItalic, FormatUnderlined, Code, FormatListBulleted, FormatListNumbered, FormatQuote, FormatClear } from '@mui/icons-material';
|
|
12
|
-
import Button from '@mui/material/Button';
|
|
13
|
-
|
|
14
|
-
const TiptapEditor = ({
|
|
15
|
-
content = "",
|
|
16
|
-
onUpdate,
|
|
17
|
-
placeholder = "Start typing...",
|
|
18
|
-
editable = true,
|
|
19
|
-
error = false,
|
|
20
|
-
onFocus,
|
|
21
|
-
modifierKey = { symbol: "Ctrl", text: "Ctrl" }
|
|
22
|
-
}) => {
|
|
23
|
-
const theme = useTheme();
|
|
24
|
-
const editor = useEditor({
|
|
25
|
-
extensions: [
|
|
26
|
-
StarterKit,
|
|
27
|
-
Placeholder.configure({
|
|
28
|
-
placeholder,
|
|
29
|
-
emptyEditorClass: "is-editor-empty"
|
|
30
|
-
})
|
|
31
|
-
],
|
|
32
|
-
shouldRerenderOnTransaction: true,
|
|
33
|
-
content,
|
|
34
|
-
editable,
|
|
35
|
-
onUpdate: ({ editor: tiptapEditor }) => {
|
|
36
|
-
if (onUpdate) {
|
|
37
|
-
onUpdate(tiptapEditor.getHTML());
|
|
38
|
-
}
|
|
39
|
-
},
|
|
40
|
-
onFocus: () => {
|
|
41
|
-
if (onFocus) {
|
|
42
|
-
onFocus();
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
});
|
|
46
|
-
if (!editor) {
|
|
47
|
-
return null;
|
|
48
|
-
}
|
|
49
|
-
const ToolbarButton = ({
|
|
50
|
-
onClick,
|
|
51
|
-
isActive,
|
|
52
|
-
disabled,
|
|
53
|
-
children,
|
|
54
|
-
title
|
|
55
|
-
}) => /* @__PURE__ */ React.createElement(
|
|
56
|
-
Button,
|
|
57
|
-
{
|
|
58
|
-
onMouseDown: (e) => {
|
|
59
|
-
e.preventDefault();
|
|
60
|
-
},
|
|
61
|
-
onClick,
|
|
62
|
-
disabled,
|
|
63
|
-
variant: isActive ? "contained" : "text",
|
|
64
|
-
title,
|
|
65
|
-
size: "small"
|
|
66
|
-
},
|
|
67
|
-
children
|
|
68
|
-
);
|
|
69
|
-
return /* @__PURE__ */ React.createElement(
|
|
70
|
-
Paper,
|
|
71
|
-
{
|
|
72
|
-
variant: "outlined",
|
|
73
|
-
sx: {
|
|
74
|
-
border: error ? `2px solid ${theme.palette.error.main}` : `1px solid ${theme.palette.divider}`,
|
|
75
|
-
borderRadius: 2,
|
|
76
|
-
overflow: "hidden",
|
|
77
|
-
"&:focus-within": {
|
|
78
|
-
borderColor: theme.palette.primary.main,
|
|
79
|
-
borderWidth: "2px"
|
|
80
|
-
},
|
|
81
|
-
transition: "border-color 0.2s ease-in-out"
|
|
82
|
-
}
|
|
83
|
-
},
|
|
84
|
-
/* @__PURE__ */ React.createElement(
|
|
85
|
-
Toolbar,
|
|
86
|
-
{
|
|
87
|
-
sx: {
|
|
88
|
-
backgroundColor: theme.palette.background.default,
|
|
89
|
-
borderBottom: `1px solid ${theme.palette.divider}`,
|
|
90
|
-
minHeight: 48,
|
|
91
|
-
flexWrap: "wrap",
|
|
92
|
-
py: 0.5,
|
|
93
|
-
px: 1,
|
|
94
|
-
alignItems: "center"
|
|
95
|
-
}
|
|
96
|
-
},
|
|
97
|
-
/* @__PURE__ */ React.createElement(
|
|
98
|
-
ToolbarButton,
|
|
99
|
-
{
|
|
100
|
-
onClick: () => editor.chain().focus().toggleBold().run(),
|
|
101
|
-
isActive: editor.isActive("bold"),
|
|
102
|
-
title: `Bold (${modifierKey.text}+B)`
|
|
103
|
-
},
|
|
104
|
-
/* @__PURE__ */ React.createElement(FormatBold, { fontSize: "medium" })
|
|
105
|
-
),
|
|
106
|
-
/* @__PURE__ */ React.createElement(
|
|
107
|
-
ToolbarButton,
|
|
108
|
-
{
|
|
109
|
-
onClick: () => editor.chain().focus().toggleItalic().run(),
|
|
110
|
-
isActive: editor.isActive("italic"),
|
|
111
|
-
title: `Italic (${modifierKey.text}+I)`
|
|
112
|
-
},
|
|
113
|
-
/* @__PURE__ */ React.createElement(FormatItalic, { fontSize: "medium" })
|
|
114
|
-
),
|
|
115
|
-
/* @__PURE__ */ React.createElement(
|
|
116
|
-
ToolbarButton,
|
|
117
|
-
{
|
|
118
|
-
onClick: () => editor.chain().focus().toggleUnderline().run(),
|
|
119
|
-
isActive: editor.isActive("underline"),
|
|
120
|
-
title: `Underline (${modifierKey.text}+U)`
|
|
121
|
-
},
|
|
122
|
-
/* @__PURE__ */ React.createElement(FormatUnderlined, { fontSize: "medium" })
|
|
123
|
-
),
|
|
124
|
-
/* @__PURE__ */ React.createElement(
|
|
125
|
-
ToolbarButton,
|
|
126
|
-
{
|
|
127
|
-
onClick: () => editor.chain().focus().toggleCode().run(),
|
|
128
|
-
isActive: editor.isActive("code"),
|
|
129
|
-
title: `Inline Code (${modifierKey.text}+E)`
|
|
130
|
-
},
|
|
131
|
-
/* @__PURE__ */ React.createElement(Code, { fontSize: "medium" })
|
|
132
|
-
),
|
|
133
|
-
/* @__PURE__ */ React.createElement(Divider, { orientation: "vertical", flexItem: true, sx: { mx: 0.5, height: 24, alignSelf: "center" } }),
|
|
134
|
-
/* @__PURE__ */ React.createElement(
|
|
135
|
-
ToolbarButton,
|
|
136
|
-
{
|
|
137
|
-
onClick: () => editor.chain().focus().toggleHeading({ level: 1 }).run(),
|
|
138
|
-
isActive: editor.isActive("heading", { level: 1 }),
|
|
139
|
-
title: `Heading 1 (${modifierKey.text}+Alt+1)`
|
|
140
|
-
},
|
|
141
|
-
/* @__PURE__ */ React.createElement(Typography, { component: "span", fontWeight: "bold", fontSize: "11px" }, "H1")
|
|
142
|
-
),
|
|
143
|
-
/* @__PURE__ */ React.createElement(
|
|
144
|
-
ToolbarButton,
|
|
145
|
-
{
|
|
146
|
-
onClick: () => editor.chain().focus().toggleHeading({ level: 2 }).run(),
|
|
147
|
-
isActive: editor.isActive("heading", { level: 2 }),
|
|
148
|
-
title: `Heading 2 (${modifierKey.text}+Alt+2)`
|
|
149
|
-
},
|
|
150
|
-
/* @__PURE__ */ React.createElement(Typography, { component: "span", fontWeight: "bold", fontSize: "11px" }, "H2")
|
|
151
|
-
),
|
|
152
|
-
/* @__PURE__ */ React.createElement(
|
|
153
|
-
ToolbarButton,
|
|
154
|
-
{
|
|
155
|
-
onClick: () => editor.chain().focus().toggleHeading({ level: 3 }).run(),
|
|
156
|
-
isActive: editor.isActive("heading", { level: 3 }),
|
|
157
|
-
title: `Heading 3 (${modifierKey.text}+Alt+3)`
|
|
158
|
-
},
|
|
159
|
-
/* @__PURE__ */ React.createElement(Typography, { component: "span", fontWeight: "bold", fontSize: "11px" }, "H3")
|
|
160
|
-
),
|
|
161
|
-
/* @__PURE__ */ React.createElement(Divider, { orientation: "vertical", flexItem: true, sx: { mx: 0.5, height: 24, alignSelf: "center" } }),
|
|
162
|
-
/* @__PURE__ */ React.createElement(
|
|
163
|
-
ToolbarButton,
|
|
164
|
-
{
|
|
165
|
-
onClick: () => editor.chain().focus().toggleBulletList().run(),
|
|
166
|
-
isActive: editor.isActive("bulletList"),
|
|
167
|
-
title: "Bullet List"
|
|
168
|
-
},
|
|
169
|
-
/* @__PURE__ */ React.createElement(FormatListBulleted, { fontSize: "medium" })
|
|
170
|
-
),
|
|
171
|
-
/* @__PURE__ */ React.createElement(
|
|
172
|
-
ToolbarButton,
|
|
173
|
-
{
|
|
174
|
-
onClick: () => editor.chain().focus().toggleOrderedList().run(),
|
|
175
|
-
isActive: editor.isActive("orderedList"),
|
|
176
|
-
title: "Numbered List"
|
|
177
|
-
},
|
|
178
|
-
/* @__PURE__ */ React.createElement(FormatListNumbered, { fontSize: "medium" })
|
|
179
|
-
),
|
|
180
|
-
/* @__PURE__ */ React.createElement(
|
|
181
|
-
ToolbarButton,
|
|
182
|
-
{
|
|
183
|
-
onClick: () => editor.chain().focus().toggleBlockquote().run(),
|
|
184
|
-
isActive: editor.isActive("blockquote"),
|
|
185
|
-
title: "Quote"
|
|
186
|
-
},
|
|
187
|
-
/* @__PURE__ */ React.createElement(FormatQuote, { fontSize: "medium" })
|
|
188
|
-
),
|
|
189
|
-
/* @__PURE__ */ React.createElement(
|
|
190
|
-
ToolbarButton,
|
|
191
|
-
{
|
|
192
|
-
onClick: () => editor.chain().focus().toggleCodeBlock().run(),
|
|
193
|
-
isActive: editor.isActive("codeBlock"),
|
|
194
|
-
title: "Code Block"
|
|
195
|
-
},
|
|
196
|
-
/* @__PURE__ */ React.createElement(Typography, { variant: "caption", component: "span", fontWeight: "bold", fontSize: "10px" }, "</>")
|
|
197
|
-
),
|
|
198
|
-
/* @__PURE__ */ React.createElement(Divider, { orientation: "vertical", flexItem: true, sx: { mx: 0.5, height: 24, alignSelf: "center" } }),
|
|
199
|
-
/* @__PURE__ */ React.createElement(
|
|
200
|
-
ToolbarButton,
|
|
201
|
-
{
|
|
202
|
-
onClick: () => editor.chain().focus().clearNodes().unsetAllMarks().run(),
|
|
203
|
-
title: "Clear Format"
|
|
204
|
-
},
|
|
205
|
-
/* @__PURE__ */ React.createElement(FormatClear, { fontSize: "medium" })
|
|
206
|
-
),
|
|
207
|
-
/* @__PURE__ */ React.createElement(Box, { sx: { flexGrow: 1 } })
|
|
208
|
-
),
|
|
209
|
-
/* @__PURE__ */ React.createElement(
|
|
210
|
-
Box,
|
|
211
|
-
{
|
|
212
|
-
onClick: () => editor.chain().focus().run(),
|
|
213
|
-
sx: {
|
|
214
|
-
p: 2,
|
|
215
|
-
minHeight: 200,
|
|
216
|
-
cursor: "text",
|
|
217
|
-
backgroundColor: theme.palette.background.paper,
|
|
218
|
-
"& .ProseMirror": {
|
|
219
|
-
outline: "none",
|
|
220
|
-
minHeight: 168,
|
|
221
|
-
fontFamily: theme.typography.body1.fontFamily,
|
|
222
|
-
fontSize: theme.typography.body1.fontSize,
|
|
223
|
-
lineHeight: theme.typography.body1.lineHeight,
|
|
224
|
-
color: theme.palette.text.primary,
|
|
225
|
-
"& p": {
|
|
226
|
-
margin: theme.spacing(0, 0, 1, 0),
|
|
227
|
-
"&:last-child": {
|
|
228
|
-
marginBottom: 0
|
|
229
|
-
}
|
|
230
|
-
},
|
|
231
|
-
"& h1, & h2, & h3, & h4, & h5, & h6": {
|
|
232
|
-
fontWeight: theme.typography.fontWeightBold,
|
|
233
|
-
marginTop: theme.spacing(2),
|
|
234
|
-
marginBottom: theme.spacing(1),
|
|
235
|
-
"&:first-of-type": {
|
|
236
|
-
marginTop: 0
|
|
237
|
-
}
|
|
238
|
-
},
|
|
239
|
-
"& h1": {
|
|
240
|
-
fontSize: theme.typography.h4.fontSize
|
|
241
|
-
},
|
|
242
|
-
"& h2": {
|
|
243
|
-
fontSize: theme.typography.h5.fontSize
|
|
244
|
-
},
|
|
245
|
-
"& h3": {
|
|
246
|
-
fontSize: theme.typography.h6.fontSize
|
|
247
|
-
},
|
|
248
|
-
"& ul, & ol": {
|
|
249
|
-
paddingLeft: theme.spacing(3),
|
|
250
|
-
margin: theme.spacing(1, 0)
|
|
251
|
-
},
|
|
252
|
-
"& li": {
|
|
253
|
-
marginBottom: theme.spacing(0.5)
|
|
254
|
-
},
|
|
255
|
-
"& blockquote": {
|
|
256
|
-
borderLeft: `4px solid ${theme.palette.primary.main}`,
|
|
257
|
-
paddingLeft: theme.spacing(2),
|
|
258
|
-
margin: theme.spacing(2, 0),
|
|
259
|
-
backgroundColor: theme.palette.mode === "dark" ? theme.palette.grey[700] : theme.palette.grey[50],
|
|
260
|
-
borderRadius: theme.spacing(0, 1, 1, 0)
|
|
261
|
-
},
|
|
262
|
-
"& code": {
|
|
263
|
-
backgroundColor: theme.palette.mode === "dark" ? theme.palette.grey[700] : theme.palette.grey[100],
|
|
264
|
-
padding: theme.spacing(0.5, 0.75),
|
|
265
|
-
borderRadius: theme.shape.borderRadius,
|
|
266
|
-
fontFamily: 'Monaco, "Roboto Mono", monospace',
|
|
267
|
-
fontSize: "0.875em",
|
|
268
|
-
color: theme.palette.mode === "dark" ? theme.palette.primary.light : theme.palette.primary.dark
|
|
269
|
-
},
|
|
270
|
-
"& pre": {
|
|
271
|
-
backgroundColor: theme.palette.mode === "dark" ? theme.palette.grey[700] : theme.palette.grey[100],
|
|
272
|
-
padding: theme.spacing(2),
|
|
273
|
-
overflow: "auto",
|
|
274
|
-
margin: theme.spacing(2, 0),
|
|
275
|
-
border: `1px solid ${theme.palette.divider}`,
|
|
276
|
-
"& code": {
|
|
277
|
-
backgroundColor: "transparent",
|
|
278
|
-
padding: 0,
|
|
279
|
-
color: theme.palette.text.primary
|
|
280
|
-
}
|
|
281
|
-
},
|
|
282
|
-
"& strong": {
|
|
283
|
-
fontWeight: theme.typography.fontWeightBold
|
|
284
|
-
},
|
|
285
|
-
"& em": {
|
|
286
|
-
fontStyle: "italic"
|
|
287
|
-
},
|
|
288
|
-
"& u": {
|
|
289
|
-
textDecoration: "underline"
|
|
290
|
-
},
|
|
291
|
-
"& p.is-editor-empty:first-of-type::before": {
|
|
292
|
-
content: "attr(data-placeholder)",
|
|
293
|
-
float: "left",
|
|
294
|
-
color: theme.palette.text.disabled,
|
|
295
|
-
pointerEvents: "none",
|
|
296
|
-
height: 0,
|
|
297
|
-
fontStyle: "italic"
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
},
|
|
302
|
-
/* @__PURE__ */ React.createElement(EditorContent, { editor })
|
|
303
|
-
)
|
|
304
|
-
);
|
|
305
|
-
};
|
|
306
|
-
|
|
307
|
-
export { TiptapEditor };
|
|
308
|
-
//# sourceMappingURL=TiptapEditor.esm.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"TiptapEditor.esm.js","sources":["../../../src/components/StackOverflow/TiptapEditor.tsx"],"sourcesContent":["import React from 'react';\nimport { useEditor, EditorContent } from '@tiptap/react';\nimport StarterKit from '@tiptap/starter-kit';\nimport { Placeholder } from '@tiptap/extensions';\nimport Box from '@mui/material/Box';\nimport Paper from '@mui/material/Paper';\nimport Toolbar from '@mui/material/Toolbar';\nimport Divider from '@mui/material/Divider';\nimport Typography from '@mui/material/Typography';\nimport { useTheme } from '@mui/material/styles';\nimport {\n FormatBold,\n FormatItalic,\n FormatUnderlined,\n FormatListBulleted,\n FormatListNumbered,\n FormatQuote,\n Code,\n FormatClear,\n // Undo,\n // Redo\n} from '@mui/icons-material';\nimport Button from '@mui/material/Button';\n\ninterface TiptapEditorProps {\n content?: string;\n onUpdate?: (content: string) => void;\n placeholder?: string;\n editable?: boolean;\n error?: boolean;\n onFocus?: () => void;\n modifierKey?: {\n symbol: string,\n text: string\n }\n}\n\nexport const TiptapEditor: React.FC<TiptapEditorProps> = ({\n content = '',\n onUpdate,\n placeholder = 'Start typing...',\n editable = true,\n error = false,\n onFocus,\n modifierKey = { symbol: 'Ctrl', text: 'Ctrl' }\n}) => {\n const theme = useTheme();\n \n const editor = useEditor({\n extensions: [\n StarterKit,\n Placeholder.configure({\n placeholder,\n emptyEditorClass: 'is-editor-empty',\n }),\n ],\n shouldRerenderOnTransaction: true,\n content,\n editable,\n onUpdate: ({ editor: tiptapEditor }) => {\n if (onUpdate) {\n onUpdate(tiptapEditor.getHTML());\n }\n },\n onFocus: () => {\n if (onFocus) {\n onFocus();\n }\n },\n });\n\n if (!editor) {\n return null;\n }\n\n const ToolbarButton = ({ \n onClick, \n isActive, \n disabled, \n children, \n title \n }: {\n onClick: () => void;\n isActive?: boolean;\n disabled?: boolean;\n children: React.ReactNode;\n title: string;\n }) => (\n <Button\n onMouseDown={(e) => {\n e.preventDefault()\n }}\n onClick={onClick}\n disabled={disabled}\n variant={isActive ? 'contained' : 'text'}\n title={title}\n size=\"small\"\n >\n {children}\n </Button>\n );\n\n return (\n <Paper \n variant=\"outlined\"\n sx={{\n border: error ? `2px solid ${theme.palette.error.main}` : `1px solid ${theme.palette.divider}`,\n borderRadius: 2,\n overflow: 'hidden',\n '&:focus-within': {\n borderColor: theme.palette.primary.main,\n borderWidth: '2px',\n },\n transition: 'border-color 0.2s ease-in-out',\n }}\n >\n <Toolbar \n sx={{ \n backgroundColor: theme.palette.background.default,\n borderBottom: `1px solid ${theme.palette.divider}`,\n minHeight: 48,\n flexWrap: 'wrap',\n py: 0.5,\n px: 1,\n alignItems: 'center',\n }}\n >\n {/* Text Formatting Group */}\n <ToolbarButton\n onClick={() => editor.chain().focus().toggleBold().run()}\n isActive={editor.isActive('bold')}\n title={`Bold (${modifierKey.text}+B)`}\n >\n <FormatBold fontSize=\"medium\" />\n </ToolbarButton>\n \n <ToolbarButton\n onClick={() => editor.chain().focus().toggleItalic().run()}\n isActive={editor.isActive('italic')}\n title={`Italic (${modifierKey.text}+I)`}\n >\n <FormatItalic fontSize=\"medium\" />\n </ToolbarButton>\n \n <ToolbarButton\n onClick={() => editor.chain().focus().toggleUnderline().run()}\n isActive={editor.isActive('underline')}\n title={`Underline (${modifierKey.text}+U)`}\n >\n <FormatUnderlined fontSize=\"medium\" />\n </ToolbarButton>\n \n <ToolbarButton\n onClick={() => editor.chain().focus().toggleCode().run()}\n isActive={editor.isActive('code')}\n title={`Inline Code (${modifierKey.text}+E)`}\n >\n <Code fontSize=\"medium\" />\n </ToolbarButton>\n\n <Divider orientation=\"vertical\" flexItem sx={{ mx: 0.5, height: 24, alignSelf: 'center' }} />\n\n {/* Headings Group */}\n <ToolbarButton\n onClick={() => editor.chain().focus().toggleHeading({ level: 1 }).run()}\n isActive={editor.isActive('heading', { level: 1 })}\n title={`Heading 1 (${modifierKey.text}+Alt+1)`}\n >\n <Typography component=\"span\" fontWeight=\"bold\" fontSize=\"11px\">\n H1\n </Typography>\n </ToolbarButton>\n \n <ToolbarButton\n onClick={() => editor.chain().focus().toggleHeading({ level: 2 }).run()}\n isActive={editor.isActive('heading', { level: 2 })}\n title={`Heading 2 (${modifierKey.text}+Alt+2)`}\n >\n <Typography component=\"span\" fontWeight=\"bold\" fontSize=\"11px\">\n H2\n </Typography>\n </ToolbarButton>\n \n <ToolbarButton\n onClick={() => editor.chain().focus().toggleHeading({ level: 3 }).run()}\n isActive={editor.isActive('heading', { level: 3 })}\n title={`Heading 3 (${modifierKey.text}+Alt+3)`}\n >\n <Typography component=\"span\" fontWeight=\"bold\" fontSize=\"11px\">\n H3\n </Typography>\n </ToolbarButton>\n\n <Divider orientation=\"vertical\" flexItem sx={{ mx: 0.5, height: 24, alignSelf: 'center' }} />\n\n {/* Lists and Blocks Group */}\n <ToolbarButton\n onClick={() => editor.chain().focus().toggleBulletList().run()}\n isActive={editor.isActive('bulletList')}\n title=\"Bullet List\"\n >\n <FormatListBulleted fontSize=\"medium\" />\n </ToolbarButton>\n \n <ToolbarButton\n onClick={() => editor.chain().focus().toggleOrderedList().run()}\n isActive={editor.isActive('orderedList')}\n title=\"Numbered List\"\n >\n <FormatListNumbered fontSize=\"medium\" />\n </ToolbarButton>\n \n <ToolbarButton\n onClick={() => editor.chain().focus().toggleBlockquote().run()}\n isActive={editor.isActive('blockquote')}\n title=\"Quote\"\n >\n <FormatQuote fontSize=\"medium\" />\n </ToolbarButton>\n \n <ToolbarButton\n onClick={() => editor.chain().focus().toggleCodeBlock().run()}\n isActive={editor.isActive('codeBlock')}\n title=\"Code Block\"\n >\n <Typography variant=\"caption\" component=\"span\" fontWeight=\"bold\" fontSize=\"10px\">\n {'</>'}\n </Typography>\n </ToolbarButton>\n\n <Divider orientation=\"vertical\" flexItem sx={{ mx: 0.5, height: 24, alignSelf: 'center' }} />\n\n {/* Utility Group */}\n <ToolbarButton\n onClick={() => editor.chain().focus().clearNodes().unsetAllMarks().run()}\n title=\"Clear Format\"\n >\n <FormatClear fontSize=\"medium\" />\n </ToolbarButton>\n\n <Box sx={{ flexGrow: 1 }} />\n\n {/* History Group */}\n {/* <ToolbarButton\n onClick={() => editor.chain().focus().undo().run()}\n disabled={!editor.can().undo()}\n title={`Undo (${modifierKey.text}+Z)`}\n >\n <Undo fontSize=\"medium\" />\n </ToolbarButton>\n \n <ToolbarButton\n onClick={() => editor.chain().focus().redo().run()}\n disabled={!editor.can().redo()}\n title={`Redo (${modifierKey.text}+Y)`}\n >\n <Redo fontSize=\"medium\" />\n </ToolbarButton> */}\n </Toolbar>\n \n <Box \n onClick={() => editor.chain().focus().run()}\n sx={{\n p: 2,\n minHeight: 200,\n cursor: 'text',\n backgroundColor: theme.palette.background.paper,\n '& .ProseMirror': {\n outline: 'none',\n minHeight: 168,\n fontFamily: theme.typography.body1.fontFamily,\n fontSize: theme.typography.body1.fontSize,\n lineHeight: theme.typography.body1.lineHeight,\n color: theme.palette.text.primary,\n '& p': {\n margin: theme.spacing(0, 0, 1, 0),\n '&:last-child': {\n marginBottom: 0,\n },\n },\n '& h1, & h2, & h3, & h4, & h5, & h6': {\n fontWeight: theme.typography.fontWeightBold,\n marginTop: theme.spacing(2),\n marginBottom: theme.spacing(1),\n '&:first-of-type': {\n marginTop: 0,\n },\n },\n '& h1': {\n fontSize: theme.typography.h4.fontSize,\n },\n '& h2': {\n fontSize: theme.typography.h5.fontSize,\n },\n '& h3': {\n fontSize: theme.typography.h6.fontSize,\n },\n '& ul, & ol': {\n paddingLeft: theme.spacing(3),\n margin: theme.spacing(1, 0),\n },\n '& li': {\n marginBottom: theme.spacing(0.5),\n },\n '& blockquote': {\n borderLeft: `4px solid ${theme.palette.primary.main}`,\n paddingLeft: theme.spacing(2),\n margin: theme.spacing(2, 0),\n backgroundColor: theme.palette.mode === 'dark' \n ? theme.palette.grey[700] \n : theme.palette.grey[50],\n borderRadius: theme.spacing(0, 1, 1, 0),\n },\n '& code': {\n backgroundColor: theme.palette.mode === 'dark' \n ? theme.palette.grey[700] \n : theme.palette.grey[100],\n padding: theme.spacing(0.5, 0.75),\n borderRadius: theme.shape.borderRadius,\n fontFamily: 'Monaco, \"Roboto Mono\", monospace',\n fontSize: '0.875em',\n color: theme.palette.mode === 'dark'\n ? theme.palette.primary.light\n : theme.palette.primary.dark,\n },\n '& pre': {\n backgroundColor: theme.palette.mode === 'dark' \n ? theme.palette.grey[700] \n : theme.palette.grey[100],\n padding: theme.spacing(2),\n overflow: 'auto',\n margin: theme.spacing(2, 0),\n border: `1px solid ${theme.palette.divider}`,\n '& code': {\n backgroundColor: 'transparent',\n padding: 0,\n color: theme.palette.text.primary,\n },\n },\n '& strong': {\n fontWeight: theme.typography.fontWeightBold,\n },\n '& em': {\n fontStyle: 'italic',\n },\n '& u': {\n textDecoration: 'underline',\n },\n '& p.is-editor-empty:first-of-type::before': {\n content: 'attr(data-placeholder)',\n float: 'left',\n color: theme.palette.text.disabled,\n pointerEvents: 'none',\n height: 0,\n fontStyle: 'italic',\n },\n },\n }}\n >\n <EditorContent editor={editor} />\n </Box>\n </Paper>\n );\n};"],"names":[],"mappings":"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"}
|
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
import { useState, useCallback } from 'react';
|
|
2
|
-
import { useApi } from '@backstage/core-plugin-api';
|
|
3
|
-
import { stackoverflowteamsApiRef } from '../../../api/StackOverflowAPI.esm.js';
|
|
4
|
-
|
|
5
|
-
const useStackOverflowData = (type, options) => {
|
|
6
|
-
const stackOverflowTeamsApi = useApi(stackoverflowteamsApiRef);
|
|
7
|
-
const [data, setData] = useState(null);
|
|
8
|
-
const [loading, setLoading] = useState(true);
|
|
9
|
-
const [error, setError] = useState(null);
|
|
10
|
-
const fetchData = useCallback(async () => {
|
|
11
|
-
setLoading(true);
|
|
12
|
-
setError(null);
|
|
13
|
-
try {
|
|
14
|
-
let response;
|
|
15
|
-
switch (type) {
|
|
16
|
-
case "questions":
|
|
17
|
-
response = await stackOverflowTeamsApi.getQuestions(options?.questionFilters);
|
|
18
|
-
setData({
|
|
19
|
-
questions: response.items,
|
|
20
|
-
totalPages: response.totalPages,
|
|
21
|
-
totalCount: response.totalCount,
|
|
22
|
-
currentPage: response.page
|
|
23
|
-
});
|
|
24
|
-
break;
|
|
25
|
-
case "tags":
|
|
26
|
-
response = await stackOverflowTeamsApi.getTags(options?.tagSearch);
|
|
27
|
-
setData({ tags: response.items });
|
|
28
|
-
break;
|
|
29
|
-
case "users":
|
|
30
|
-
response = await stackOverflowTeamsApi.getUsers();
|
|
31
|
-
setData({ users: response.items });
|
|
32
|
-
break;
|
|
33
|
-
default:
|
|
34
|
-
throw new Error(`Invalid data type: ${type}`);
|
|
35
|
-
}
|
|
36
|
-
} catch (e) {
|
|
37
|
-
setError(e instanceof Error ? e : new Error(String(e)));
|
|
38
|
-
} finally {
|
|
39
|
-
setLoading(false);
|
|
40
|
-
}
|
|
41
|
-
}, [type, stackOverflowTeamsApi, options?.questionFilters, options?.tagSearch]);
|
|
42
|
-
const fetchActiveQuestions = useCallback(async (page) => {
|
|
43
|
-
if (type !== "questions") return;
|
|
44
|
-
setLoading(true);
|
|
45
|
-
setError(null);
|
|
46
|
-
try {
|
|
47
|
-
const response = await stackOverflowTeamsApi.getActiveQuestions(page);
|
|
48
|
-
setData({
|
|
49
|
-
questions: response.items,
|
|
50
|
-
totalPages: response.totalPages,
|
|
51
|
-
totalCount: response.totalCount,
|
|
52
|
-
currentPage: response.page
|
|
53
|
-
});
|
|
54
|
-
} catch (e) {
|
|
55
|
-
setError(e instanceof Error ? e : new Error(String(e)));
|
|
56
|
-
} finally {
|
|
57
|
-
setLoading(false);
|
|
58
|
-
}
|
|
59
|
-
}, [type, stackOverflowTeamsApi]);
|
|
60
|
-
const fetchNewestQuestions = useCallback(async (page) => {
|
|
61
|
-
if (type !== "questions") return;
|
|
62
|
-
setLoading(true);
|
|
63
|
-
setError(null);
|
|
64
|
-
try {
|
|
65
|
-
const response = await stackOverflowTeamsApi.getNewestQuestions(page);
|
|
66
|
-
setData({
|
|
67
|
-
questions: response.items,
|
|
68
|
-
totalPages: response.totalPages,
|
|
69
|
-
totalCount: response.totalCount,
|
|
70
|
-
currentPage: response.page
|
|
71
|
-
});
|
|
72
|
-
} catch (e) {
|
|
73
|
-
setError(e instanceof Error ? e : new Error(String(e)));
|
|
74
|
-
} finally {
|
|
75
|
-
setLoading(false);
|
|
76
|
-
}
|
|
77
|
-
}, [type, stackOverflowTeamsApi]);
|
|
78
|
-
const fetchTopScoredQuestions = useCallback(async (page) => {
|
|
79
|
-
if (type !== "questions") return;
|
|
80
|
-
setLoading(true);
|
|
81
|
-
setError(null);
|
|
82
|
-
try {
|
|
83
|
-
const response = await stackOverflowTeamsApi.getTopScoredQuestions(page);
|
|
84
|
-
setData({
|
|
85
|
-
questions: response.items,
|
|
86
|
-
totalPages: response.totalPages,
|
|
87
|
-
totalCount: response.totalCount,
|
|
88
|
-
currentPage: response.page
|
|
89
|
-
});
|
|
90
|
-
} catch (e) {
|
|
91
|
-
setError(e instanceof Error ? e : new Error(String(e)));
|
|
92
|
-
} finally {
|
|
93
|
-
setLoading(false);
|
|
94
|
-
}
|
|
95
|
-
}, [type, stackOverflowTeamsApi]);
|
|
96
|
-
const fetchUnansweredQuestions = useCallback(async (page) => {
|
|
97
|
-
if (type !== "questions") return;
|
|
98
|
-
setLoading(true);
|
|
99
|
-
setError(null);
|
|
100
|
-
try {
|
|
101
|
-
const response = await stackOverflowTeamsApi.getUnansweredQuestions(page);
|
|
102
|
-
setData({
|
|
103
|
-
questions: response.items,
|
|
104
|
-
totalPages: response.totalPages,
|
|
105
|
-
totalCount: response.totalCount,
|
|
106
|
-
currentPage: response.page
|
|
107
|
-
});
|
|
108
|
-
} catch (e) {
|
|
109
|
-
setError(e instanceof Error ? e : new Error(String(e)));
|
|
110
|
-
} finally {
|
|
111
|
-
setLoading(false);
|
|
112
|
-
}
|
|
113
|
-
}, [type, stackOverflowTeamsApi]);
|
|
114
|
-
return {
|
|
115
|
-
data,
|
|
116
|
-
loading,
|
|
117
|
-
error,
|
|
118
|
-
fetchData,
|
|
119
|
-
// Convenience methods for questions
|
|
120
|
-
fetchActiveQuestions,
|
|
121
|
-
fetchNewestQuestions,
|
|
122
|
-
fetchTopScoredQuestions,
|
|
123
|
-
fetchUnansweredQuestions
|
|
124
|
-
};
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
export { useStackOverflowData };
|
|
128
|
-
//# sourceMappingURL=useStackOverflowData.esm.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useStackOverflowData.esm.js","sources":["../../../../src/components/StackOverflow/hooks/useStackOverflowData.ts"],"sourcesContent":["import { useState, useCallback } from 'react';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { Question, stackoverflowteamsApiRef, Tag, User } from '../../../api/';\n\ntype PostType = 'questions' | 'tags' | 'users' \n\ninterface QuestionFilters {\n sort?: 'activity' | 'creation' | 'score';\n order?: 'asc' | 'desc';\n isAnswered?: boolean;\n page?: number;\n pageSize?: number;\n}\n\ninterface StackOverflowData {\n questions?: Question[];\n tags?: Tag[];\n users?: User[];\n totalPages?: number;\n totalCount?: number;\n currentPage?: number;\n}\n\ninterface UseStackOverflowDataOptions {\n questionFilters?: QuestionFilters;\n tagSearch?: string;\n}\n\nexport const useStackOverflowData = (type: PostType, options?: UseStackOverflowDataOptions) => {\n const stackOverflowTeamsApi = useApi(stackoverflowteamsApiRef);\n const [data, setData] = useState<StackOverflowData | null>(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n const fetchData = useCallback(async () => {\n setLoading(true);\n setError(null);\n \n try {\n let response;\n switch (type) {\n case 'questions':\n response = await stackOverflowTeamsApi.getQuestions(options?.questionFilters);\n setData({ \n questions: response.items,\n totalPages: response.totalPages,\n totalCount: response.totalCount,\n currentPage: response.page\n });\n break;\n case 'tags':\n response = await stackOverflowTeamsApi.getTags(options?.tagSearch);\n setData({ tags: response.items });\n break;\n case 'users':\n response = await stackOverflowTeamsApi.getUsers();\n setData({ users: response.items });\n break;\n default:\n throw new Error(`Invalid data type: ${type}`);\n }\n } catch (e) {\n setError(e instanceof Error ? e : new Error(String(e)));\n } finally {\n setLoading(false);\n }\n }, [type, stackOverflowTeamsApi, options?.questionFilters, options?.tagSearch]);\n\n // Convenience methods for questions\n const fetchActiveQuestions = useCallback(async (page?: number) => {\n if (type !== 'questions') return;\n setLoading(true);\n setError(null);\n \n try {\n const response = await stackOverflowTeamsApi.getActiveQuestions(page);\n setData({ \n questions: response.items,\n totalPages: response.totalPages,\n totalCount: response.totalCount,\n currentPage: response.page\n });\n } catch (e) {\n setError(e instanceof Error ? e : new Error(String(e)));\n } finally {\n setLoading(false);\n }\n }, [type, stackOverflowTeamsApi]);\n\n const fetchNewestQuestions = useCallback(async (page?: number) => {\n if (type !== 'questions') return;\n setLoading(true);\n setError(null);\n \n try {\n const response = await stackOverflowTeamsApi.getNewestQuestions(page);\n setData({ \n questions: response.items,\n totalPages: response.totalPages,\n totalCount: response.totalCount,\n currentPage: response.page\n });\n } catch (e) {\n setError(e instanceof Error ? e : new Error(String(e)));\n } finally {\n setLoading(false);\n }\n }, [type, stackOverflowTeamsApi]);\n\n const fetchTopScoredQuestions = useCallback(async (page?: number) => {\n if (type !== 'questions') return;\n setLoading(true);\n setError(null);\n \n try {\n const response = await stackOverflowTeamsApi.getTopScoredQuestions(page);\n setData({ \n questions: response.items,\n totalPages: response.totalPages,\n totalCount: response.totalCount,\n currentPage: response.page\n });\n } catch (e) {\n setError(e instanceof Error ? e : new Error(String(e)));\n } finally {\n setLoading(false);\n }\n }, [type, stackOverflowTeamsApi]);\n\n const fetchUnansweredQuestions = useCallback(async (page?: number) => {\n if (type !== 'questions') return;\n setLoading(true);\n setError(null);\n \n try {\n const response = await stackOverflowTeamsApi.getUnansweredQuestions(page);\n setData({ \n questions: response.items,\n totalPages: response.totalPages,\n totalCount: response.totalCount,\n currentPage: response.page\n });\n } catch (e) {\n setError(e instanceof Error ? e : new Error(String(e)));\n } finally {\n setLoading(false);\n }\n }, [type, stackOverflowTeamsApi]);\n\n return { \n data, \n loading, \n error, \n fetchData,\n // Convenience methods for questions\n fetchActiveQuestions,\n fetchNewestQuestions, \n fetchTopScoredQuestions,\n fetchUnansweredQuestions\n };\n};"],"names":[],"mappings":"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"}
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import { useApi } from '@backstage/core-plugin-api';
|
|
2
|
-
import { stackoverflowteamsApiRef } from '../../../api/StackOverflowAPI.esm.js';
|
|
3
|
-
import { useState, useCallback } from 'react';
|
|
4
|
-
|
|
5
|
-
const useStackOverflowSearch = () => {
|
|
6
|
-
const stackOverflowTeamsApi = useApi(stackoverflowteamsApiRef);
|
|
7
|
-
const [searchData, setSearchData] = useState(null);
|
|
8
|
-
const [loading, setLoading] = useState(false);
|
|
9
|
-
const [error, setError] = useState(null);
|
|
10
|
-
const search = useCallback(async (query, page) => {
|
|
11
|
-
if (!query.trim()) {
|
|
12
|
-
setSearchData(null);
|
|
13
|
-
setError(null);
|
|
14
|
-
return;
|
|
15
|
-
}
|
|
16
|
-
setLoading(true);
|
|
17
|
-
setError(null);
|
|
18
|
-
try {
|
|
19
|
-
const response = await stackOverflowTeamsApi.search(query, page);
|
|
20
|
-
setSearchData({
|
|
21
|
-
items: response.items,
|
|
22
|
-
totalCount: response.totalCount,
|
|
23
|
-
totalPages: response.totalPages,
|
|
24
|
-
page: response.page,
|
|
25
|
-
pageSize: response.pageSize
|
|
26
|
-
});
|
|
27
|
-
} catch (e) {
|
|
28
|
-
setError(e instanceof Error ? e : new Error(String(e)));
|
|
29
|
-
setSearchData(null);
|
|
30
|
-
} finally {
|
|
31
|
-
setLoading(false);
|
|
32
|
-
}
|
|
33
|
-
}, [stackOverflowTeamsApi]);
|
|
34
|
-
const clearSearch = useCallback(() => {
|
|
35
|
-
setSearchData(null);
|
|
36
|
-
setError(null);
|
|
37
|
-
}, []);
|
|
38
|
-
return {
|
|
39
|
-
searchData,
|
|
40
|
-
loading,
|
|
41
|
-
error,
|
|
42
|
-
search,
|
|
43
|
-
clearSearch,
|
|
44
|
-
// Convenience getters
|
|
45
|
-
hasResults: !!searchData?.items.length,
|
|
46
|
-
totalPages: searchData?.totalPages || 0,
|
|
47
|
-
currentPage: searchData?.page || 1,
|
|
48
|
-
totalCount: searchData?.totalCount
|
|
49
|
-
};
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
export { useStackOverflowSearch };
|
|
53
|
-
//# sourceMappingURL=useStackOverflowSearch.esm.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useStackOverflowSearch.esm.js","sources":["../../../../src/components/StackOverflow/hooks/useStackOverflowSearch.ts"],"sourcesContent":["import { useApi } from \"@backstage/core-plugin-api\";\nimport { stackoverflowteamsApiRef } from \"../../../api/StackOverflowAPI\";\nimport { useCallback, useState } from \"react\";\nimport { PaginatedResponse } from \"../../../types\";\n\ninterface SearchData {\n items: any[];\n totalCount: number;\n totalPages: number;\n page: number;\n pageSize: number;\n}\n\nexport const useStackOverflowSearch = () => {\n const stackOverflowTeamsApi = useApi(stackoverflowteamsApiRef);\n const [searchData, setSearchData] = useState<SearchData | null>(null);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const search = useCallback(async (query: string, page?: number) => {\n if (!query.trim()) {\n setSearchData(null);\n setError(null);\n return;\n }\n\n setLoading(true);\n setError(null);\n\n try {\n const response: PaginatedResponse<any> = await stackOverflowTeamsApi.search(query, page);\n setSearchData({\n items: response.items,\n totalCount: response.totalCount,\n totalPages: response.totalPages,\n page: response.page,\n pageSize: response.pageSize,\n });\n } catch (e) {\n setError(e instanceof Error ? e : new Error(String(e)));\n setSearchData(null);\n } finally {\n setLoading(false);\n }\n }, [stackOverflowTeamsApi]);\n\n const clearSearch = useCallback(() => {\n setSearchData(null);\n setError(null);\n }, []);\n\n return { \n searchData, \n loading, \n error, \n search, \n clearSearch,\n // Convenience getters\n hasResults: !!searchData?.items.length,\n totalPages: searchData?.totalPages || 0,\n currentPage: searchData?.page || 1,\n totalCount: searchData?.totalCount,\n };\n};"],"names":[],"mappings":";;;;AAaO,MAAM,yBAAyB,MAAM;AAC1C,EAAM,MAAA,qBAAA,GAAwB,OAAO,wBAAwB,CAAA;AAC7D,EAAA,MAAM,CAAC,UAAA,EAAY,aAAa,CAAA,GAAI,SAA4B,IAAI,CAAA;AACpE,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,SAAS,KAAK,CAAA;AAC5C,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,SAAuB,IAAI,CAAA;AAErD,EAAA,MAAM,MAAS,GAAA,WAAA,CAAY,OAAO,KAAA,EAAe,IAAkB,KAAA;AACjE,IAAI,IAAA,CAAC,KAAM,CAAA,IAAA,EAAQ,EAAA;AACjB,MAAA,aAAA,CAAc,IAAI,CAAA;AAClB,MAAA,QAAA,CAAS,IAAI,CAAA;AACb,MAAA;AAAA;AAGF,IAAA,UAAA,CAAW,IAAI,CAAA;AACf,IAAA,QAAA,CAAS,IAAI,CAAA;AAEb,IAAI,IAAA;AACF,MAAA,MAAM,QAAmC,GAAA,MAAM,qBAAsB,CAAA,MAAA,CAAO,OAAO,IAAI,CAAA;AACvF,MAAc,aAAA,CAAA;AAAA,QACZ,OAAO,QAAS,CAAA,KAAA;AAAA,QAChB,YAAY,QAAS,CAAA,UAAA;AAAA,QACrB,YAAY,QAAS,CAAA,UAAA;AAAA,QACrB,MAAM,QAAS,CAAA,IAAA;AAAA,QACf,UAAU,QAAS,CAAA;AAAA,OACpB,CAAA;AAAA,aACM,CAAG,EAAA;AACV,MAAS,QAAA,CAAA,CAAA,YAAa,QAAQ,CAAI,GAAA,IAAI,MAAM,MAAO,CAAA,CAAC,CAAC,CAAC,CAAA;AACtD,MAAA,aAAA,CAAc,IAAI,CAAA;AAAA,KAClB,SAAA;AACA,MAAA,UAAA,CAAW,KAAK,CAAA;AAAA;AAClB,GACF,EAAG,CAAC,qBAAqB,CAAC,CAAA;AAE1B,EAAM,MAAA,WAAA,GAAc,YAAY,MAAM;AACpC,IAAA,aAAA,CAAc,IAAI,CAAA;AAClB,IAAA,QAAA,CAAS,IAAI,CAAA;AAAA,GACf,EAAG,EAAE,CAAA;AAEL,EAAO,OAAA;AAAA,IACL,UAAA;AAAA,IACA,OAAA;AAAA,IACA,KAAA;AAAA,IACA,MAAA;AAAA,IACA,WAAA;AAAA;AAAA,IAEA,UAAY,EAAA,CAAC,CAAC,UAAA,EAAY,KAAM,CAAA,MAAA;AAAA,IAChC,UAAA,EAAY,YAAY,UAAc,IAAA,CAAA;AAAA,IACtC,WAAA,EAAa,YAAY,IAAQ,IAAA,CAAA;AAAA,IACjC,YAAY,UAAY,EAAA;AAAA,GAC1B;AACF;;;;"}
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { makeStyles } from '@material-ui/core/styles';
|
|
2
|
-
|
|
3
|
-
const useStackOverflowStyles = makeStyles((theme) => ({
|
|
4
|
-
title: {
|
|
5
|
-
color: theme.palette.type === "dark" ? "#4CA8FF" : "#0077CC",
|
|
6
|
-
// Brighter blue in dark mode
|
|
7
|
-
fontWeight: "bold"
|
|
8
|
-
},
|
|
9
|
-
unanswered: {
|
|
10
|
-
backgroundColor: theme.palette.type === "dark" ? "#3B2D1F" : "#FFF4E5",
|
|
11
|
-
// Darker orange for dark mode
|
|
12
|
-
borderRadius: "4px",
|
|
13
|
-
padding: "4px 8px"
|
|
14
|
-
},
|
|
15
|
-
answered: {
|
|
16
|
-
backgroundColor: theme.palette.type === "dark" ? "#1E4620" : "#E3FCEF",
|
|
17
|
-
// Darker green for dark mode
|
|
18
|
-
borderRadius: "4px",
|
|
19
|
-
padding: "4px 8px"
|
|
20
|
-
},
|
|
21
|
-
button: {
|
|
22
|
-
backgroundColor: "#F48024",
|
|
23
|
-
// Stack Overflow orange
|
|
24
|
-
color: "#fff",
|
|
25
|
-
"&:hover": {
|
|
26
|
-
backgroundColor: theme.palette.type === "dark" ? "#C15C17" : "#D4691E"
|
|
27
|
-
}
|
|
28
|
-
},
|
|
29
|
-
tableRow: {
|
|
30
|
-
backgroundColor: theme.palette.background.paper,
|
|
31
|
-
"&:hover": {
|
|
32
|
-
backgroundColor: theme.palette.type === "dark" ? theme.palette.action.hover : "#F5F5F5"
|
|
33
|
-
// Light gray hover effect in light mode
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
}));
|
|
37
|
-
|
|
38
|
-
export { useStackOverflowStyles };
|
|
39
|
-
//# sourceMappingURL=useStackOverflowStyles.esm.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useStackOverflowStyles.esm.js","sources":["../../../../src/components/StackOverflow/hooks/useStackOverflowStyles.ts"],"sourcesContent":["import { makeStyles, Theme } from '@material-ui/core/styles';\n\n/**\n * Reusable styles for Stack Overflow-themed components with dark mode support\n */\nexport const useStackOverflowStyles = makeStyles((theme: Theme) => ({\n title: {\n color: theme.palette.type === 'dark' ? '#4CA8FF' : '#0077CC', // Brighter blue in dark mode\n fontWeight: 'bold',\n },\n unanswered: {\n backgroundColor: theme.palette.type === 'dark' ? '#3B2D1F' : '#FFF4E5', // Darker orange for dark mode\n borderRadius: '4px',\n padding: '4px 8px',\n },\n answered: {\n backgroundColor: theme.palette.type === 'dark' ? '#1E4620' : '#E3FCEF', // Darker green for dark mode\n borderRadius: '4px',\n padding: '4px 8px',\n },\n button: {\n backgroundColor: '#F48024', // Stack Overflow orange\n color: '#fff',\n '&:hover': {\n backgroundColor: theme.palette.type === 'dark' ? '#C15C17' : '#D4691E',\n },\n },\n tableRow: {\n backgroundColor: theme.palette.background.paper,\n '&:hover': {\n backgroundColor:\n theme.palette.type === 'dark'\n ? theme.palette.action.hover\n : '#F5F5F5', // Light gray hover effect in light mode\n },\n },\n}));\n"],"names":[],"mappings":";;AAKa,MAAA,sBAAA,GAAyB,UAAW,CAAA,CAAC,KAAkB,MAAA;AAAA,EAClE,KAAO,EAAA;AAAA,IACL,KAAO,EAAA,KAAA,CAAM,OAAQ,CAAA,IAAA,KAAS,SAAS,SAAY,GAAA,SAAA;AAAA;AAAA,IACnD,UAAY,EAAA;AAAA,GACd;AAAA,EACA,UAAY,EAAA;AAAA,IACV,eAAiB,EAAA,KAAA,CAAM,OAAQ,CAAA,IAAA,KAAS,SAAS,SAAY,GAAA,SAAA;AAAA;AAAA,IAC7D,YAAc,EAAA,KAAA;AAAA,IACd,OAAS,EAAA;AAAA,GACX;AAAA,EACA,QAAU,EAAA;AAAA,IACR,eAAiB,EAAA,KAAA,CAAM,OAAQ,CAAA,IAAA,KAAS,SAAS,SAAY,GAAA,SAAA;AAAA;AAAA,IAC7D,YAAc,EAAA,KAAA;AAAA,IACd,OAAS,EAAA;AAAA,GACX;AAAA,EACA,MAAQ,EAAA;AAAA,IACN,eAAiB,EAAA,SAAA;AAAA;AAAA,IACjB,KAAO,EAAA,MAAA;AAAA,IACP,SAAW,EAAA;AAAA,MACT,eAAiB,EAAA,KAAA,CAAM,OAAQ,CAAA,IAAA,KAAS,SAAS,SAAY,GAAA;AAAA;AAC/D,GACF;AAAA,EACA,QAAU,EAAA;AAAA,IACR,eAAA,EAAiB,KAAM,CAAA,OAAA,CAAQ,UAAW,CAAA,KAAA;AAAA,IAC1C,SAAW,EAAA;AAAA,MACT,eAAA,EACE,MAAM,OAAQ,CAAA,IAAA,KAAS,SACnB,KAAM,CAAA,OAAA,CAAQ,OAAO,KACrB,GAAA;AAAA;AAAA;AACR;AAEJ,CAAE,CAAA;;;;"}
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { useApi } from '@backstage/core-plugin-api';
|
|
2
|
-
import { stackoverflowteamsApiRef } from '../../api/StackOverflowAPI.esm.js';
|
|
3
|
-
import React, { useState, useEffect } from 'react';
|
|
4
|
-
import { useLocation } from 'react-router-dom';
|
|
5
|
-
import { StackAuthSuccess } from './StackAuthSuccess.esm.js';
|
|
6
|
-
import { StackAuthLoading } from './StackAuthLoading.esm.js';
|
|
7
|
-
import { StackAuthFailed } from './StackAuthFailed.esm.js';
|
|
8
|
-
|
|
9
|
-
const StackOverflowCallback = () => {
|
|
10
|
-
const stackOverflowTeamsApi = useApi(stackoverflowteamsApiRef);
|
|
11
|
-
const location = useLocation();
|
|
12
|
-
const [status, setStatus] = useState("loading");
|
|
13
|
-
useEffect(() => {
|
|
14
|
-
const handleCallback = async () => {
|
|
15
|
-
const queryParams = new URLSearchParams(location.search);
|
|
16
|
-
const code = queryParams.get("code");
|
|
17
|
-
const state = queryParams.get("state");
|
|
18
|
-
const isLoggedIn = await stackOverflowTeamsApi.getAuthStatus();
|
|
19
|
-
if (isLoggedIn) {
|
|
20
|
-
setStatus("success");
|
|
21
|
-
return;
|
|
22
|
-
}
|
|
23
|
-
if (!code || !state) {
|
|
24
|
-
setStatus("error");
|
|
25
|
-
return;
|
|
26
|
-
}
|
|
27
|
-
try {
|
|
28
|
-
await stackOverflowTeamsApi.completeAuth(code, state);
|
|
29
|
-
setStatus("success");
|
|
30
|
-
window.history.replaceState({}, document.title, location.pathname);
|
|
31
|
-
} catch (error) {
|
|
32
|
-
setStatus("error");
|
|
33
|
-
}
|
|
34
|
-
};
|
|
35
|
-
handleCallback();
|
|
36
|
-
}, [location.pathname, location.search, stackOverflowTeamsApi]);
|
|
37
|
-
if (status === "loading") {
|
|
38
|
-
return /* @__PURE__ */ React.createElement(StackAuthLoading, null);
|
|
39
|
-
}
|
|
40
|
-
if (status === "success") {
|
|
41
|
-
return /* @__PURE__ */ React.createElement(StackAuthSuccess, null);
|
|
42
|
-
}
|
|
43
|
-
return /* @__PURE__ */ React.createElement(StackAuthFailed, null);
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
export { StackOverflowCallback };
|
|
47
|
-
//# sourceMappingURL=StackAuthCallback.esm.js.map
|