@yadsh/dsh-qa-surface 0.6.1 → 0.7.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 +136 -7
- package/capability-policy.json +1 -1
- package/lib/access/capability-catalog.js +144 -0
- package/lib/access/capability-catalog.js.map +1 -0
- package/lib/access/model.js +379 -0
- package/lib/access/model.js.map +1 -0
- package/lib/access/role-repository.js +195 -0
- package/lib/access/role-repository.js.map +1 -0
- package/lib/access/service.js +380 -0
- package/lib/access/service.js.map +1 -0
- package/lib/access/skill-metadata.js +234 -0
- package/lib/access/skill-metadata.js.map +1 -0
- package/lib/account-remotes.js +20 -10
- package/lib/account-remotes.js.map +1 -1
- package/lib/accounts/errors.js.map +1 -1
- package/lib/accounts/file.js.map +1 -1
- package/lib/accounts/store.js +202 -3
- package/lib/accounts/store.js.map +1 -1
- package/lib/admin/conversation-log.js +256 -0
- package/lib/admin/conversation-log.js.map +1 -0
- package/lib/admin/index.js +17 -0
- package/lib/admin/index.js.map +1 -0
- package/lib/admin/metrics.js +103 -0
- package/lib/admin/metrics.js.map +1 -0
- package/lib/admin/paging.js +23 -0
- package/lib/admin/paging.js.map +1 -0
- package/lib/admin/permissions.js +50 -0
- package/lib/admin/permissions.js.map +1 -0
- package/lib/admin/quality-store.js +485 -0
- package/lib/admin/quality-store.js.map +1 -0
- package/lib/admin/queue.js +107 -0
- package/lib/admin/queue.js.map +1 -0
- package/lib/admin/redaction.js +45 -0
- package/lib/admin/redaction.js.map +1 -0
- package/lib/admin/service.js +897 -0
- package/lib/admin/service.js.map +1 -0
- package/lib/admin/session-log.js +142 -0
- package/lib/admin/session-log.js.map +1 -0
- package/lib/cli.js +9 -6
- package/lib/cli.js.map +1 -1
- package/lib/client/QaSessionController.js +28 -2
- package/lib/client/QaSessionController.js.map +1 -1
- package/lib/client/QaSurface.js +143 -5
- package/lib/client/QaSurface.js.map +1 -1
- package/lib/client/QaTranscriptAdapter.js +1 -0
- package/lib/client/QaTranscriptAdapter.js.map +1 -1
- package/lib/client/admin/QaAdmin.js +458 -0
- package/lib/client/admin/QaAdmin.js.map +1 -0
- package/lib/client/admin/format.js +177 -0
- package/lib/client/admin/format.js.map +1 -0
- package/lib/client/admin/pages/Conversations.js +114 -0
- package/lib/client/admin/pages/Conversations.js.map +1 -0
- package/lib/client/admin/pages/Overview.js +24 -0
- package/lib/client/admin/pages/Overview.js.map +1 -0
- package/lib/client/admin/pages/Quality.js +71 -0
- package/lib/client/admin/pages/Quality.js.map +1 -0
- package/lib/client/admin/pages/Review.js +93 -0
- package/lib/client/admin/pages/Review.js.map +1 -0
- package/lib/client/admin/pages/Users.js +95 -0
- package/lib/client/admin/pages/Users.js.map +1 -0
- package/lib/client/admin/routes.js +127 -0
- package/lib/client/admin/routes.js.map +1 -0
- package/lib/client/admin/shared.js +91 -0
- package/lib/client/admin/shared.js.map +1 -0
- package/lib/client/admin/styles.js +111 -0
- package/lib/client/admin/styles.js.map +1 -0
- package/lib/client/components/QaChangelog.js +35 -0
- package/lib/client/components/QaChangelog.js.map +1 -1
- package/lib/client/components/QaHeader.js +3 -3
- package/lib/client/components/QaHeader.js.map +1 -1
- package/lib/client/components/QaMessage.js +61 -2
- package/lib/client/components/QaMessage.js.map +1 -1
- package/lib/client/create-session.js +1 -1
- package/lib/client/create-session.js.map +1 -1
- package/lib/client/index.js +33 -1
- package/lib/client/index.js.map +1 -1
- package/lib/client/role/RoleSelector.js +31 -0
- package/lib/client/role/RoleSelector.js.map +1 -0
- package/lib/client/session-sources.js +37 -1
- package/lib/client/session-sources.js.map +1 -1
- package/lib/client/settings/card.js +2 -2
- package/lib/client/settings/card.js.map +1 -1
- package/lib/client/settings/sections.js +0 -1
- package/lib/client/settings/sections.js.map +1 -1
- package/lib/client/styles.js +31 -0
- package/lib/client/styles.js.map +1 -1
- package/lib/client/types.js.map +1 -1
- package/lib/client.js +9908 -4857
- package/lib/client.js.map +1 -1
- package/lib/config-resolvers/defaults.js +0 -2
- package/lib/config-resolvers/defaults.js.map +1 -1
- package/lib/config.js +0 -249
- package/lib/config.js.map +1 -1
- package/lib/enforcement/skill-policy.js +172 -0
- package/lib/enforcement/skill-policy.js.map +1 -0
- package/lib/enforcement/tool-grants.js +151 -0
- package/lib/enforcement/tool-grants.js.map +1 -0
- package/lib/index.js +224 -42
- package/lib/index.js.map +1 -1
- package/lib/personal-skills/service.js +10 -3
- package/lib/personal-skills/service.js.map +1 -1
- package/lib/qa-tools/index.js +4 -0
- package/lib/qa-tools/index.js.map +1 -1
- package/lib/resolve-config.js +0 -2
- package/lib/resolve-config.js.map +1 -1
- package/lib/secure-session.js +71 -17
- package/lib/secure-session.js.map +1 -1
- package/lib/typert.host.js +2237 -202
- package/lib/typert.remote-client.d.ts +49 -3
- package/lib/typert.remote-client.js +1863 -183
- package/lib/types/access/capability-catalog.d.ts +37 -0
- package/lib/types/access/model.d.ts +60 -0
- package/lib/types/access/role-repository.d.ts +32 -0
- package/lib/types/access/service.d.ts +57 -0
- package/lib/types/access/skill-metadata.d.ts +53 -0
- package/lib/types/account-remotes.d.ts +6 -0
- package/lib/types/accounts/errors.d.ts +1 -1
- package/lib/types/accounts/file.d.ts +16 -5
- package/lib/types/accounts/store.d.ts +83 -3
- package/lib/types/admin/conversation-log.d.ts +39 -0
- package/lib/types/admin/index.d.ts +24 -0
- package/lib/types/admin/metrics.d.ts +29 -0
- package/lib/types/admin/paging.d.ts +33 -0
- package/lib/types/admin/permissions.d.ts +10 -0
- package/lib/types/admin/quality-store.d.ts +82 -0
- package/lib/types/admin/queue.d.ts +21 -0
- package/lib/types/admin/redaction.d.ts +29 -0
- package/lib/types/admin/service.d.ts +105 -0
- package/lib/types/admin/session-log.d.ts +53 -0
- package/lib/types/client/QaSessionController.d.ts +12 -1
- package/lib/types/client/QaSurface.d.ts +7 -1
- package/lib/types/client/admin/QaAdmin.d.ts +17 -0
- package/lib/types/client/admin/format.d.ts +43 -0
- package/lib/types/client/admin/pages/Conversations.d.ts +21 -0
- package/lib/types/client/admin/pages/Overview.d.ts +13 -0
- package/lib/types/client/admin/pages/Quality.d.ts +18 -0
- package/lib/types/client/admin/pages/Review.d.ts +15 -0
- package/lib/types/client/admin/pages/Users.d.ts +22 -0
- package/lib/types/client/admin/routes.d.ts +50 -0
- package/lib/types/client/admin/shared.d.ts +53 -0
- package/lib/types/client/admin/styles.d.ts +11 -0
- package/lib/types/client/components/QaHeader.d.ts +5 -1
- package/lib/types/client/components/QaMessage.d.ts +14 -1
- package/lib/types/client/create-session.d.ts +2 -0
- package/lib/types/client/role/RoleSelector.d.ts +14 -0
- package/lib/types/client/session-sources.d.ts +9 -0
- package/lib/types/client/settings/sections.d.ts +0 -1
- package/lib/types/client/types.d.ts +39 -2
- package/lib/types/enforcement/skill-policy.d.ts +29 -0
- package/lib/types/enforcement/tool-grants.d.ts +84 -0
- package/lib/types/index.d.ts +62 -14
- package/lib/types/qa-tools/index.d.ts +2 -0
- package/lib/types/secure-session.d.ts +10 -1
- package/lib/types/types.d.ts +568 -5
- package/package.json +1 -1
- package/lib/client/settings/sections/documents.js +0 -88
- package/lib/client/settings/sections/documents.js.map +0 -1
- package/lib/documents/artifacts/ids.js +0 -43
- package/lib/documents/artifacts/ids.js.map +0 -1
- package/lib/documents/artifacts/manifest.js +0 -66
- package/lib/documents/artifacts/manifest.js.map +0 -1
- package/lib/documents/artifacts/store.js +0 -169
- package/lib/documents/artifacts/store.js.map +0 -1
- package/lib/documents/capabilities.js +0 -93
- package/lib/documents/capabilities.js.map +0 -1
- package/lib/documents/config.js +0 -302
- package/lib/documents/config.js.map +0 -1
- package/lib/documents/defaults.js +0 -78
- package/lib/documents/defaults.js.map +0 -1
- package/lib/documents/errors.js +0 -101
- package/lib/documents/errors.js.map +0 -1
- package/lib/documents/index.js +0 -80
- package/lib/documents/index.js.map +0 -1
- package/lib/documents/inspect/facts.js +0 -161
- package/lib/documents/inspect/facts.js.map +0 -1
- package/lib/documents/inspect/zip.js +0 -108
- package/lib/documents/inspect/zip.js.map +0 -1
- package/lib/documents/markdown/directives.js +0 -135
- package/lib/documents/markdown/directives.js.map +0 -1
- package/lib/documents/markdown/frontmatter.js +0 -35
- package/lib/documents/markdown/frontmatter.js.map +0 -1
- package/lib/documents/markdown/normalize.js +0 -113
- package/lib/documents/markdown/normalize.js.map +0 -1
- package/lib/documents/orchestrator/assets.js +0 -243
- package/lib/documents/orchestrator/assets.js.map +0 -1
- package/lib/documents/orchestrator/convert-document.js +0 -186
- package/lib/documents/orchestrator/convert-document.js.map +0 -1
- package/lib/documents/orchestrator/create-document.js +0 -292
- package/lib/documents/orchestrator/create-document.js.map +0 -1
- package/lib/documents/orchestrator/extract-document.js +0 -162
- package/lib/documents/orchestrator/extract-document.js.map +0 -1
- package/lib/documents/orchestrator/inspect-document.js +0 -89
- package/lib/documents/orchestrator/inspect-document.js.map +0 -1
- package/lib/documents/orchestrator/runtime-deps.js +0 -59
- package/lib/documents/orchestrator/runtime-deps.js.map +0 -1
- package/lib/documents/orchestrator/scope.js +0 -132
- package/lib/documents/orchestrator/scope.js.map +0 -1
- package/lib/documents/providers/docling.js +0 -247
- package/lib/documents/providers/docling.js.map +0 -1
- package/lib/documents/providers/libreoffice.js +0 -130
- package/lib/documents/providers/libreoffice.js.map +0 -1
- package/lib/documents/providers/markitdown.js +0 -89
- package/lib/documents/providers/markitdown.js.map +0 -1
- package/lib/documents/providers/pandoc.js +0 -161
- package/lib/documents/providers/pandoc.js.map +0 -1
- package/lib/documents/providers/process.js +0 -164
- package/lib/documents/providers/process.js.map +0 -1
- package/lib/documents/providers/registry.js +0 -152
- package/lib/documents/providers/registry.js.map +0 -1
- package/lib/documents/providers/shared.js +0 -75
- package/lib/documents/providers/shared.js.map +0 -1
- package/lib/documents/runtime.js +0 -114
- package/lib/documents/runtime.js.map +0 -1
- package/lib/documents/security/file-types.js +0 -188
- package/lib/documents/security/file-types.js.map +0 -1
- package/lib/documents/security/limits.js +0 -78
- package/lib/documents/security/limits.js.map +0 -1
- package/lib/documents/security/mime.js +0 -43
- package/lib/documents/security/mime.js.map +0 -1
- package/lib/documents/security/paths.js +0 -133
- package/lib/documents/security/paths.js.map +0 -1
- package/lib/documents/templates/registry.js +0 -147
- package/lib/documents/templates/registry.js.map +0 -1
- package/lib/documents/templates/resolver.js +0 -59
- package/lib/documents/templates/resolver.js.map +0 -1
- package/lib/documents/tools/convert.js +0 -125
- package/lib/documents/tools/convert.js.map +0 -1
- package/lib/documents/tools/create.js +0 -187
- package/lib/documents/tools/create.js.map +0 -1
- package/lib/documents/tools/index.js +0 -41
- package/lib/documents/tools/index.js.map +0 -1
- package/lib/documents/tools/inspect.js +0 -135
- package/lib/documents/tools/inspect.js.map +0 -1
- package/lib/documents/tools/shared.js +0 -88
- package/lib/documents/tools/shared.js.map +0 -1
- package/lib/documents/tools/to-markdown.js +0 -125
- package/lib/documents/tools/to-markdown.js.map +0 -1
- package/lib/documents/types.js +0 -12
- package/lib/documents/types.js.map +0 -1
- package/lib/types/client/settings/sections/documents.d.ts +0 -13
- package/lib/types/documents/artifacts/ids.d.ts +0 -14
- package/lib/types/documents/artifacts/manifest.d.ts +0 -32
- package/lib/types/documents/artifacts/store.d.ts +0 -67
- package/lib/types/documents/capabilities.d.ts +0 -32
- package/lib/types/documents/config.d.ts +0 -27
- package/lib/types/documents/defaults.d.ts +0 -161
- package/lib/types/documents/errors.d.ts +0 -42
- package/lib/types/documents/index.d.ts +0 -63
- package/lib/types/documents/inspect/facts.d.ts +0 -43
- package/lib/types/documents/inspect/zip.d.ts +0 -28
- package/lib/types/documents/markdown/directives.d.ts +0 -39
- package/lib/types/documents/markdown/frontmatter.d.ts +0 -15
- package/lib/types/documents/markdown/normalize.d.ts +0 -30
- package/lib/types/documents/orchestrator/assets.d.ts +0 -55
- package/lib/types/documents/orchestrator/convert-document.d.ts +0 -25
- package/lib/types/documents/orchestrator/create-document.d.ts +0 -18
- package/lib/types/documents/orchestrator/extract-document.d.ts +0 -24
- package/lib/types/documents/orchestrator/inspect-document.d.ts +0 -12
- package/lib/types/documents/orchestrator/runtime-deps.d.ts +0 -43
- package/lib/types/documents/orchestrator/scope.d.ts +0 -52
- package/lib/types/documents/providers/docling.d.ts +0 -54
- package/lib/types/documents/providers/libreoffice.d.ts +0 -40
- package/lib/types/documents/providers/markitdown.d.ts +0 -28
- package/lib/types/documents/providers/pandoc.d.ts +0 -42
- package/lib/types/documents/providers/process.d.ts +0 -54
- package/lib/types/documents/providers/registry.d.ts +0 -68
- package/lib/types/documents/providers/shared.d.ts +0 -27
- package/lib/types/documents/runtime.d.ts +0 -59
- package/lib/types/documents/security/file-types.d.ts +0 -39
- package/lib/types/documents/security/limits.d.ts +0 -24
- package/lib/types/documents/security/mime.d.ts +0 -13
- package/lib/types/documents/security/paths.d.ts +0 -38
- package/lib/types/documents/templates/registry.d.ts +0 -50
- package/lib/types/documents/templates/resolver.d.ts +0 -30
- package/lib/types/documents/tools/convert.d.ts +0 -9
- package/lib/types/documents/tools/create.d.ts +0 -14
- package/lib/types/documents/tools/index.d.ts +0 -33
- package/lib/types/documents/tools/inspect.d.ts +0 -9
- package/lib/types/documents/tools/shared.d.ts +0 -77
- package/lib/types/documents/tools/to-markdown.d.ts +0 -12
- package/lib/types/documents/types.d.ts +0 -294
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import { ISSUE_GROUPS, ISSUE_LABELS, REVIEW_PRIORITY_LABELS, REVIEW_REASON_LABELS, SEVERITY_LABELS, TARGET_LABELS, formatStamp, } from "../format.js";
|
|
4
|
+
import { Badge, FilterField, Pager, adminErrorMessage, useAdminResource, } from "../shared.js";
|
|
5
|
+
/**
|
|
6
|
+
* The review form and its queue.
|
|
7
|
+
*
|
|
8
|
+
* A verdict here is the reviewer's own judgement, deliberately kept apart from
|
|
9
|
+
* the user's thumbs: the reviewer answers "does this match our quality bar",
|
|
10
|
+
* the user answered "was this useful to me". Both are stored against the exact
|
|
11
|
+
* message, and neither rewrites the other.
|
|
12
|
+
*/
|
|
13
|
+
const PAGE_SIZE = 20;
|
|
14
|
+
export function AdminReviewQueue(props) {
|
|
15
|
+
const [rows, setRows] = useState([]);
|
|
16
|
+
const [cursor, setCursor] = useState(null);
|
|
17
|
+
const [total, setTotal] = useState(0);
|
|
18
|
+
const load = async (next, append) => {
|
|
19
|
+
const result = await props.api.reviewQueue(props.token, next, PAGE_SIZE);
|
|
20
|
+
if (!result.ok)
|
|
21
|
+
return;
|
|
22
|
+
setTotal(result.value.total);
|
|
23
|
+
setCursor(result.value.nextCursor);
|
|
24
|
+
setRows((current) => append ? [...current, ...result.value.items] : result.value.items);
|
|
25
|
+
};
|
|
26
|
+
const resource = useAdminResource(() => props.api.reviewQueue(props.token, null, PAGE_SIZE), [props.api, props.token]);
|
|
27
|
+
const items = resource.data?.items ?? rows;
|
|
28
|
+
return (_jsxs("section", { className: "dsh-qa-admin__page", "aria-label": "\u041E\u0447\u0435\u0440\u0435\u0434\u044C \u0440\u0430\u0437\u0431\u043E\u0440\u0430", children: [_jsx("div", { className: "dsh-qa-admin__title-row", children: _jsxs("div", { children: [_jsx("h1", { children: "\u041E\u0447\u0435\u0440\u0435\u0434\u044C \u0440\u0430\u0437\u0431\u043E\u0440\u0430" }), _jsx("p", { children: "\u0420\u0430\u0437\u0433\u043E\u0432\u043E\u0440\u044B, \u0442\u0440\u0435\u0431\u0443\u044E\u0449\u0438\u0435 \u0432\u043D\u0438\u043C\u0430\u043D\u0438\u044F: \u043D\u0435\u0433\u0430\u0442\u0438\u0432\u043D\u044B\u0435 \u043E\u0446\u0435\u043D\u043A\u0438, \u0440\u0443\u0447\u043D\u044B\u0435 \u0437\u0430\u043F\u0440\u043E\u0441\u044B \u0438 \u0441\u0431\u043E\u0438 \u0438\u043D\u0441\u0442\u0440\u0443\u043C\u0435\u043D\u0442\u043E\u0432. \u0420\u0430\u0437\u043E\u0431\u0440\u0430\u043D\u043D\u044B\u0439 \u043F\u0443\u043D\u043A\u0442 \u0443\u0445\u043E\u0434\u0438\u0442 \u0438\u0437 \u043E\u0447\u0435\u0440\u0435\u0434\u0438." })] }) }), resource.error === undefined ? null : (_jsx("p", { className: "dsh-qa-admin__error", role: "alert", children: adminErrorMessage(resource.error) })), items.length === 0 ? (_jsx("p", { className: "dsh-qa-admin__empty", children: resource.loading ? "Загружаю…" : "Очередь пуста." })) : (_jsx("ul", { className: "dsh-qa-admin__queue", children: items.map((row, index) => (_jsxs("li", { className: `dsh-qa-admin__queue-item dsh-qa-admin__queue-item--${row.priority}`, children: [_jsxs("div", { className: "dsh-qa-admin__queue-head", children: [_jsx("span", { className: "dsh-qa-admin__queue-priority", children: REVIEW_PRIORITY_LABELS[row.priority] }), _jsx("span", { children: REVIEW_REASON_LABELS[row.reason] }), _jsx(Badge, { tone: row.status === "reviewed" ? "positive" : "neutral", children: row.status === "reviewed"
|
|
29
|
+
? "Разобрано"
|
|
30
|
+
: row.status === "needs_followup"
|
|
31
|
+
? "Нужно вернуться"
|
|
32
|
+
: "Не разобрано" }), _jsx("time", { title: row.raisedAt, children: formatStamp(row.raisedAt) })] }), _jsx("button", { type: "button", onClick: () => props.onOpenConversation(row.conversationId, row.messageId), children: row.title ?? row.conversationId }), _jsxs("span", { className: "dsh-qa-admin__queue-owner", children: [row.displayName, row.subroleId === "" ? "" : ` · ${row.subroleId}`] }), row.issueSummary === undefined ? null : (_jsx("p", { className: "dsh-qa-admin__queue-issues", children: row.issueSummary
|
|
33
|
+
.map((issue) => ISSUE_LABELS[issue])
|
|
34
|
+
.join(", ") }))] }, `${row.conversationId}:${row.messageId ?? ""}:${index}`))) })), _jsx(Pager, { total: resource.data?.total ?? total, shown: items.length, hasMore: (resource.data?.nextCursor ?? cursor) !== null, loading: resource.loading, onMore: () => void load(resource.data?.nextCursor ?? cursor, true), onReset: () => void resource.reload() })] }));
|
|
35
|
+
}
|
|
36
|
+
const SEVERITIES = ["minor", "major", "critical"];
|
|
37
|
+
export function ReviewPanel(props) {
|
|
38
|
+
const [status, setStatus] = useState("reviewed");
|
|
39
|
+
const [issues, setIssues] = useState([]);
|
|
40
|
+
const [severity, setSeverity] = useState("minor");
|
|
41
|
+
const [notes, setNotes] = useState("");
|
|
42
|
+
const [target, setTarget] = useState("");
|
|
43
|
+
const [suggestedAction, setSuggestedAction] = useState("");
|
|
44
|
+
const [busy, setBusy] = useState(false);
|
|
45
|
+
const [error, setError] = useState();
|
|
46
|
+
const [queued, setQueued] = useState(false);
|
|
47
|
+
const toggleIssue = (issue) => {
|
|
48
|
+
setIssues((current) => current.includes(issue)
|
|
49
|
+
? current.filter((value) => value !== issue)
|
|
50
|
+
: [...current, issue]);
|
|
51
|
+
};
|
|
52
|
+
const save = async () => {
|
|
53
|
+
setBusy(true);
|
|
54
|
+
const input = {
|
|
55
|
+
conversationId: props.detail.conversationId,
|
|
56
|
+
status,
|
|
57
|
+
issues,
|
|
58
|
+
severity,
|
|
59
|
+
...(notes.trim() === "" ? {} : { notes: notes.trim() }),
|
|
60
|
+
...(target === "" ? {} : { target }),
|
|
61
|
+
...(suggestedAction.trim() === ""
|
|
62
|
+
? {}
|
|
63
|
+
: { suggestedAction: suggestedAction.trim() }),
|
|
64
|
+
};
|
|
65
|
+
const result = await props.api.saveReview(props.token, input);
|
|
66
|
+
setBusy(false);
|
|
67
|
+
if (!result.ok) {
|
|
68
|
+
setError(adminErrorMessage(result.error));
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
setError(undefined);
|
|
72
|
+
setNotes("");
|
|
73
|
+
setSuggestedAction("");
|
|
74
|
+
props.onSaved();
|
|
75
|
+
};
|
|
76
|
+
const queueIt = async () => {
|
|
77
|
+
setBusy(true);
|
|
78
|
+
const result = await props.api.queueConversation(props.token, props.detail.conversationId, null);
|
|
79
|
+
setBusy(false);
|
|
80
|
+
if (!result.ok) {
|
|
81
|
+
setError(adminErrorMessage(result.error));
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
setQueued(true);
|
|
85
|
+
props.onSaved();
|
|
86
|
+
};
|
|
87
|
+
return (_jsxs("aside", { className: "dsh-qa-admin__review", "aria-label": "\u0420\u0430\u0437\u0431\u043E\u0440 \u0440\u0430\u0437\u0433\u043E\u0432\u043E\u0440\u0430", children: [_jsx("h2", { children: "\u0420\u0430\u0437\u0431\u043E\u0440" }), error === undefined ? null : (_jsx("p", { className: "dsh-qa-admin__error", role: "alert", children: error })), props.detail.reviews.length === 0 ? null : (_jsx("ul", { className: "dsh-qa-admin__reviews", children: props.detail.reviews.map((review) => (_jsxs("li", { children: [_jsxs("div", { children: [_jsx(Badge, { tone: review.status === "reviewed" ? "positive" : "negative", children: review.status === "reviewed"
|
|
88
|
+
? "Разобрано"
|
|
89
|
+
: "Нужно вернуться" }), _jsx("span", { children: SEVERITY_LABELS[review.severity] }), _jsx("time", { title: review.createdAt, children: formatStamp(review.createdAt) })] }), review.issues.length === 0 ? null : (_jsx("p", { children: review.issues.map((issue) => ISSUE_LABELS[issue]).join(", ") })), review.notes === undefined ? null : _jsx("p", { children: review.notes }), review.target === undefined ? null : (_jsxs("p", { children: ["\u041F\u0440\u0438\u0447\u0438\u043D\u0430: ", TARGET_LABELS[review.target], review.suggestedAction === undefined
|
|
90
|
+
? ""
|
|
91
|
+
: ` — ${review.suggestedAction}`] }))] }, review.id))) })), props.canReview ? (_jsxs(_Fragment, { children: [_jsx(FilterField, { label: "\u0421\u0442\u0430\u0442\u0443\u0441", children: _jsxs("select", { value: status, onChange: (event) => setStatus(event.currentTarget.value), children: [_jsx("option", { value: "reviewed", children: "\u0420\u0430\u0437\u043E\u0431\u0440\u0430\u043D\u043E" }), _jsx("option", { value: "needs_followup", children: "\u041D\u0443\u0436\u043D\u043E \u0432\u0435\u0440\u043D\u0443\u0442\u044C\u0441\u044F" })] }) }), _jsxs("fieldset", { className: "dsh-qa-admin__issues", children: [_jsx("legend", { children: "\u041F\u0440\u043E\u0431\u043B\u0435\u043C\u044B" }), ISSUE_GROUPS.map((group) => (_jsxs("div", { children: [_jsx("h4", { children: group.title }), group.issues.map((issue) => (_jsxs("label", { children: [_jsx("input", { type: "checkbox", checked: issues.includes(issue), onChange: () => toggleIssue(issue) }), ISSUE_LABELS[issue]] }, issue)))] }, group.title)))] }), _jsx(FilterField, { label: "\u0412\u0430\u0436\u043D\u043E\u0441\u0442\u044C", children: _jsx("select", { value: severity, onChange: (event) => setSeverity(event.currentTarget.value), children: SEVERITIES.map((value) => (_jsx("option", { value: value, children: SEVERITY_LABELS[value] }, value))) }) }), _jsx(FilterField, { label: "\u041A\u0443\u0434\u0430 \u043D\u0430\u043F\u0440\u0430\u0432\u0438\u0442\u044C \u0438\u0441\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u0435", children: _jsxs("select", { value: target, onChange: (event) => setTarget(event.currentTarget.value), children: [_jsx("option", { value: "", children: "\u041D\u0435 \u0443\u043A\u0430\u0437\u0430\u043D\u043E" }), Object.keys(TARGET_LABELS).map((value) => (_jsx("option", { value: value, children: TARGET_LABELS[value] }, value)))] }) }), _jsx(FilterField, { label: "\u0427\u0442\u043E \u0441\u0434\u0435\u043B\u0430\u0442\u044C", children: _jsx("input", { type: "text", value: suggestedAction, onChange: (event) => setSuggestedAction(event.currentTarget.value), placeholder: "\u041D\u0430\u043F\u0440\u0438\u043C\u0435\u0440: \u0434\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0440\u0435\u0433\u043B\u0430\u043C\u0435\u043D\u0442 \u0432 \u0431\u0430\u0437\u0443 \u0437\u043D\u0430\u043D\u0438\u0439" }) }), _jsx(FilterField, { label: "\u0417\u0430\u043C\u0435\u0442\u043A\u0438", children: _jsx("textarea", { value: notes, rows: 4, onChange: (event) => setNotes(event.currentTarget.value) }) }), _jsxs("div", { className: "dsh-qa-admin__actions", children: [_jsx("button", { type: "button", className: "dsh-qa-admin__primary", disabled: busy, onClick: () => void save(), children: "\u0421\u043E\u0445\u0440\u0430\u043D\u0438\u0442\u044C \u0440\u0430\u0437\u0431\u043E\u0440" }), _jsx("button", { type: "button", disabled: busy || queued, onClick: () => void queueIt(), children: queued ? "В очереди" : "Отправить на разбор" })] })] })) : (_jsx("p", { className: "dsh-qa-admin__empty", children: "\u041A\u043B\u0430\u0441\u0441\u0438\u0444\u0438\u0446\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u0440\u0430\u0437\u0433\u043E\u0432\u043E\u0440\u044B \u043C\u043E\u0436\u0435\u0442 \u0442\u043E\u043B\u044C\u043A\u043E \u0440\u0435\u0432\u044C\u044E\u0435\u0440 \u0438\u043B\u0438 \u0430\u0434\u043C\u0438\u043D\u0438\u0441\u0442\u0440\u0430\u0442\u043E\u0440." }))] }));
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=Review.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Review.js","sourceRoot":"","sources":["../../../../src/client/admin/pages/Review.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback, useEffect, useState } from "react";
|
|
3
|
+
import { ADMIN_ROLE_LABELS, formatCount, formatStamp } from "../format.js";
|
|
4
|
+
import { Badge, FilterField, Pager, Stamp, adminErrorMessage, useAdminResource, } from "../shared.js";
|
|
5
|
+
const PAGE_SIZE = 25;
|
|
6
|
+
/**
|
|
7
|
+
* Users: the table an administrator triages from, and the detail page that
|
|
8
|
+
* separates authorization from the QA subrole assignment — an admin may work
|
|
9
|
+
* as an analyst without that saying anything about their administrative reach.
|
|
10
|
+
*/
|
|
11
|
+
export function AdminUsers(props) {
|
|
12
|
+
const [search, setSearch] = useState("");
|
|
13
|
+
const [role, setRole] = useState("");
|
|
14
|
+
const [status, setStatus] = useState("");
|
|
15
|
+
const [rows, setRows] = useState([]);
|
|
16
|
+
const [cursor, setCursor] = useState(null);
|
|
17
|
+
const [total, setTotal] = useState(0);
|
|
18
|
+
const [error, setError] = useState();
|
|
19
|
+
const [loading, setLoading] = useState(true);
|
|
20
|
+
// One loader owns the page: the filter state rebuilds the callback, which
|
|
21
|
+
// restarts paging from the first page, and "show more" continues from the
|
|
22
|
+
// cursor the Host returned.
|
|
23
|
+
const load = useCallback(async (next, append) => {
|
|
24
|
+
setLoading(true);
|
|
25
|
+
const result = await props.api.users(props.token, {
|
|
26
|
+
search: search === "" ? null : search,
|
|
27
|
+
role: role === "" ? null : role,
|
|
28
|
+
status: status === "" ? null : status,
|
|
29
|
+
}, next, PAGE_SIZE);
|
|
30
|
+
setLoading(false);
|
|
31
|
+
if (!result.ok) {
|
|
32
|
+
setError(adminErrorMessage(result.error));
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
setError(undefined);
|
|
36
|
+
setTotal(result.value.total);
|
|
37
|
+
setCursor(result.value.nextCursor);
|
|
38
|
+
setRows((current) => append ? [...current, ...result.value.items] : result.value.items);
|
|
39
|
+
}, [props.api, props.token, search, role, status]);
|
|
40
|
+
useEffect(() => {
|
|
41
|
+
void load(null, false);
|
|
42
|
+
}, [load]);
|
|
43
|
+
return (_jsxs("section", { className: "dsh-qa-admin__page", "aria-label": "\u041F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u0438", children: [_jsx("div", { className: "dsh-qa-admin__title-row", children: _jsxs("div", { children: [_jsx("h1", { children: "\u041F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u0438" }), _jsx("p", { children: "\u0410\u0434\u043C\u0438\u043D\u0438\u0441\u0442\u0440\u0430\u0442\u0438\u0432\u043D\u0430\u044F \u0440\u043E\u043B\u044C \u0438 \u043F\u0440\u043E\u0444\u0438\u043B\u0438 \u0430\u0433\u0435\u043D\u0442\u0430 \u043D\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u044E\u0442\u0441\u044F \u043D\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043C\u043E. \u0423\u0434\u0430\u043B\u0435\u043D\u0438\u044F \u043D\u0435\u0442: \u0438\u0441\u0442\u043E\u0440\u0438\u044E \u0440\u0430\u0437\u0433\u043E\u0432\u043E\u0440\u043E\u0432 \u0441\u043E\u0445\u0440\u0430\u043D\u044F\u0435\u0442 \u043E\u0442\u043A\u043B\u044E\u0447\u0435\u043D\u0438\u0435." })] }) }), _jsxs("div", { className: "dsh-qa-admin__filters", children: [_jsx(FilterField, { label: "\u041F\u043E\u0438\u0441\u043A", children: _jsx("input", { type: "search", value: search, placeholder: "\u0418\u043C\u044F \u0438\u043B\u0438 \u0430\u0434\u0440\u0435\u0441", onChange: (event) => setSearch(event.currentTarget.value) }) }), _jsx(FilterField, { label: "\u0420\u043E\u043B\u044C", children: _jsxs("select", { value: role, onChange: (event) => setRole(event.currentTarget.value), children: [_jsx("option", { value: "", children: "\u041B\u044E\u0431\u0430\u044F" }), _jsx("option", { value: "admin", children: "\u0410\u0434\u043C\u0438\u043D\u0438\u0441\u0442\u0440\u0430\u0442\u043E\u0440" }), _jsx("option", { value: "reviewer", children: "\u0420\u0435\u0432\u044C\u044E\u0435\u0440" }), _jsx("option", { value: "user", children: "\u041F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044C" })] }) }), _jsx(FilterField, { label: "\u0421\u0442\u0430\u0442\u0443\u0441", children: _jsxs("select", { value: status, onChange: (event) => setStatus(event.currentTarget.value), children: [_jsx("option", { value: "", children: "\u041B\u044E\u0431\u043E\u0439" }), _jsx("option", { value: "active", children: "\u0410\u043A\u0442\u0438\u0432\u043D\u044B\u0435" }), _jsx("option", { value: "disabled", children: "\u041E\u0442\u043A\u043B\u044E\u0447\u0451\u043D\u043D\u044B\u0435" })] }) })] }), error === undefined ? null : (_jsx("p", { className: "dsh-qa-admin__error", role: "alert", children: error })), rows.length === 0 ? (_jsx("p", { className: "dsh-qa-admin__empty", children: loading ? "Загружаю…" : "Никого не нашлось." })) : (_jsxs("table", { className: "dsh-qa-admin__table", children: [_jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { children: "\u041F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044C" }), _jsx("th", { children: "\u0421\u0442\u0430\u0442\u0443\u0441" }), _jsx("th", { children: "\u0420\u043E\u043B\u044C" }), _jsx("th", { children: "\u041F\u0440\u043E\u0444\u0438\u043B\u0438 QA" }), _jsx("th", { children: "\u041F\u043E\u0441\u043B\u0435\u0434\u043D\u0438\u0439 \u0432\u0445\u043E\u0434" }), _jsx("th", { children: "\u0420\u0430\u0437\u0433\u043E\u0432\u043E\u0440\u044B" }), _jsx("th", { children: "\u041E\u0446\u0435\u043D\u043A\u0438" }), _jsx("th", {})] }) }), _jsx("tbody", { children: rows.map((row) => (_jsxs("tr", { children: [_jsxs("td", { children: [_jsx("strong", { children: row.fullName === "" ? row.displayName : row.fullName }), _jsx("small", { children: row.email })] }), _jsx("td", { children: row.disabled ? (_jsx(Badge, { tone: "negative", children: "\u041E\u0442\u043A\u043B\u044E\u0447\u0451\u043D" })) : (_jsx(Badge, { tone: "positive", children: "\u0410\u043A\u0442\u0438\u0432\u0435\u043D" })) }), _jsx("td", { children: ADMIN_ROLE_LABELS[row.role] }), _jsx("td", { children: row.access.allowedSubroles.join(", ") || "—" }), _jsx("td", { children: _jsx(Stamp, { value: row.lastLoginAt ?? undefined }) }), _jsx("td", { children: formatCount(row.conversations) }), _jsx("td", { children: formatCount(row.feedbackGiven) }), _jsx("td", { children: _jsx("button", { type: "button", onClick: () => props.onOpenUser(row.id), children: "\u041E\u0442\u043A\u0440\u044B\u0442\u044C" }) })] }, row.id))) })] })), _jsx(Pager, { total: total, shown: rows.length, hasMore: cursor !== null, loading: loading, onMore: () => void load(cursor, true), onReset: () => void load(null, false) })] }));
|
|
44
|
+
}
|
|
45
|
+
/** Authorization, assignment and the activity counters of one account. */
|
|
46
|
+
export function AdminUserDetail(props) {
|
|
47
|
+
const resource = useAdminResource(() => props.api.user(props.token, props.userId), [props.api, props.token, props.userId]);
|
|
48
|
+
const roles = useAdminResource(() => props.accessApi.admin(props.token), [props.accessApi, props.token]);
|
|
49
|
+
const [error, setError] = useState();
|
|
50
|
+
const [busy, setBusy] = useState(false);
|
|
51
|
+
const detail = resource.data;
|
|
52
|
+
const subroles = (roles.data?.config.subroles ?? []).filter(({ enabled }) => enabled);
|
|
53
|
+
const write = async (update) => {
|
|
54
|
+
setBusy(true);
|
|
55
|
+
const result = await props.api.updateUser(props.token, props.userId, update);
|
|
56
|
+
setBusy(false);
|
|
57
|
+
if (!result.ok) {
|
|
58
|
+
setError(adminErrorMessage(result.error));
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
setError(undefined);
|
|
62
|
+
await resource.reload();
|
|
63
|
+
};
|
|
64
|
+
if (resource.error !== undefined) {
|
|
65
|
+
return (_jsxs("section", { className: "dsh-qa-admin__page", children: [_jsx("p", { className: "dsh-qa-admin__error", role: "alert", children: adminErrorMessage(resource.error) }), _jsx("button", { type: "button", onClick: props.onBack, children: "\u041A \u0441\u043F\u0438\u0441\u043A\u0443" })] }));
|
|
66
|
+
}
|
|
67
|
+
if (detail === undefined) {
|
|
68
|
+
return (_jsx("section", { className: "dsh-qa-admin__page", children: _jsx("p", { className: "dsh-qa-admin__empty", children: "\u0417\u0430\u0433\u0440\u0443\u0436\u0430\u044E \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044F\u2026" }) }));
|
|
69
|
+
}
|
|
70
|
+
const access = detail.user.access;
|
|
71
|
+
const toggleSubrole = (id) => {
|
|
72
|
+
const allowed = access.allowedSubroles.includes(id)
|
|
73
|
+
? access.allowedSubroles.filter((value) => value !== id)
|
|
74
|
+
: [...access.allowedSubroles, id];
|
|
75
|
+
if (allowed.length === 0) {
|
|
76
|
+
setError("Нужен хотя бы один доступный профиль QA.");
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
const defaultSubrole = allowed.includes(access.defaultSubrole)
|
|
80
|
+
? access.defaultSubrole
|
|
81
|
+
: allowed[0];
|
|
82
|
+
void write({ access: { allowedSubroles: allowed, defaultSubrole } });
|
|
83
|
+
};
|
|
84
|
+
return (_jsxs("section", { className: "dsh-qa-admin__page", "aria-label": "\u041F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044C", children: [_jsx("div", { className: "dsh-qa-admin__title-row", children: _jsxs("div", { children: [_jsx("button", { type: "button", onClick: props.onBack, children: "\u2190 \u041F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u0438" }), _jsx("h1", { children: detail.user.fullName === ""
|
|
85
|
+
? detail.user.displayName
|
|
86
|
+
: detail.user.fullName }), _jsxs("p", { children: [detail.user.email, " \u00B7 \u0441\u043E\u0437\u0434\u0430\u043D ", formatStamp(detail.user.createdAt), " \u00B7 \u0432\u0445\u043E\u0434 ", formatStamp(detail.user.lastLoginAt ?? undefined)] })] }) }), error === undefined ? null : (_jsx("p", { className: "dsh-qa-admin__error", role: "alert", children: error })), _jsxs("div", { className: "dsh-qa-admin__columns", children: [_jsxs("section", { className: "dsh-qa-admin__panel", children: [_jsx("h2", { children: "\u0414\u043E\u0441\u0442\u0443\u043F" }), _jsx(FilterField, { label: "\u0410\u0434\u043C\u0438\u043D\u0438\u0441\u0442\u0440\u0430\u0442\u0438\u0432\u043D\u0430\u044F \u0440\u043E\u043B\u044C", children: _jsxs("select", { value: detail.user.role, disabled: busy, onChange: (event) => void write({
|
|
87
|
+
role: event.currentTarget.value,
|
|
88
|
+
}), children: [_jsx("option", { value: "user", children: "\u041F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044C" }), _jsx("option", { value: "reviewer", children: "\u0420\u0435\u0432\u044C\u044E\u0435\u0440" }), _jsx("option", { value: "admin", children: "\u0410\u0434\u043C\u0438\u043D\u0438\u0441\u0442\u0440\u0430\u0442\u043E\u0440" })] }) }), _jsx(FilterField, { label: "\u0421\u0442\u0430\u0442\u0443\u0441", children: _jsx("button", { type: "button", disabled: busy, onClick: () => void write({ disabled: !detail.user.disabled }), children: detail.user.disabled ? "Включить" : "Отключить" }) }), _jsx("h3", { children: "\u0414\u043E\u0441\u0442\u0443\u043F\u043D\u044B\u0435 \u043F\u0440\u043E\u0444\u0438\u043B\u0438 QA" }), _jsx("ul", { className: "dsh-qa-admin__checks", children: subroles.map((role) => (_jsx("li", { children: _jsxs("label", { children: [_jsx("input", { type: "checkbox", checked: access.allowedSubroles.includes(role.id), disabled: busy, onChange: () => toggleSubrole(role.id) }), role.name] }) }, role.id))) }), _jsx(FilterField, { label: "\u041F\u0440\u043E\u0444\u0438\u043B\u044C \u043F\u043E \u0443\u043C\u043E\u043B\u0447\u0430\u043D\u0438\u044E", children: _jsx("select", { value: access.defaultSubrole, disabled: busy || access.allowedSubroles.length === 0, onChange: (event) => void write({
|
|
89
|
+
access: {
|
|
90
|
+
allowedSubroles: access.allowedSubroles,
|
|
91
|
+
defaultSubrole: event.currentTarget.value,
|
|
92
|
+
},
|
|
93
|
+
}), children: access.allowedSubroles.map((id) => (_jsx("option", { value: id, children: subroles.find((role) => role.id === id)?.name ?? id }, id))) }) }), _jsx("h3", { children: "\u0414\u0435\u0439\u0441\u0442\u0432\u0443\u044E\u0449\u0438\u0435 \u0432\u043E\u0437\u043C\u043E\u0436\u043D\u043E\u0441\u0442\u0438" }), _jsx("ul", { className: "dsh-qa-admin__effective", children: detail.effective.map((row) => (_jsxs("li", { children: [_jsx("strong", { children: row.name }), _jsxs("span", { children: [formatCount(row.tools), " \u0438\u043D\u0441\u0442\u0440\u0443\u043C\u0435\u043D\u0442\u043E\u0432 \u00B7", " ", formatCount(row.skills), " \u043D\u0430\u0432\u044B\u043A\u043E\u0432"] })] }, row.subroleId))) })] }), _jsxs("section", { className: "dsh-qa-admin__panel", children: [_jsx("h2", { children: "\u0410\u043A\u0442\u0438\u0432\u043D\u043E\u0441\u0442\u044C" }), _jsxs("dl", { className: "dsh-qa-admin__facts", children: [_jsx("dt", { children: "\u0420\u0430\u0437\u0433\u043E\u0432\u043E\u0440\u044B" }), _jsx("dd", { children: formatCount(detail.activity.conversations) }), _jsx("dt", { children: "\u0421\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u044F" }), _jsx("dd", { children: formatCount(detail.activity.messages) }), _jsx("dt", { children: "\u041F\u043E\u043B\u043E\u0436\u0438\u0442\u0435\u043B\u044C\u043D\u044B\u0435 \u043E\u0446\u0435\u043D\u043A\u0438" }), _jsx("dd", { children: formatCount(detail.activity.positiveRatings) }), _jsx("dt", { children: "\u041D\u0435\u0433\u0430\u0442\u0438\u0432\u043D\u044B\u0435 \u043E\u0446\u0435\u043D\u043A\u0438" }), _jsx("dd", { children: formatCount(detail.activity.negativeRatings) })] }), _jsxs("div", { className: "dsh-qa-admin__actions", children: [_jsx("button", { type: "button", onClick: () => props.onOpenConversations(detail.user.id), children: "\u0420\u0430\u0437\u0433\u043E\u0432\u043E\u0440\u044B \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044F" }), _jsx("button", { type: "button", onClick: props.onOpenAudit, children: "\u0418\u0441\u0442\u043E\u0440\u0438\u044F \u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u0439" })] })] })] })] }));
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=Users.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Users.js","sourceRoot":"","sources":["../../../../src/client/admin/pages/Users.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The admin console's route model.
|
|
3
|
+
*
|
|
4
|
+
* The console lives under one host route (`/qa/admin`) and gives every entity
|
|
5
|
+
* with its own identity its own path, because a review finding is something
|
|
6
|
+
* people paste into a chat. Parsing and serializing live here, away from the
|
|
7
|
+
* components, so the mapping is testable without a DOM.
|
|
8
|
+
*/
|
|
9
|
+
/** Path segments after `/qa/admin`, without the leading slash. */
|
|
10
|
+
export function adminSegments(pathname, routePath) {
|
|
11
|
+
const base = `${routePath === "/" ? "" : routePath}/admin`;
|
|
12
|
+
const rest = pathname.startsWith(base) ? pathname.slice(base.length) : "";
|
|
13
|
+
return rest
|
|
14
|
+
.split("/")
|
|
15
|
+
.map((segment) => segment.trim())
|
|
16
|
+
.filter((segment) => segment !== "");
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Resolve a pathname into a console route. Unknown segments fall back to the
|
|
20
|
+
* section they live under rather than to an error page: a stale link should
|
|
21
|
+
* still land the reviewer somewhere useful.
|
|
22
|
+
*/
|
|
23
|
+
export function parseAdminRoute(pathname, routePath) {
|
|
24
|
+
const segments = adminSegments(pathname, routePath);
|
|
25
|
+
const [section, ...rest] = segments;
|
|
26
|
+
const param = rest[0];
|
|
27
|
+
switch (section) {
|
|
28
|
+
case undefined:
|
|
29
|
+
case "":
|
|
30
|
+
return { page: "overview" };
|
|
31
|
+
case "users":
|
|
32
|
+
return param === undefined
|
|
33
|
+
? { page: "users" }
|
|
34
|
+
: { page: "user", userId: decodeURIComponent(param) };
|
|
35
|
+
case "access":
|
|
36
|
+
if (rest[0] === "common")
|
|
37
|
+
return { page: "common" };
|
|
38
|
+
if (rest[0] === "skills")
|
|
39
|
+
return { page: "skills" };
|
|
40
|
+
return { page: "subroles" };
|
|
41
|
+
case "subroles":
|
|
42
|
+
return { page: "subroles" };
|
|
43
|
+
case "skills":
|
|
44
|
+
return { page: "skills" };
|
|
45
|
+
case "common":
|
|
46
|
+
return { page: "common" };
|
|
47
|
+
case "conversations":
|
|
48
|
+
return param === undefined
|
|
49
|
+
? { page: "conversations" }
|
|
50
|
+
: {
|
|
51
|
+
page: "conversation",
|
|
52
|
+
conversationId: decodeURIComponent(param),
|
|
53
|
+
...(rest[1] === undefined
|
|
54
|
+
? {}
|
|
55
|
+
: { messageId: decodeURIComponent(rest[1]) }),
|
|
56
|
+
};
|
|
57
|
+
case "review":
|
|
58
|
+
return { page: "review" };
|
|
59
|
+
case "quality":
|
|
60
|
+
return rest[0] === "analytics"
|
|
61
|
+
? { page: "quality" }
|
|
62
|
+
: { page: "feedback" };
|
|
63
|
+
case "feedback":
|
|
64
|
+
return { page: "feedback" };
|
|
65
|
+
case "analytics":
|
|
66
|
+
return { page: "quality" };
|
|
67
|
+
case "audit":
|
|
68
|
+
return { page: "audit" };
|
|
69
|
+
default:
|
|
70
|
+
return { page: "overview" };
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/** The pathname for one console route; the inverse of {@link parseAdminRoute}. */
|
|
74
|
+
export function adminPath(routePath, route, search = "") {
|
|
75
|
+
const base = `${routePath === "/" ? "" : routePath}/admin`;
|
|
76
|
+
const suffix = (() => {
|
|
77
|
+
switch (route.page) {
|
|
78
|
+
case "overview":
|
|
79
|
+
return "";
|
|
80
|
+
case "users":
|
|
81
|
+
return "/users";
|
|
82
|
+
case "user":
|
|
83
|
+
return `/users/${encodeURIComponent(route.userId)}`;
|
|
84
|
+
case "subroles":
|
|
85
|
+
return "/access/subroles";
|
|
86
|
+
case "skills":
|
|
87
|
+
return "/access/skills";
|
|
88
|
+
case "common":
|
|
89
|
+
return "/access/common";
|
|
90
|
+
case "conversations":
|
|
91
|
+
return "/conversations";
|
|
92
|
+
case "conversation":
|
|
93
|
+
return `/conversations/${encodeURIComponent(route.conversationId)}${route.messageId === undefined
|
|
94
|
+
? ""
|
|
95
|
+
: `/${encodeURIComponent(route.messageId)}`}`;
|
|
96
|
+
case "review":
|
|
97
|
+
return "/review";
|
|
98
|
+
case "feedback":
|
|
99
|
+
return "/quality/feedback";
|
|
100
|
+
case "quality":
|
|
101
|
+
return "/quality/analytics";
|
|
102
|
+
case "audit":
|
|
103
|
+
return "/audit";
|
|
104
|
+
}
|
|
105
|
+
})();
|
|
106
|
+
return `${base}${suffix}${search}`;
|
|
107
|
+
}
|
|
108
|
+
/** Which navigation entry is current for one route. */
|
|
109
|
+
export function adminSectionOf(route) {
|
|
110
|
+
switch (route.page) {
|
|
111
|
+
case "user":
|
|
112
|
+
case "users":
|
|
113
|
+
return "users";
|
|
114
|
+
case "subroles":
|
|
115
|
+
case "skills":
|
|
116
|
+
case "common":
|
|
117
|
+
return "access";
|
|
118
|
+
case "conversation":
|
|
119
|
+
case "conversations":
|
|
120
|
+
return "conversations";
|
|
121
|
+
case "feedback":
|
|
122
|
+
return "feedback";
|
|
123
|
+
default:
|
|
124
|
+
return route.page;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=routes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routes.js","sourceRoot":"","sources":["../../../src/client/admin/routes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback, useEffect, useState } from "react";
|
|
3
|
+
import { formatRelative } from "./format.js";
|
|
4
|
+
/** The audience-safe text of a refused Remote call. */
|
|
5
|
+
export function errorMessage(error) {
|
|
6
|
+
if (typeof error === "string")
|
|
7
|
+
return error;
|
|
8
|
+
if (error !== null && typeof error === "object" && "message" in error) {
|
|
9
|
+
return String(error.message ?? error);
|
|
10
|
+
}
|
|
11
|
+
return String(error);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* The refusal copy a console page shows. The Host sends a coarse reason code
|
|
15
|
+
* on the wire and nothing else, so the wording lives here — one place to edit,
|
|
16
|
+
* and no deployment detail leaks into the browser.
|
|
17
|
+
*/
|
|
18
|
+
export function adminErrorMessage(error) {
|
|
19
|
+
const message = errorMessage(error);
|
|
20
|
+
if (/reason: forbidden/u.test(message)) {
|
|
21
|
+
return "У вашей роли нет прав на это действие.";
|
|
22
|
+
}
|
|
23
|
+
if (/reason: auth-required/u.test(message)) {
|
|
24
|
+
return "Сессия истекла: войдите заново.";
|
|
25
|
+
}
|
|
26
|
+
if (/QA accounts are not enabled/u.test(message)) {
|
|
27
|
+
return "Учётные записи на этом стенде выключены.";
|
|
28
|
+
}
|
|
29
|
+
return message;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Load one administrative resource, keeping the previous value visible while
|
|
33
|
+
* it refreshes. Reviewers page through lists while new conversations arrive;
|
|
34
|
+
* blanking the table on every reload would make that unusable.
|
|
35
|
+
*/
|
|
36
|
+
export function useAdminResource(load, deps) {
|
|
37
|
+
const [data, setData] = useState();
|
|
38
|
+
const [error, setError] = useState();
|
|
39
|
+
const [loading, setLoading] = useState(true);
|
|
40
|
+
const reload = useCallback(async () => {
|
|
41
|
+
setLoading(true);
|
|
42
|
+
try {
|
|
43
|
+
const result = await load();
|
|
44
|
+
if (result.ok) {
|
|
45
|
+
setData(result.value);
|
|
46
|
+
setError(undefined);
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
setError(errorMessage(result.error));
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
catch (cause) {
|
|
53
|
+
setError(errorMessage(cause));
|
|
54
|
+
}
|
|
55
|
+
finally {
|
|
56
|
+
setLoading(false);
|
|
57
|
+
}
|
|
58
|
+
// The caller owns the identity of `load`: every page passes a callback
|
|
59
|
+
// rebuilt from its own state, and lists the state in `deps`.
|
|
60
|
+
}, deps);
|
|
61
|
+
useEffect(() => {
|
|
62
|
+
void reload();
|
|
63
|
+
}, [reload]);
|
|
64
|
+
return { data, error, loading, reload };
|
|
65
|
+
}
|
|
66
|
+
/** A status chip; the modifier class carries the semantic colour. */
|
|
67
|
+
export function Badge(props) {
|
|
68
|
+
return (_jsx("span", { className: `dsh-qa-admin__badge${props.tone === undefined ? "" : ` dsh-qa-admin__badge--${props.tone}`}`, children: props.children }));
|
|
69
|
+
}
|
|
70
|
+
export function Empty(props) {
|
|
71
|
+
return _jsx("p", { className: "dsh-qa-admin__empty", children: props.children });
|
|
72
|
+
}
|
|
73
|
+
/** A relative timestamp with the exact one available on hover. */
|
|
74
|
+
export function Stamp(props) {
|
|
75
|
+
return (_jsx("time", { className: "dsh-qa-admin__stamp", dateTime: props.value, title: props.value, children: props.value === undefined ? "—" : formatRelative(props.value) }));
|
|
76
|
+
}
|
|
77
|
+
export function ErrorLine(props) {
|
|
78
|
+
return props.message === undefined ? null : (_jsx("p", { className: "dsh-qa-admin__error", role: "alert", children: props.message }));
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Cursor paging controls. The cursor is opaque to the browser by design: only
|
|
82
|
+
* the Host knows how a page was cut.
|
|
83
|
+
*/
|
|
84
|
+
export function Pager(props) {
|
|
85
|
+
return (_jsxs("div", { className: "dsh-qa-admin__pager", children: [_jsxs("span", { children: ["\u041F\u043E\u043A\u0430\u0437\u0430\u043D\u043E ", props.shown, " \u0438\u0437 ", props.total] }), props.hasMore ? (_jsx("button", { type: "button", disabled: props.loading, onClick: props.onMore, children: "\u041F\u043E\u043A\u0430\u0437\u0430\u0442\u044C \u0435\u0449\u0451" })) : null, props.shown > 0 && props.hasMore ? (_jsx("button", { type: "button", onClick: props.onReset, children: "\u0421\u043D\u0430\u0447\u0430\u043B\u0430" })) : null] }));
|
|
86
|
+
}
|
|
87
|
+
/** One labeled filter control in a table toolbar. */
|
|
88
|
+
export function FilterField(props) {
|
|
89
|
+
return (_jsxs("label", { className: "dsh-qa-admin__filter", children: [_jsx("span", { children: props.label }), props.children] }));
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=shared.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared.js","sourceRoot":"","sources":["../../../src/client/admin/shared.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The administrative console's stylesheet. Colors come only from the QA
|
|
3
|
+
* palette tokens or the host's themed aliases, so light, dark and system themes
|
|
4
|
+
* stay coherent; the stylesheet test enforces that rule.
|
|
5
|
+
*
|
|
6
|
+
* Layout intent: a dense table surface for triage, a side panel for the review
|
|
7
|
+
* form, and no modal windows — the console is a place to work through a list,
|
|
8
|
+
* not a wizard.
|
|
9
|
+
*/
|
|
10
|
+
export const QA_ADMIN_CONSOLE_STYLES = String.raw `
|
|
11
|
+
.dsh-qa-admin__nav-group{display:flex;flex-direction:column;gap:4px;margin-bottom:14px}
|
|
12
|
+
.dsh-qa-admin__page{display:flex;flex-direction:column;min-width:0;gap:20px}
|
|
13
|
+
.dsh-qa-admin__panel{display:flex;flex-direction:column;gap:10px;padding:16px 18px;border:1px solid var(--dsw-alias-border-l2);border-radius:12px;background:var(--dsw-alias-bg-layer-3)}
|
|
14
|
+
.dsh-qa-admin__panel h2{margin:0;font-size:15px}
|
|
15
|
+
.dsh-qa-admin__panel h3{margin:14px 0 6px;font-size:13px;color:var(--dsw-alias-label-secondary)}
|
|
16
|
+
.dsh-qa-admin__panel-head{display:flex;align-items:center;justify-content:space-between;gap:12px}
|
|
17
|
+
.dsh-qa-admin__columns{display:grid;grid-template-columns:minmax(0,360px) minmax(0,1fr);gap:18px;align-items:start}
|
|
18
|
+
.dsh-qa-admin__metrics{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:12px}
|
|
19
|
+
.dsh-qa-admin__metric{display:flex;flex-direction:column;gap:2px;padding:14px 16px;border:1px solid var(--dsw-alias-border-l2);border-radius:12px;background:var(--dsw-alias-bg-layer-3)}
|
|
20
|
+
.dsh-qa-admin__metric-label{color:var(--dsw-alias-label-tertiary);font-size:11px;text-transform:uppercase;letter-spacing:.06em}
|
|
21
|
+
.dsh-qa-admin__metric-value{font-size:26px;line-height:1.2}
|
|
22
|
+
.dsh-qa-admin__metric-hint{color:var(--dsw-alias-label-tertiary);font-size:11px}
|
|
23
|
+
.dsh-qa-admin__filters{display:flex;flex-wrap:wrap;gap:10px 16px;align-items:flex-end;padding:12px 14px;border:1px solid var(--dsw-alias-border-l2);border-radius:12px;background:var(--dsw-alias-bg-layer-2)}
|
|
24
|
+
.dsh-qa-admin__filter{display:flex;flex-direction:column;gap:4px;color:var(--dsw-alias-label-tertiary);font-size:11px}
|
|
25
|
+
.dsh-qa-admin__filter>input,.dsh-qa-admin__filter>select,.dsh-qa-admin__filter>textarea{min-width:170px}
|
|
26
|
+
.dsh-qa-admin__filter>textarea{font-family:inherit;font-size:13px;resize:vertical}
|
|
27
|
+
.dsh-qa-admin__table{width:100%;border-collapse:collapse;font-size:13px}
|
|
28
|
+
.dsh-qa-admin__table th{position:sticky;top:0;padding:9px 10px;border-bottom:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-base);color:var(--dsw-alias-label-tertiary);font-size:11px;text-align:left;text-transform:uppercase;letter-spacing:.05em}
|
|
29
|
+
.dsh-qa-admin__table td{padding:10px;border-bottom:1px solid var(--dsw-alias-border-l2);vertical-align:top}
|
|
30
|
+
.dsh-qa-admin__table td small{display:block;margin-top:2px;color:var(--dsw-alias-label-tertiary);font-size:11px}
|
|
31
|
+
.dsh-qa-admin__table tr:hover td{background:var(--dsw-alias-interactive-bg-hover)}
|
|
32
|
+
.dsh-qa-admin__badge{display:inline-block;white-space:nowrap;padding:1px 8px;border-radius:999px;background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-secondary);font-size:11px;font-weight:500;line-height:17px}
|
|
33
|
+
.dsh-qa-admin__badge--positive{background:var(--dsh-qa-success10);color:var(--dsh-qa-success)}
|
|
34
|
+
.dsh-qa-admin__badge--negative{background:var(--dsh-qa-error10);color:var(--dsh-qa-error)}
|
|
35
|
+
.dsh-qa-admin__badge--warning{background:var(--dsh-qa-warning10);color:var(--dsh-qa-warning-hover)}
|
|
36
|
+
.dsh-qa-admin__pager{display:flex;align-items:center;gap:10px;color:var(--dsw-alias-label-tertiary);font-size:12px}
|
|
37
|
+
.dsh-qa-admin__pager>span{margin-right:auto}
|
|
38
|
+
.dsh-qa-admin__stamp{color:var(--dsw-alias-label-secondary);font-size:12px}
|
|
39
|
+
.dsh-qa-admin__mono{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:11px}
|
|
40
|
+
.dsh-qa-admin__alerts{display:flex;flex-direction:column;gap:6px;margin:0;padding:0;list-style:none}
|
|
41
|
+
.dsh-qa-admin__alert{padding:8px 12px;border-radius:9px;border:1px solid var(--dsw-alias-border-l2);font-size:13px}
|
|
42
|
+
.dsh-qa-admin__alert--critical{border-color:var(--dsh-qa-error30);background:var(--dsh-qa-error10)}
|
|
43
|
+
.dsh-qa-admin__alert--warning{border-color:var(--dsh-qa-warning30);background:var(--dsh-qa-warning10)}
|
|
44
|
+
.dsh-qa-admin__recent{display:flex;flex-direction:column;gap:6px;margin:0;padding:0;list-style:none}
|
|
45
|
+
.dsh-qa-admin__recent li{display:grid;grid-template-columns:20px minmax(0,1fr) 140px 120px;gap:8px;align-items:center;font-size:13px}
|
|
46
|
+
.dsh-qa-admin__recent button{text-align:left;border-color:transparent;background:transparent;padding:2px 0}
|
|
47
|
+
.dsh-qa-admin__recent time{color:var(--dsw-alias-label-tertiary);font-size:11px}
|
|
48
|
+
.dsh-qa-admin__queue{display:flex;flex-direction:column;gap:8px;margin:0;padding:0;list-style:none}
|
|
49
|
+
.dsh-qa-admin__queue-item{display:flex;flex-direction:column;gap:4px;padding:12px 14px;border:1px solid var(--dsw-alias-border-l2);border-left-width:3px;border-radius:10px;background:var(--dsw-alias-bg-layer-3)}
|
|
50
|
+
.dsh-qa-admin__queue-item--high{border-left-color:var(--dsh-qa-error)}
|
|
51
|
+
.dsh-qa-admin__queue-item--normal{border-left-color:var(--dsh-qa-warning)}
|
|
52
|
+
.dsh-qa-admin__queue-item--low{border-left-color:var(--dsw-alias-border-l2)}
|
|
53
|
+
.dsh-qa-admin__queue-head{display:flex;align-items:center;gap:10px;color:var(--dsw-alias-label-tertiary);font-size:11px}
|
|
54
|
+
.dsh-qa-admin__queue-head time{margin-left:auto}
|
|
55
|
+
.dsh-qa-admin__queue-priority{font-weight:600;color:var(--dsw-alias-label-secondary);text-transform:uppercase;letter-spacing:.05em}
|
|
56
|
+
.dsh-qa-admin__queue-item>button{align-self:flex-start;padding:0;border:0;background:transparent;color:var(--dsw-alias-label-primary);font-size:14px;font-weight:600;text-align:left}
|
|
57
|
+
.dsh-qa-admin__queue-owner{color:var(--dsw-alias-label-tertiary);font-size:12px}
|
|
58
|
+
.dsh-qa-admin__queue-issues{margin:0;color:var(--dsw-alias-label-secondary);font-size:12px}
|
|
59
|
+
.dsh-qa-admin__conversation{display:grid;grid-template-columns:minmax(0,1fr) minmax(280px,360px);gap:20px;align-items:start}
|
|
60
|
+
.dsh-qa-admin__transcript{display:flex;flex-direction:column;gap:14px;min-width:0}
|
|
61
|
+
.dsh-qa-admin__runtime{display:flex;flex-direction:column;gap:8px;padding:14px 16px;border:1px solid var(--dsw-alias-border-l2);border-radius:12px;background:var(--dsw-alias-bg-layer-2)}
|
|
62
|
+
.dsh-qa-admin__runtime h2{margin:0;font-size:13px;color:var(--dsw-alias-label-secondary)}
|
|
63
|
+
.dsh-qa-admin__runtime summary{cursor:pointer;color:var(--dsw-alias-label-secondary);font-size:12px}
|
|
64
|
+
.dsh-qa-admin__message{display:flex;flex-direction:column;gap:8px;padding:12px 14px;border:1px solid var(--dsw-alias-border-l2);border-radius:12px;background:var(--dsw-alias-bg-layer-3)}
|
|
65
|
+
.dsh-qa-admin__message--user{background:var(--dsw-alias-bg-layer-2)}
|
|
66
|
+
.dsh-qa-admin__message--highlighted{border-color:var(--dsh-qa-accent);box-shadow:0 0 0 2px var(--dsh-qa-accent-soft)}
|
|
67
|
+
.dsh-qa-admin__message>header{display:flex;flex-wrap:wrap;align-items:center;gap:8px;color:var(--dsw-alias-label-tertiary);font-size:11px}
|
|
68
|
+
.dsh-qa-admin__message>header strong{color:var(--dsw-alias-label-secondary);font-size:12px}
|
|
69
|
+
.dsh-qa-admin__message-text{margin:0;font-size:13px;line-height:1.6;white-space:pre-wrap;overflow-wrap:anywhere}
|
|
70
|
+
.dsh-qa-admin__usage{color:var(--dsw-alias-label-tertiary)}
|
|
71
|
+
.dsh-qa-admin__comment{margin:0;color:var(--dsw-alias-label-secondary);font-size:12px;font-style:italic}
|
|
72
|
+
.dsh-qa-admin__tools>button{display:inline-flex;align-items:center;gap:5px;padding:2px 0;border:0;background:transparent;color:var(--dsw-alias-label-secondary);font-size:12px}
|
|
73
|
+
.dsh-qa-admin__disclosure{flex:none;transition:transform .16s}
|
|
74
|
+
.dsh-qa-admin__disclosure--open{transform:rotate(180deg)}
|
|
75
|
+
.dsh-qa-admin__tools ol{display:flex;flex-direction:column;gap:8px;margin:8px 0 0;padding:0;list-style:none}
|
|
76
|
+
.dsh-qa-admin__tools li{display:flex;flex-wrap:wrap;align-items:center;gap:8px;padding:8px 10px;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;background:var(--dsw-alias-bg-layer-2);font-size:12px}
|
|
77
|
+
.dsh-qa-admin__tools pre{flex-basis:100%;margin:0;padding:8px;border-radius:6px;background:var(--dsw-alias-bg-base);color:var(--dsw-alias-label-secondary);font-size:11px;white-space:pre-wrap;overflow-wrap:anywhere;max-height:200px;overflow:auto}
|
|
78
|
+
.dsh-qa-admin__review{display:flex;flex-direction:column;gap:12px;position:sticky;top:0;padding:16px;border:1px solid var(--dsw-alias-border-l2);border-radius:12px;background:var(--dsw-alias-bg-layer-2)}
|
|
79
|
+
.dsh-qa-admin__review h2{margin:0;font-size:15px}
|
|
80
|
+
.dsh-qa-admin__reviews{display:flex;flex-direction:column;gap:10px;margin:0;padding:0;list-style:none}
|
|
81
|
+
.dsh-qa-admin__reviews li{display:flex;flex-direction:column;gap:4px;padding:10px;border:1px solid var(--dsw-alias-border-l2);border-radius:9px;font-size:12px}
|
|
82
|
+
.dsh-qa-admin__reviews li>div{display:flex;flex-wrap:wrap;align-items:center;gap:8px;color:var(--dsw-alias-label-tertiary);font-size:11px}
|
|
83
|
+
.dsh-qa-admin__reviews p{margin:0;color:var(--dsw-alias-label-secondary)}
|
|
84
|
+
.dsh-qa-admin__issues{display:flex;flex-direction:column;gap:10px;margin:0;padding:10px 12px;border:1px solid var(--dsw-alias-border-l2);border-radius:10px}
|
|
85
|
+
.dsh-qa-admin__issues legend{padding:0 6px;color:var(--dsw-alias-label-tertiary);font-size:11px}
|
|
86
|
+
.dsh-qa-admin__issues h4{margin:6px 0 4px;color:var(--dsw-alias-label-tertiary);font-size:10px;text-transform:uppercase;letter-spacing:.06em}
|
|
87
|
+
.dsh-qa-admin__issues label{display:flex;align-items:center;gap:6px;font-size:12px}
|
|
88
|
+
.dsh-qa-admin__checks,.dsh-qa-admin__effective,.dsh-qa-admin__issues-list,.dsh-qa-admin__trend{display:flex;flex-direction:column;gap:6px;margin:0;padding:0;list-style:none}
|
|
89
|
+
.dsh-qa-admin__checks label{display:flex;align-items:center;gap:6px;font-size:13px}
|
|
90
|
+
.dsh-qa-admin__effective li{display:flex;justify-content:space-between;gap:10px;font-size:12px}
|
|
91
|
+
.dsh-qa-admin__effective span{color:var(--dsw-alias-label-tertiary)}
|
|
92
|
+
.dsh-qa-admin__issues-list li,.dsh-qa-admin__trend li{display:flex;justify-content:space-between;gap:10px;font-size:12px}
|
|
93
|
+
.dsh-qa-admin__trend li span:first-child{color:var(--dsw-alias-label-tertiary)}
|
|
94
|
+
.dsh-qa-admin__facts{display:grid;grid-template-columns:auto minmax(0,1fr);gap:4px 14px;margin:0;font-size:12px}
|
|
95
|
+
.dsh-qa-admin__facts--wide{grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:10px 20px;padding:14px 16px;border:1px solid var(--dsw-alias-border-l2);border-radius:12px}
|
|
96
|
+
.dsh-qa-admin__facts--wide dd{margin-bottom:6px}
|
|
97
|
+
.dsh-qa-admin__facts dt{color:var(--dsw-alias-label-tertiary)}
|
|
98
|
+
.dsh-qa-admin__facts dd{margin:0;color:var(--dsw-alias-label-primary)}
|
|
99
|
+
.dsh-qa-admin__actions{display:flex;flex-wrap:wrap;gap:8px}
|
|
100
|
+
.dsh-qa-feedback{display:flex;flex-direction:column;gap:8px;margin-top:10px;padding:10px 12px;border:1px solid var(--dsw-alias-border-l2);border-radius:10px;background:var(--dsw-alias-bg-layer-2);font-size:12px}
|
|
101
|
+
.dsh-qa-feedback>strong{color:var(--dsw-alias-label-secondary);font-size:12px}
|
|
102
|
+
.dsh-qa-feedback__reasons{display:flex;flex-wrap:wrap;gap:4px 14px}
|
|
103
|
+
.dsh-qa-feedback__reasons label{display:flex;align-items:center;gap:6px;color:var(--dsw-alias-label-secondary)}
|
|
104
|
+
.dsh-qa-feedback textarea{width:100%;padding:6px 8px;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;background:var(--dsw-specific-input-major);color:var(--dsw-alias-label-primary);font:inherit;font-size:12px;resize:vertical}
|
|
105
|
+
.dsh-qa-feedback__actions{display:flex;gap:8px}
|
|
106
|
+
.dsh-qa-feedback__actions button{padding:5px 10px;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;background:var(--dsw-alias-bg-layer-3);color:var(--dsw-alias-label-secondary);cursor:pointer}
|
|
107
|
+
.dsh-qa-feedback__actions button[type="submit"]{border-color:transparent;background:var(--dsh-qa-accent);color:var(--dsh-qa-accent-contrast);font-weight:600}
|
|
108
|
+
@media (max-width:1100px){.dsh-qa-admin__conversation{grid-template-columns:minmax(0,1fr)}.dsh-qa-admin__columns{grid-template-columns:minmax(0,1fr)}.dsh-qa-admin__review{position:static}}
|
|
109
|
+
@media (max-width:760px){.dsh-qa-admin__recent li{grid-template-columns:20px minmax(0,1fr)}}
|
|
110
|
+
`;
|
|
111
|
+
//# sourceMappingURL=styles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"styles.js","sourceRoot":"","sources":["../../../src/client/admin/styles.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoGhD,CAAC"}
|