@koda-plus/medusa-plugin-subiekt-nexo 0.2.1 → 0.3.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/.medusa/server/src/admin/index.js +1983 -1218
- package/.medusa/server/src/admin/index.mjs +1986 -1221
- package/.medusa/server/src/api/admin/subiekt/helpers.js +4 -4
- package/.medusa/server/src/api/admin/subiekt/orders/[id]/check/route.d.ts +10 -0
- package/.medusa/server/src/api/admin/subiekt/orders/[id]/check/route.js +33 -0
- package/.medusa/server/src/api/admin/subiekt/orders/[id]/link/route.d.ts +10 -0
- package/.medusa/server/src/api/admin/subiekt/orders/[id]/link/route.js +40 -0
- package/.medusa/server/src/api/admin/subiekt/sync/route.d.ts +1 -1
- package/.medusa/server/src/api/admin/subiekt/sync/route.js +6 -4
- package/.medusa/server/src/jobs/subiekt-catch-up.d.ts +12 -0
- package/.medusa/server/src/jobs/subiekt-catch-up.js +26 -0
- package/.medusa/server/src/modules/subiekt/lib/catch-up.d.ts +47 -0
- package/.medusa/server/src/modules/subiekt/lib/catch-up.js +79 -0
- package/.medusa/server/src/modules/subiekt/lib/constants.d.ts +13 -1
- package/.medusa/server/src/modules/subiekt/lib/constants.js +15 -3
- package/.medusa/server/src/modules/subiekt/lib/contract.d.ts +37 -4
- package/.medusa/server/src/modules/subiekt/lib/demo.d.ts +1 -1
- package/.medusa/server/src/modules/subiekt/lib/demo.js +1 -1
- package/.medusa/server/src/modules/subiekt/lib/kit-contract.js +1 -1
- package/.medusa/server/src/modules/subiekt/lib/kit-meta.d.ts +2 -2
- package/.medusa/server/src/modules/subiekt/lib/kit-meta.js +3 -3
- package/.medusa/server/src/modules/subiekt/lib/kit-routes.d.ts +1 -1
- package/.medusa/server/src/modules/subiekt/lib/kit-routes.js +2 -2
- package/.medusa/server/src/modules/subiekt/lib/options.d.ts +9 -4
- package/.medusa/server/src/modules/subiekt/lib/options.js +4 -3
- package/.medusa/server/src/modules/subiekt/lib/order-payload.js +24 -12
- package/.medusa/server/src/modules/subiekt/lib/reconcile.d.ts +47 -0
- package/.medusa/server/src/modules/subiekt/lib/reconcile.js +83 -0
- package/.medusa/server/src/subscribers/subiekt-order-placed.d.ts +4 -0
- package/.medusa/server/src/subscribers/subiekt-order-placed.js +8 -13
- package/.medusa/server/src/workflows/subiekt/catch-up.d.ts +45 -0
- package/.medusa/server/src/workflows/subiekt/catch-up.js +163 -0
- package/.medusa/server/src/workflows/subiekt/reconcile-order.d.ts +26 -0
- package/.medusa/server/src/workflows/subiekt/reconcile-order.js +95 -0
- package/.medusa/server/src/workflows/subiekt/runtime.d.ts +9 -0
- package/.medusa/server/src/workflows/subiekt/runtime.js +38 -1
- package/CHANGELOG.md +39 -0
- package/README.md +56 -9
- package/contract/examples/events.response.json +1 -1
- package/contract/openapi.yaml +1 -1
- package/package.json +1 -1
- package/.medusa/server/src/modules/subiekt/lib/references.d.ts +0 -76
- package/.medusa/server/src/modules/subiekt/lib/references.js +0 -137
|
@@ -3,14 +3,15 @@ var __defProp = Object.defineProperty;
|
|
|
3
3
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
4
4
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
5
5
|
const jsxRuntime = require("react/jsx-runtime");
|
|
6
|
+
const react = require("react");
|
|
6
7
|
const reactI18next = require("react-i18next");
|
|
7
8
|
const adminSdk = require("@medusajs/admin-sdk");
|
|
9
|
+
const icons = require("@medusajs/icons");
|
|
8
10
|
const ui = require("@medusajs/ui");
|
|
9
11
|
const reactQuery = require("@tanstack/react-query");
|
|
10
12
|
const reactRouterDom = require("react-router-dom");
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
function backendUrl() {
|
|
13
|
+
const reactDom = require("react-dom");
|
|
14
|
+
function backendUrl$1() {
|
|
14
15
|
try {
|
|
15
16
|
if (typeof __BACKEND_URL__ !== "undefined" && __BACKEND_URL__) return String(__BACKEND_URL__).replace(/\/+$/, "");
|
|
16
17
|
} catch {
|
|
@@ -27,7 +28,7 @@ class SubiektRequestError extends Error {
|
|
|
27
28
|
}
|
|
28
29
|
async function subiektFetch(path, init) {
|
|
29
30
|
const hasBody = (init == null ? void 0 : init.body) !== void 0;
|
|
30
|
-
const res = await fetch(`${backendUrl()}${path}`, {
|
|
31
|
+
const res = await fetch(`${backendUrl$1()}${path}`, {
|
|
31
32
|
method: (init == null ? void 0 : init.method) ?? "GET",
|
|
32
33
|
credentials: "include",
|
|
33
34
|
headers: { Accept: "application/json", ...hasBody ? { "Content-Type": "application/json" } : {} },
|
|
@@ -82,6 +83,7 @@ function useSubiektTasks(filter, q, offset, limit, poll) {
|
|
|
82
83
|
function useSubiektDocuments(kind, q, offset, limit, poll) {
|
|
83
84
|
const params = new URLSearchParams({ limit: String(limit), offset: String(offset) });
|
|
84
85
|
if (kind && kind !== "all") params.set("kind", kind);
|
|
86
|
+
if (q) params.set("q", q);
|
|
85
87
|
return reactQuery.useQuery({
|
|
86
88
|
queryKey: subiektKeys.documents(kind, q, offset, limit),
|
|
87
89
|
queryFn: () => subiektFetch(`/admin/subiekt/documents?${params.toString()}`),
|
|
@@ -166,493 +168,240 @@ function useSubiektSendOrder(orderId) {
|
|
|
166
168
|
onSuccess: () => client.invalidateQueries({ queryKey: subiektKeys.order(orderId) })
|
|
167
169
|
});
|
|
168
170
|
}
|
|
169
|
-
function
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
171
|
+
function useSubiektOrderCheck(orderId) {
|
|
172
|
+
return reactQuery.useMutation({
|
|
173
|
+
mutationFn: () => subiektFetch(`/admin/subiekt/orders/${encodeURIComponent(orderId)}/check`, { method: "POST", body: {} })
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
function useSubiektLinkDocument(orderId) {
|
|
177
|
+
const client = reactQuery.useQueryClient();
|
|
178
|
+
return reactQuery.useMutation({
|
|
179
|
+
mutationFn: (body) => subiektFetch(`/admin/subiekt/orders/${encodeURIComponent(orderId)}/link`, { method: "POST", body }),
|
|
180
|
+
onSuccess: () => client.invalidateQueries({ queryKey: subiektKeys.all })
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
function backendUrl() {
|
|
173
184
|
try {
|
|
174
|
-
|
|
185
|
+
if (typeof __BACKEND_URL__ !== "undefined" && __BACKEND_URL__ && __BACKEND_URL__ !== "/") return String(__BACKEND_URL__).replace(/\/+$/, "");
|
|
175
186
|
} catch {
|
|
176
|
-
return d.toISOString().slice(0, 16).replace("T", " ");
|
|
177
187
|
}
|
|
188
|
+
return "";
|
|
178
189
|
}
|
|
179
|
-
function
|
|
180
|
-
|
|
181
|
-
return ms < 1e4 ? `${(ms / 1e3).toFixed(1)} s` : `${Math.round(ms / 1e3)} s`;
|
|
182
|
-
}
|
|
183
|
-
function fmtNumber(value, lang) {
|
|
184
|
-
const n = typeof value === "number" ? value : Number(value);
|
|
185
|
-
if (!Number.isFinite(n)) return "0";
|
|
190
|
+
function authHeaders() {
|
|
191
|
+
let type = "session";
|
|
186
192
|
try {
|
|
187
|
-
|
|
193
|
+
if (typeof __AUTH_TYPE__ !== "undefined" && __AUTH_TYPE__) type = String(__AUTH_TYPE__);
|
|
188
194
|
} catch {
|
|
189
|
-
return String(n);
|
|
190
195
|
}
|
|
196
|
+
if (type !== "jwt") return {};
|
|
197
|
+
let key = "medusa_auth_token";
|
|
198
|
+
try {
|
|
199
|
+
if (typeof __JWT_TOKEN_STORAGE_KEY__ !== "undefined" && __JWT_TOKEN_STORAGE_KEY__) key = String(__JWT_TOKEN_STORAGE_KEY__);
|
|
200
|
+
} catch {
|
|
201
|
+
}
|
|
202
|
+
let token = null;
|
|
203
|
+
try {
|
|
204
|
+
token = window.localStorage.getItem(key) ?? window.sessionStorage.getItem(key);
|
|
205
|
+
} catch {
|
|
206
|
+
token = null;
|
|
207
|
+
}
|
|
208
|
+
return token ? { Authorization: `Bearer ${token}` } : {};
|
|
191
209
|
}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
return /* @__PURE__ */ jsxRuntime.jsx(ui.StatusBadge, { color: TASK_TONE[status] ?? "grey", children: t(`tasks.statuses.${status}`) });
|
|
204
|
-
}
|
|
205
|
-
const RUN_TONE = { success: "green", partial: "orange", error: "red", skipped: "grey" };
|
|
206
|
-
function RunStatusBadge({ status }) {
|
|
207
|
-
const { t } = reactI18next.useTranslation("subiekt");
|
|
208
|
-
return /* @__PURE__ */ jsxRuntime.jsx(ui.StatusBadge, { color: RUN_TONE[status] ?? "grey", children: t(`runs.statuses.${status}`) });
|
|
209
|
-
}
|
|
210
|
-
function DocumentStatusBadge({ status }) {
|
|
211
|
-
const { t } = reactI18next.useTranslation("subiekt");
|
|
212
|
-
const tone = status === "canceled" ? "grey" : status === "completed" ? "green" : "blue";
|
|
213
|
-
return /* @__PURE__ */ jsxRuntime.jsx(ui.StatusBadge, { color: tone, children: t(`documents.statuses.${status}`, { defaultValue: status }) });
|
|
214
|
-
}
|
|
215
|
-
const CATALOG_TONE = {
|
|
216
|
-
planned: "blue",
|
|
217
|
-
applied: "green",
|
|
218
|
-
simulated: "purple",
|
|
219
|
-
over_cap: "grey",
|
|
220
|
-
stale: "orange",
|
|
221
|
-
failed: "red",
|
|
222
|
-
quarantined: "red",
|
|
223
|
-
skipped: "grey"
|
|
224
|
-
};
|
|
225
|
-
function CatalogStatusBadge({ status }) {
|
|
226
|
-
const { t } = reactI18next.useTranslation("subiekt");
|
|
227
|
-
return /* @__PURE__ */ jsxRuntime.jsx(ui.StatusBadge, { color: CATALOG_TONE[status] ?? "grey", children: t(`products.statuses.${status}`, { defaultValue: status }) });
|
|
228
|
-
}
|
|
229
|
-
function SampleList({ label, items }) {
|
|
230
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-1", children: [
|
|
231
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-fg-subtle", children: label }),
|
|
232
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-1", children: items.map((item) => /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { size: "2xsmall", className: "font-mono", children: item }, item)) })
|
|
233
|
-
] });
|
|
234
|
-
}
|
|
235
|
-
function RichText({ text }) {
|
|
236
|
-
const parts = text.split("`");
|
|
237
|
-
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: parts.map(
|
|
238
|
-
(part, i) => i % 2 === 1 ? /* @__PURE__ */ jsxRuntime.jsx("code", { className: "txt-compact-xsmall rounded border border-ui-border-base bg-ui-bg-subtle px-1 font-mono text-ui-fg-base", children: part }, i) : /* @__PURE__ */ jsxRuntime.jsx("span", { children: part }, i)
|
|
239
|
-
) });
|
|
210
|
+
class KitRequestError extends Error {
|
|
211
|
+
constructor(status, message, code, body) {
|
|
212
|
+
super(message);
|
|
213
|
+
__publicField(this, "status");
|
|
214
|
+
__publicField(this, "code");
|
|
215
|
+
__publicField(this, "body");
|
|
216
|
+
this.name = "KitRequestError";
|
|
217
|
+
this.status = status;
|
|
218
|
+
this.code = code;
|
|
219
|
+
this.body = body;
|
|
220
|
+
}
|
|
240
221
|
}
|
|
241
|
-
function
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
222
|
+
function kitRequestInit(init = {}) {
|
|
223
|
+
const method = init.method ?? "GET";
|
|
224
|
+
const write = method !== "GET";
|
|
225
|
+
const hasBody = init.body !== void 0;
|
|
226
|
+
return {
|
|
227
|
+
method,
|
|
228
|
+
credentials: "include",
|
|
229
|
+
signal: init.signal,
|
|
230
|
+
headers: {
|
|
231
|
+
Accept: "application/json",
|
|
232
|
+
...write ? { "Content-Type": "application/json", "x-koda-request": "1" } : {},
|
|
233
|
+
...authHeaders(),
|
|
234
|
+
...init.headers ?? {}
|
|
235
|
+
},
|
|
236
|
+
body: write ? JSON.stringify(hasBody ? init.body : {}) : void 0
|
|
237
|
+
};
|
|
250
238
|
}
|
|
251
|
-
function
|
|
252
|
-
const
|
|
253
|
-
const
|
|
254
|
-
|
|
239
|
+
async function kitFetch(path, init = {}) {
|
|
240
|
+
const res = await fetch(`${backendUrl()}${path}`, kitRequestInit(init));
|
|
241
|
+
const text = await res.text();
|
|
242
|
+
let json = null;
|
|
243
|
+
try {
|
|
244
|
+
json = text ? JSON.parse(text) : null;
|
|
245
|
+
} catch {
|
|
246
|
+
json = null;
|
|
247
|
+
}
|
|
248
|
+
if (!res.ok) {
|
|
249
|
+
const body = json && typeof json === "object" ? json : {};
|
|
250
|
+
throw new KitRequestError(res.status, typeof body.message === "string" ? body.message : `HTTP ${res.status}`, typeof body.code === "string" ? body.code : null, json);
|
|
251
|
+
}
|
|
252
|
+
return json;
|
|
255
253
|
}
|
|
256
|
-
function
|
|
257
|
-
return /* @__PURE__ */ jsxRuntime.
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
{
|
|
262
|
-
size: "xlarge",
|
|
263
|
-
weight: "plus",
|
|
264
|
-
leading: "compact",
|
|
265
|
-
className: ui.clx("tabular-nums", tone === "attention" ? "text-ui-tag-red-text" : tone === "muted" ? "text-ui-fg-muted" : "text-ui-fg-base"),
|
|
266
|
-
children: value
|
|
267
|
-
}
|
|
268
|
-
)
|
|
254
|
+
function WidgetFrame({ embedded, header, children, className }) {
|
|
255
|
+
if (embedded) return /* @__PURE__ */ jsxRuntime.jsx("div", { className: ui.clx("divide-y divide-ui-border-base", className), children });
|
|
256
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: ui.clx("divide-y p-0", className), children: [
|
|
257
|
+
header,
|
|
258
|
+
children
|
|
269
259
|
] });
|
|
270
260
|
}
|
|
271
|
-
function
|
|
272
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "
|
|
273
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
274
|
-
/* @__PURE__ */ jsxRuntime.jsx("
|
|
261
|
+
function KitLoading({ label, className }) {
|
|
262
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { role: "status", "aria-live": "polite", className: ui.clx("flex min-h-[8rem] flex-col items-center justify-center gap-y-2 px-6 py-8", className), children: [
|
|
263
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "size-5 animate-spin rounded-full border-2 border-ui-border-base border-t-ui-fg-interactive" }),
|
|
264
|
+
label ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "txt-compact-small text-ui-fg-subtle", children: label }) : null
|
|
275
265
|
] });
|
|
276
266
|
}
|
|
277
|
-
function
|
|
278
|
-
return /* @__PURE__ */ jsxRuntime.jsx("
|
|
279
|
-
"button",
|
|
280
|
-
{
|
|
281
|
-
type: "button",
|
|
282
|
-
onClick: () => onChange(o.value),
|
|
283
|
-
className: ui.clx(
|
|
284
|
-
"txt-compact-small-plus rounded-full border px-3 py-1 transition-colors",
|
|
285
|
-
value === o.value ? "border-ui-border-interactive bg-ui-bg-highlight text-ui-fg-interactive" : "border-ui-border-base text-ui-fg-subtle hover:bg-ui-bg-base-hover"
|
|
286
|
-
),
|
|
287
|
-
children: [
|
|
288
|
-
o.label,
|
|
289
|
-
typeof o.count === "number" && o.count > 0 ? /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { size: "2xsmall", className: "ml-2", children: o.count }) : null
|
|
290
|
-
]
|
|
291
|
-
},
|
|
292
|
-
o.value
|
|
293
|
-
)) });
|
|
267
|
+
function KitSkeletonRows({ cols, rows = 6 }) {
|
|
268
|
+
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: Array.from({ length: rows }, (_, r) => /* @__PURE__ */ jsxRuntime.jsx("tr", { "aria-hidden": true, className: "border-b border-ui-border-base last:border-b-0", children: Array.from({ length: cols }, (_2, c) => /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-6 py-3.5", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block h-3 animate-pulse rounded bg-ui-bg-component", style: { width: `${45 + (r * 7 + c * 13) % 45}%` } }) }, c)) }, r)) });
|
|
294
269
|
}
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
270
|
+
const KIT_META = {
|
|
271
|
+
pkg: "@koda-plus/medusa-plugin-subiekt-nexo",
|
|
272
|
+
version: "0.3.0"
|
|
273
|
+
};
|
|
274
|
+
const NBSP = " ";
|
|
275
|
+
const NBHY = "‑";
|
|
276
|
+
const SHORT = /(^|[\s("„])(oraz|albo|lub|ale|że|bo|czy|gdy|aby|by|więc|jak|na|do|za|ze|we|od|po|to|[aiouwze])[ \t]+/gi;
|
|
277
|
+
function nb(text) {
|
|
278
|
+
let out = text;
|
|
279
|
+
for (let k = 0; k < 2; k++) out = out.replace(SHORT, `$1$2${NBSP}`);
|
|
280
|
+
out = out.replace(/(\d) (?=\d{3}\b)/g, `$1${NBSP}`);
|
|
281
|
+
out = out.replace(/\b([eE])-(?=mail)/g, `$1${NBHY}`);
|
|
282
|
+
return out.replace(/(\d) (zł|€|Kč|EUR|USD|PLN|CZK|mln|tys\.|cm|mm|m²|%)/g, `$1${NBSP}$2`);
|
|
305
283
|
}
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
if (
|
|
310
|
-
|
|
311
|
-
const changes = num(s.toUpdate) + num(s.toCreate);
|
|
312
|
-
return t(run.dryRun ? "runs.summary.stockDry" : "runs.summary.stock", { changes, unchanged: num(s.unchanged) });
|
|
313
|
-
}
|
|
314
|
-
if (run.kind === "tasks") {
|
|
315
|
-
const vars = { succeeded: num(s.succeeded), retry: num(s.retry), failed: num(s.failed) };
|
|
316
|
-
return t(vars.retry || vars.failed ? "runs.summary.tasksIssues" : "runs.summary.tasks", vars);
|
|
317
|
-
}
|
|
318
|
-
if (run.kind === "events") return num(s.read) > 0 ? t("runs.summary.events", { applied: num(s.applied) }) : t("runs.summary.eventsNone");
|
|
319
|
-
if (run.kind === "health" && run.status === "success") return t("runs.summary.health");
|
|
320
|
-
if (run.kind === "products") {
|
|
321
|
-
const applied = num(s.applied) + num(s.simulated);
|
|
322
|
-
return t(run.dryRun ? "runs.summary.productsPlan" : "runs.summary.productsApplied", {
|
|
323
|
-
prices: num(s.priceChanges),
|
|
324
|
-
creates: num(s.toCreate),
|
|
325
|
-
applied,
|
|
326
|
-
failed: num(s.failed)
|
|
327
|
-
});
|
|
284
|
+
function typeset(value) {
|
|
285
|
+
if (typeof value === "string") return nb(value);
|
|
286
|
+
if (Array.isArray(value)) return value.map((v) => typeset(v));
|
|
287
|
+
if (value && typeof value === "object") {
|
|
288
|
+
return Object.fromEntries(Object.entries(value).map(([k, v]) => [k, typeset(v)]));
|
|
328
289
|
}
|
|
329
|
-
return
|
|
290
|
+
return value;
|
|
330
291
|
}
|
|
331
|
-
function
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
292
|
+
function usePageNav(tabs) {
|
|
293
|
+
const [params, setParams] = reactRouterDom.useSearchParams();
|
|
294
|
+
const raw = params.get("view");
|
|
295
|
+
const view = raw === "guide" || raw === "settings" ? raw : "panel";
|
|
296
|
+
const asked = params.get("tab") ?? "";
|
|
297
|
+
const tab = tabs.includes(asked) ? asked : tabs[0];
|
|
298
|
+
const go = (next, nextTab) => {
|
|
299
|
+
const p = new URLSearchParams(params);
|
|
300
|
+
if (next === "panel") p.delete("view");
|
|
301
|
+
else p.set("view", next);
|
|
302
|
+
if (next === "settings") p.set("tab", nextTab ?? tab);
|
|
303
|
+
else p.delete("tab");
|
|
304
|
+
setParams(p, { replace: true });
|
|
305
|
+
};
|
|
306
|
+
return { view, tab, go };
|
|
338
307
|
}
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
return
|
|
308
|
+
const VIEWS = ["panel", "guide", "settings"];
|
|
309
|
+
const VIEW_ICON = { panel: /* @__PURE__ */ jsxRuntime.jsx(icons.ChartBar, {}), guide: /* @__PURE__ */ jsxRuntime.jsx(icons.BookOpen, {}), settings: /* @__PURE__ */ jsxRuntime.jsx(icons.CogSixTooth, {}) };
|
|
310
|
+
function PageTabs({ value, onChange, labels }) {
|
|
311
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { role: "tablist", className: "flex flex-wrap items-center gap-1", children: VIEWS.map((v) => {
|
|
312
|
+
const on = v === value;
|
|
313
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
314
|
+
"button",
|
|
315
|
+
{
|
|
316
|
+
type: "button",
|
|
317
|
+
role: "tab",
|
|
318
|
+
"aria-selected": on,
|
|
319
|
+
onClick: () => onChange(v),
|
|
320
|
+
className: ui.clx(
|
|
321
|
+
"txt-compact-small-plus inline-flex items-center gap-x-1.5 rounded-md px-2.5 py-1.5 outline-none transition-fg focus-visible:shadow-borders-focus",
|
|
322
|
+
on ? "bg-ui-bg-base text-ui-fg-base shadow-borders-base" : "text-ui-fg-subtle hover:bg-ui-bg-base-hover hover:text-ui-fg-base"
|
|
323
|
+
),
|
|
324
|
+
children: [
|
|
325
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: ui.clx("flex", on ? "text-ui-fg-interactive" : "text-ui-fg-muted"), children: VIEW_ICON[v] }),
|
|
326
|
+
labels[v]
|
|
327
|
+
]
|
|
328
|
+
},
|
|
329
|
+
v
|
|
330
|
+
);
|
|
331
|
+
}) });
|
|
343
332
|
}
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
333
|
+
const POINT_TONE = {
|
|
334
|
+
grey: "border-ui-border-base bg-ui-bg-subtle text-ui-fg-subtle",
|
|
335
|
+
green: "border-ui-tag-green-border bg-ui-tag-green-bg text-ui-tag-green-text",
|
|
336
|
+
orange: "border-ui-tag-orange-border bg-ui-tag-orange-bg text-ui-tag-orange-text",
|
|
337
|
+
red: "border-ui-tag-red-border bg-ui-tag-red-bg text-ui-tag-red-text",
|
|
338
|
+
blue: "border-ui-tag-blue-border bg-ui-tag-blue-bg text-ui-tag-blue-text"
|
|
339
|
+
};
|
|
340
|
+
function KeyPoints({ items, label, className }) {
|
|
341
|
+
const shown = items.filter((p) => Boolean(p));
|
|
342
|
+
if (!shown.length) return null;
|
|
343
|
+
return /* @__PURE__ */ jsxRuntime.jsx("ul", { "aria-label": label, title: label, className: ui.clx("flex min-w-0 flex-nowrap items-center gap-1.5 overflow-x-auto [scrollbar-width:none] [&::-webkit-scrollbar]:hidden", className), children: shown.map((p, i) => /* @__PURE__ */ jsxRuntime.jsxs("li", { title: p.title, className: ui.clx("txt-compact-xsmall-plus inline-flex shrink-0 items-center gap-1 whitespace-nowrap rounded-full border px-2 py-0.5", POINT_TONE[p.tone ?? "grey"]), children: [
|
|
344
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": true, className: "flex shrink-0 [&_svg]:size-3.5", children: p.icon }),
|
|
345
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: p.text })
|
|
346
|
+
] }, i)) });
|
|
347
|
+
}
|
|
348
|
+
function OtherActions({ items }) {
|
|
349
|
+
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: items.map((a) => /* @__PURE__ */ jsxRuntime.jsxs(ui.Button, { size: "small", variant: "secondary", isLoading: a.loading, disabled: a.disabled, onClick: a.onClick, className: "whitespace-nowrap", children: [
|
|
350
|
+
a.icon,
|
|
351
|
+
a.label
|
|
352
|
+
] }, a.key)) });
|
|
361
353
|
}
|
|
362
|
-
function
|
|
354
|
+
function isWhiteLabel() {
|
|
355
|
+
var _a;
|
|
363
356
|
try {
|
|
364
|
-
return
|
|
357
|
+
return Boolean((_a = globalThis.__KODA_KIT__) == null ? void 0 : _a.whiteLabel);
|
|
365
358
|
} catch {
|
|
366
|
-
return
|
|
359
|
+
return false;
|
|
367
360
|
}
|
|
368
361
|
}
|
|
369
|
-
function
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
]
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
386
|
-
/* @__PURE__ */ jsxRuntime.
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
/* @__PURE__ */ jsxRuntime.
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
title: displayId ? `#${displayId}` : orderId,
|
|
413
|
-
mono: displayId ? orderId : null,
|
|
414
|
-
monoTitle: orderId,
|
|
415
|
-
action: t("store.openOrder")
|
|
416
|
-
}
|
|
417
|
-
);
|
|
418
|
-
}
|
|
419
|
-
function SubiektIcon({ width = 15, height = 15, ...props }) {
|
|
420
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
421
|
-
"svg",
|
|
422
|
-
{
|
|
423
|
-
width,
|
|
424
|
-
height,
|
|
425
|
-
viewBox: "0 0 192 192",
|
|
426
|
-
fill: "none",
|
|
427
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
428
|
-
"aria-hidden": "true",
|
|
429
|
-
...props,
|
|
430
|
-
children: [
|
|
431
|
-
/* @__PURE__ */ jsxRuntime.jsx("rect", { width: "192", height: "192", rx: "40", fill: "#0071B8" }),
|
|
432
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
433
|
-
"path",
|
|
434
|
-
{
|
|
435
|
-
fill: "#FFFFFF",
|
|
436
|
-
d: "M38.4 134.71L38.4 123.08Q40.4 124.84 43.19 126.25 45.98 127.66 49.06 128.63 52.15 129.6 55.26 130.13 58.37 130.66 61.02 130.66 70.12 130.66 74.62 127.28 79.11 123.9 79.11 117.56 79.11 114.15 77.61 111.63 76.12 109.1 73.47 107.02 70.83 104.93 67.21 103.02 63.6 101.11 59.43 99 55.03 96.76 51.21 94.47 47.39 92.18 44.57 89.42 41.75 86.66 40.13 83.16 38.52 79.67 38.52 74.97 38.52 69.21 41.04 64.95 43.57 60.69 47.68 57.93 51.79 55.17 57.05 53.82 62.31 52.47 67.77 52.47 80.23 52.47 85.93 55.47L85.93 66.57Q78.46 61.4 66.77 61.4 63.54 61.4 60.31 62.07 57.08 62.75 54.56 64.28 52.03 65.8 50.44 68.21 48.86 70.62 48.86 74.09 48.86 77.32 50.06 79.67 51.27 82.02 53.62 83.96 55.97 85.9 59.34 87.72 62.72 89.54 67.13 91.71 71.65 93.94 75.7 96.41 79.76 98.88 82.81 101.87 85.87 104.87 87.66 108.51 89.45 112.15 89.45 116.85 89.45 123.08 87.01 127.4 84.57 131.72 80.43 134.42 76.29 137.12 70.89 138.33 65.48 139.53 59.49 139.53 57.49 139.53 54.56 139.21 51.62 138.88 48.56 138.27 45.51 137.65 42.78 136.74 40.04 135.83 38.4 134.71M153.6 77.96L153.6 138.12 143.97 138.12 143.97 128.6 143.73 128.6Q137.74 139.53 125.17 139.53 103.67 139.53 103.67 113.92L103.67 77.96 113.24 77.96 113.24 112.39Q113.24 131.42 127.81 131.42 134.86 131.42 139.41 126.22 143.97 121.03 143.97 112.63L143.97 77.96"
|
|
437
|
-
}
|
|
438
|
-
)
|
|
439
|
-
]
|
|
440
|
-
}
|
|
441
|
-
);
|
|
442
|
-
}
|
|
443
|
-
const SubiektOrderWidget = ({ data }) => {
|
|
444
|
-
var _a, _b, _c, _d;
|
|
445
|
-
const { t, i18n } = reactI18next.useTranslation("subiekt");
|
|
446
|
-
const lang = i18n.language || "en";
|
|
447
|
-
const q = useSubiektOrder(data.id);
|
|
448
|
-
const send = useSubiektSendOrder(data.id);
|
|
449
|
-
const issue = useSubiektIssueDocument(data.id);
|
|
450
|
-
const retry = useSubiektRetry();
|
|
451
|
-
const documents = ((_a = q.data) == null ? void 0 : _a.documents) ?? [];
|
|
452
|
-
const tasks = ((_b = q.data) == null ? void 0 : _b.tasks) ?? [];
|
|
453
|
-
const sales = (_c = q.data) == null ? void 0 : _c.salesDocument;
|
|
454
|
-
const create = tasks.find((task) => task.kind === "order.create");
|
|
455
|
-
const documentTask = tasks.find((task) => task.kind === "order.document");
|
|
456
|
-
const hasZk = documents.some((d) => d.kind === "ZK" && d.status !== "canceled");
|
|
457
|
-
const hasSales = documents.some((d) => (d.kind === "FS" || d.kind === "PA") && d.status !== "canceled");
|
|
458
|
-
const busy = (create == null ? void 0 : create.status) === "pending" || (create == null ? void 0 : create.status) === "running";
|
|
459
|
-
const documentBusy = documentTask ? ["pending", "running", "unknown"].includes(documentTask.status) : false;
|
|
460
|
-
const canceled = data.status === "canceled";
|
|
461
|
-
const offerIssue = Boolean(sales && sales.option !== "none" && sales.supported && hasZk && !hasSales && !documentBusy && !canceled);
|
|
462
|
-
const onSend = async () => {
|
|
463
|
-
try {
|
|
464
|
-
await send.mutateAsync();
|
|
465
|
-
ui.toast.success(t("widget.sent"));
|
|
466
|
-
} catch (err) {
|
|
467
|
-
ui.toast.error(t("toast.error", { error: errorMessage(err) }));
|
|
468
|
-
}
|
|
469
|
-
};
|
|
470
|
-
const onIssue = async (kind) => {
|
|
471
|
-
try {
|
|
472
|
-
await issue.mutateAsync(kind);
|
|
473
|
-
ui.toast.success(t("widget.issued"));
|
|
474
|
-
} catch (err) {
|
|
475
|
-
ui.toast.error(t("toast.error", { error: errorMessage(err) }));
|
|
476
|
-
}
|
|
477
|
-
};
|
|
478
|
-
const onRetry = async (id) => {
|
|
479
|
-
try {
|
|
480
|
-
await retry.mutateAsync(id);
|
|
481
|
-
ui.toast.success(t("toast.retried"));
|
|
482
|
-
void q.refetch();
|
|
483
|
-
} catch (err) {
|
|
484
|
-
ui.toast.error(t("toast.error", { error: errorMessage(err) }));
|
|
485
|
-
}
|
|
486
|
-
};
|
|
487
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "divide-y p-0", children: [
|
|
488
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between px-6 py-4", children: [
|
|
489
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-2", children: [
|
|
490
|
-
/* @__PURE__ */ jsxRuntime.jsx(SubiektIcon, { width: 18, height: 18, className: "shrink-0" }),
|
|
491
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", children: t("widget.title") }),
|
|
492
|
-
((_d = q.data) == null ? void 0 : _d.mode) === "demo" ? /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { size: "2xsmall", color: "purple", children: t("widget.demo") }) : null
|
|
493
|
-
] }),
|
|
494
|
-
/* @__PURE__ */ jsxRuntime.jsx("a", { href: "/app/subiekt", className: "txt-compact-small text-ui-fg-interactive hover:text-ui-fg-interactive-hover", children: t("widget.more") })
|
|
495
|
-
] }),
|
|
496
|
-
q.isLoading ? null : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
497
|
-
documents.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-y-2 px-6 py-4", children: documents.map((d) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-x-2", children: [
|
|
498
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-col", children: [
|
|
499
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", className: "font-mono", children: d.number }),
|
|
500
|
-
/* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "xsmall", className: "text-ui-fg-muted", children: [
|
|
501
|
-
fmtDateTime(d.issuedAt, lang),
|
|
502
|
-
", ",
|
|
503
|
-
t(`documents.sources.${d.source}`, { defaultValue: d.source })
|
|
504
|
-
] }),
|
|
505
|
-
d.kind === "FS" && d.status !== "canceled" ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: d.ksefNumber ? "break-all font-mono text-ui-fg-subtle" : "text-ui-fg-muted", children: d.ksefNumber ? t("widget.ksef", { number: d.ksefNumber }) : t("widget.ksefWaiting") }) : null
|
|
506
|
-
] }),
|
|
507
|
-
/* @__PURE__ */ jsxRuntime.jsx(DocumentStatusBadge, { status: d.status })
|
|
508
|
-
] }, d.id)) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-6 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: (create == null ? void 0 : create.status) === "waiting" ? t("widget.waiting") : t("widget.none") }) }),
|
|
509
|
-
tasks.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-y-3 px-6 py-4", children: tasks.map((task) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-1", children: [
|
|
510
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-x-2", children: [
|
|
511
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", children: task.kind === "order.document" && (task.documentKind === "fs" || task.documentKind === "pa") ? t(`tasks.documentKinds.${task.documentKind}`) : t(`tasks.kinds.${task.kind}`) }),
|
|
512
|
-
/* @__PURE__ */ jsxRuntime.jsx(TaskStatusBadge, { status: task.status })
|
|
513
|
-
] }),
|
|
514
|
-
task.buyer ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-fg-subtle", children: task.buyer.source === "retail" ? t("tasks.buyer.retail") : t(`tasks.buyer.${task.buyer.source}`, { name: task.buyer.name ?? task.buyer.symbol ?? "?", nip: task.buyer.nip ?? "?" }) }) : null,
|
|
515
|
-
task.warnings.map((w) => /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-tag-orange-text", children: w }, w)),
|
|
516
|
-
task.lastError && task.status !== "succeeded" ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: task.status === "failed" ? "text-ui-tag-red-text" : "text-ui-fg-muted", children: task.lastError }) : null,
|
|
517
|
-
task.status === "unknown" ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-tag-orange-text", children: t("tasks.unknownHint") }) : null,
|
|
518
|
-
task.manualAction ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-tag-orange-text", children: t("tasks.manual") }) : null,
|
|
519
|
-
task.status === "failed" ? /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", isLoading: retry.isPending && retry.variables === task.id, onClick: () => onRetry(task.id), children: t("actions.retry") }) }) : null
|
|
520
|
-
] }, task.id)) }) : null,
|
|
521
|
-
!hasZk && !busy && !canceled && (create == null ? void 0 : create.status) !== "failed" ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-6 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", isLoading: send.isPending, onClick: onSend, children: t("widget.send") }) }) : null,
|
|
522
|
-
offerIssue && sales ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-2 px-6 py-4", children: [
|
|
523
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-fg-muted", children: sales.writerActive ? t("widget.autoOn", { after: sales.after.toUpperCase() }) : t("widget.autoOff") }),
|
|
524
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-2", children: [
|
|
525
|
-
sales.option === "fs" || sales.option === "auto" ? /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", isLoading: issue.isPending && issue.variables === "fs", onClick: () => onIssue("fs"), children: t("widget.issueFs") }) : null,
|
|
526
|
-
sales.option === "pa" || sales.option === "auto" ? /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", isLoading: issue.isPending && issue.variables === "pa", onClick: () => onIssue("pa"), children: t("widget.issuePa") }) : null
|
|
527
|
-
] })
|
|
528
|
-
] }) : null
|
|
529
|
-
] })
|
|
530
|
-
] });
|
|
531
|
-
};
|
|
532
|
-
adminSdk.defineWidgetConfig({
|
|
533
|
-
zone: "order.details.side.after"
|
|
534
|
-
});
|
|
535
|
-
const KIT_META = {
|
|
536
|
-
pkg: "@koda-plus/medusa-plugin-subiekt-nexo",
|
|
537
|
-
version: "0.2.1"
|
|
538
|
-
};
|
|
539
|
-
const NBSP = " ";
|
|
540
|
-
const NBHY = "‑";
|
|
541
|
-
const SHORT = /(^|[\s("„])(oraz|albo|lub|ale|że|bo|czy|gdy|aby|by|więc|jak|na|do|za|ze|we|od|po|to|[aiouwze])[ \t]+/gi;
|
|
542
|
-
function nb(text) {
|
|
543
|
-
let out = text;
|
|
544
|
-
for (let k = 0; k < 2; k++) out = out.replace(SHORT, `$1$2${NBSP}`);
|
|
545
|
-
out = out.replace(/(\d) (?=\d{3}\b)/g, `$1${NBSP}`);
|
|
546
|
-
out = out.replace(/\b([eE])-(?=mail)/g, `$1${NBHY}`);
|
|
547
|
-
return out.replace(/(\d) (zł|€|Kč|EUR|USD|PLN|CZK|mln|tys\.|cm|mm|m²|%)/g, `$1${NBSP}$2`);
|
|
548
|
-
}
|
|
549
|
-
function typeset(value) {
|
|
550
|
-
if (typeof value === "string") return nb(value);
|
|
551
|
-
if (Array.isArray(value)) return value.map((v) => typeset(v));
|
|
552
|
-
if (value && typeof value === "object") {
|
|
553
|
-
return Object.fromEntries(Object.entries(value).map(([k, v]) => [k, typeset(v)]));
|
|
554
|
-
}
|
|
555
|
-
return value;
|
|
556
|
-
}
|
|
557
|
-
function usePageNav(tabs) {
|
|
558
|
-
const [params, setParams] = reactRouterDom.useSearchParams();
|
|
559
|
-
const raw = params.get("view");
|
|
560
|
-
const view = raw === "guide" || raw === "settings" ? raw : "panel";
|
|
561
|
-
const asked = params.get("tab") ?? "";
|
|
562
|
-
const tab = tabs.includes(asked) ? asked : tabs[0];
|
|
563
|
-
const go = (next, nextTab) => {
|
|
564
|
-
const p = new URLSearchParams(params);
|
|
565
|
-
if (next === "panel") p.delete("view");
|
|
566
|
-
else p.set("view", next);
|
|
567
|
-
if (next === "settings") p.set("tab", nextTab ?? tab);
|
|
568
|
-
else p.delete("tab");
|
|
569
|
-
setParams(p, { replace: true });
|
|
570
|
-
};
|
|
571
|
-
return { view, tab, go };
|
|
572
|
-
}
|
|
573
|
-
const VIEWS = ["panel", "guide", "settings"];
|
|
574
|
-
const VIEW_ICON = { panel: /* @__PURE__ */ jsxRuntime.jsx(icons.ChartBar, {}), guide: /* @__PURE__ */ jsxRuntime.jsx(icons.BookOpen, {}), settings: /* @__PURE__ */ jsxRuntime.jsx(icons.CogSixTooth, {}) };
|
|
575
|
-
function PageTabs({ value, onChange, labels }) {
|
|
576
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { role: "tablist", className: "flex flex-wrap items-center gap-1", children: VIEWS.map((v) => {
|
|
577
|
-
const on = v === value;
|
|
578
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
579
|
-
"button",
|
|
580
|
-
{
|
|
581
|
-
type: "button",
|
|
582
|
-
role: "tab",
|
|
583
|
-
"aria-selected": on,
|
|
584
|
-
onClick: () => onChange(v),
|
|
585
|
-
className: ui.clx(
|
|
586
|
-
"txt-compact-small-plus inline-flex items-center gap-x-1.5 rounded-md px-2.5 py-1.5 outline-none transition-fg focus-visible:shadow-borders-focus",
|
|
587
|
-
on ? "bg-ui-bg-base text-ui-fg-base shadow-borders-base" : "text-ui-fg-subtle hover:bg-ui-bg-base-hover hover:text-ui-fg-base"
|
|
588
|
-
),
|
|
589
|
-
children: [
|
|
590
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: ui.clx("flex", on ? "text-ui-fg-interactive" : "text-ui-fg-muted"), children: VIEW_ICON[v] }),
|
|
591
|
-
labels[v]
|
|
592
|
-
]
|
|
593
|
-
},
|
|
594
|
-
v
|
|
595
|
-
);
|
|
596
|
-
}) });
|
|
597
|
-
}
|
|
598
|
-
function OtherActions({ items, label }) {
|
|
599
|
-
if (items.length === 1) {
|
|
600
|
-
const a = items[0];
|
|
601
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(ui.Button, { size: "small", variant: "secondary", isLoading: a.loading, disabled: a.disabled, onClick: a.onClick, children: [
|
|
602
|
-
a.icon,
|
|
603
|
-
a.label
|
|
604
|
-
] });
|
|
605
|
-
}
|
|
606
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu, { children: [
|
|
607
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Button, { size: "small", variant: "secondary", children: [
|
|
608
|
-
label,
|
|
609
|
-
/* @__PURE__ */ jsxRuntime.jsx(icons.ChevronDownMini, {})
|
|
610
|
-
] }) }),
|
|
611
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenu.Content, { align: "end", children: items.map((a) => /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu.Item, { disabled: a.disabled || a.loading, onClick: a.onClick, className: "gap-x-2", children: [
|
|
612
|
-
a.icon,
|
|
613
|
-
a.label
|
|
614
|
-
] }, a.key)) })
|
|
615
|
-
] });
|
|
616
|
-
}
|
|
617
|
-
function IntegrationHeader({
|
|
618
|
-
icon,
|
|
619
|
-
title,
|
|
620
|
-
by,
|
|
621
|
-
badges,
|
|
622
|
-
description,
|
|
623
|
-
social,
|
|
624
|
-
help,
|
|
625
|
-
view,
|
|
626
|
-
onView,
|
|
627
|
-
labels,
|
|
628
|
-
primary,
|
|
629
|
-
actions = []
|
|
630
|
-
}) {
|
|
631
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
|
|
632
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-3 px-6 pb-5 pt-5", children: [
|
|
633
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 lg:flex-row lg:items-start lg:justify-between", children: [
|
|
634
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-wrap items-center gap-x-2.5 gap-y-1.5", children: [
|
|
635
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex shrink-0", children: icon }),
|
|
636
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: title }),
|
|
637
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: by }),
|
|
638
|
-
badges ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex flex-wrap items-center gap-1.5", children: badges }) : null
|
|
639
|
-
] }),
|
|
640
|
-
help ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex shrink-0", children: help }) : null
|
|
641
|
-
] }),
|
|
642
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "max-w-3xl text-ui-fg-subtle", children: description }),
|
|
643
|
-
social ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap items-center gap-2 pt-0.5", children: social }) : null
|
|
644
|
-
] }),
|
|
645
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 border-t border-ui-border-base bg-ui-bg-subtle px-6 py-2.5 md:flex-row md:items-center md:justify-between", children: [
|
|
646
|
-
/* @__PURE__ */ jsxRuntime.jsx(PageTabs, { value: view, onChange: onView, labels }),
|
|
647
|
-
primary || actions.length ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
648
|
-
actions.length ? /* @__PURE__ */ jsxRuntime.jsx(OtherActions, { items: actions, label: labels.more }) : null,
|
|
649
|
-
primary ? /* @__PURE__ */ jsxRuntime.jsxs(ui.Button, { size: "small", variant: "primary", isLoading: primary.loading, disabled: primary.disabled, onClick: primary.onClick, children: [
|
|
650
|
-
primary.icon,
|
|
651
|
-
primary.label
|
|
652
|
-
] }) : null
|
|
653
|
-
] }) : null
|
|
654
|
-
] })
|
|
655
|
-
] });
|
|
362
|
+
function IntegrationHeader({
|
|
363
|
+
icon,
|
|
364
|
+
title,
|
|
365
|
+
badges,
|
|
366
|
+
featured,
|
|
367
|
+
description,
|
|
368
|
+
points,
|
|
369
|
+
social,
|
|
370
|
+
help,
|
|
371
|
+
view,
|
|
372
|
+
onView,
|
|
373
|
+
labels,
|
|
374
|
+
primary,
|
|
375
|
+
actions = []
|
|
376
|
+
}) {
|
|
377
|
+
const plain2 = isWhiteLabel();
|
|
378
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
|
|
379
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-3 px-6 pb-5 pt-5", children: [
|
|
380
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 lg:flex-row lg:items-start lg:justify-between", children: [
|
|
381
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-wrap items-center gap-x-2.5 gap-y-1.5", children: [
|
|
382
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex shrink-0", children: icon }),
|
|
383
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: title }),
|
|
384
|
+
featured && !plain2 || badges ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex flex-wrap items-center gap-1.5", children: [
|
|
385
|
+
featured && !plain2 ? /* @__PURE__ */ jsxRuntime.jsx(FeaturedBadge, { url: featured.url, labels: featured.labels }) : null,
|
|
386
|
+
badges
|
|
387
|
+
] }) : null
|
|
388
|
+
] }),
|
|
389
|
+
help && !plain2 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex shrink-0", children: help }) : null
|
|
390
|
+
] }),
|
|
391
|
+
points && points.some(Boolean) ? /* @__PURE__ */ jsxRuntime.jsx(KeyPoints, { items: points, label: description }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "max-w-3xl text-ui-fg-subtle", children: description }),
|
|
392
|
+
social && !plain2 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap items-center gap-2 pt-0.5", children: social }) : null
|
|
393
|
+
] }),
|
|
394
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 border-t border-ui-border-base bg-ui-bg-subtle px-6 py-2.5 md:flex-row md:items-center md:justify-between", children: [
|
|
395
|
+
/* @__PURE__ */ jsxRuntime.jsx(PageTabs, { value: view, onChange: onView, labels }),
|
|
396
|
+
primary || actions.length ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
397
|
+
actions.length ? /* @__PURE__ */ jsxRuntime.jsx(OtherActions, { items: actions, label: labels.more }) : null,
|
|
398
|
+
primary ? /* @__PURE__ */ jsxRuntime.jsxs(ui.Button, { size: "small", variant: "primary", isLoading: primary.loading, disabled: primary.disabled, onClick: primary.onClick, children: [
|
|
399
|
+
primary.icon,
|
|
400
|
+
primary.label
|
|
401
|
+
] }) : null
|
|
402
|
+
] }) : null
|
|
403
|
+
] })
|
|
404
|
+
] });
|
|
656
405
|
}
|
|
657
406
|
function ModeBadge({ color, label, title, children }) {
|
|
658
407
|
if (!children) return /* @__PURE__ */ jsxRuntime.jsx(ui.StatusBadge, { color, children: label });
|
|
@@ -667,149 +416,31 @@ function ModeBadge({ color, label, title, children }) {
|
|
|
667
416
|
] })
|
|
668
417
|
] });
|
|
669
418
|
}
|
|
670
|
-
function
|
|
671
|
-
return
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
function Stars({ rating, scale = 5, size = 12 }) {
|
|
685
|
-
const fill = Math.max(0, Math.min(1, rating / (scale || 5))) * 100;
|
|
686
|
-
const row = (color) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex gap-x-px", style: { color }, children: [0, 1, 2, 3, 4].map((i) => /* @__PURE__ */ jsxRuntime.jsx("svg", { width: size, height: size, viewBox: "0 0 20 20", "aria-hidden": true, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: STAR, fill: "currentColor" }) }, i)) });
|
|
687
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "relative inline-flex shrink-0", "aria-hidden": true, children: [
|
|
688
|
-
row("var(--fg-disabled)"),
|
|
689
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute inset-y-0 left-0 overflow-hidden", style: { width: `${fill}%` }, children: row("#F5A524") })
|
|
690
|
-
] });
|
|
691
|
-
}
|
|
692
|
-
function SourceMark({ review, height = 10 }) {
|
|
693
|
-
if (!review.icon) {
|
|
694
|
-
return /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", weight: "plus", className: "text-ui-fg-subtle", children: review.source });
|
|
695
|
-
}
|
|
696
|
-
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-flex shrink-0 items-center rounded-full bg-white px-2 py-1 shadow-borders-base", children: /* @__PURE__ */ jsxRuntime.jsx("img", { src: review.icon, alt: review.source, style: { height, width: "auto" } }) });
|
|
697
|
-
}
|
|
698
|
-
function StoreIcon({ reference, size }) {
|
|
699
|
-
const box = { width: size, height: size };
|
|
700
|
-
return reference.icon ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: reference.icon, alt: "", width: size, height: size, style: box, className: "shrink-0 rounded-md bg-white object-contain shadow-borders-base" }) : /* @__PURE__ */ jsxRuntime.jsx("span", { style: box, className: "txt-compact-xsmall-plus flex shrink-0 items-center justify-center rounded-md bg-ui-bg-base text-ui-fg-base shadow-borders-base", children: reference.name.slice(0, 1).toUpperCase() });
|
|
701
|
-
}
|
|
702
|
-
function meanRating(items) {
|
|
703
|
-
const reviews = items.map((r) => r.review).filter((r) => Boolean(r));
|
|
704
|
-
if (reviews.length === 0) return null;
|
|
705
|
-
const value = reviews.reduce((sum, r) => sum + r.rating / (r.scale || 5) * 5, 0) / reviews.length;
|
|
706
|
-
return { value: Math.round(value * 10) / 10, first: reviews[0] };
|
|
707
|
-
}
|
|
708
|
-
function ReferencesBadge({ items, labels }) {
|
|
709
|
-
const { live, soon } = splitReferences(items);
|
|
710
|
-
if (live.length + soon.length === 0) return null;
|
|
711
|
-
const mean = meanRating(live);
|
|
712
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(ui.Popover, { children: [
|
|
713
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Popover.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
714
|
-
"button",
|
|
715
|
-
{
|
|
716
|
-
type: "button",
|
|
717
|
-
className: "inline-flex h-9 max-w-full items-center gap-x-3 rounded-full border border-ui-border-base bg-ui-bg-component py-1 pl-1.5 pr-3 outline-none transition-fg hover:bg-ui-bg-component-hover focus-visible:shadow-borders-focus",
|
|
718
|
-
children: [
|
|
719
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex shrink-0 items-center", children: [...live, ...soon].slice(0, 3).map((r, i) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: ui.clx("rounded-md", i > 0 && "-ml-2", r.soon && "opacity-50"), children: /* @__PURE__ */ jsxRuntime.jsx(StoreIcon, { reference: r, size: 24 }) }, r.url ?? r.name)) }),
|
|
720
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex min-w-0 items-center gap-x-1.5", children: [
|
|
721
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "txt-compact-small-plus truncate text-ui-fg-base", children: labels.count(live.length, soon.length) }),
|
|
722
|
-
live.length > 0 && soon.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "txt-compact-small shrink-0 text-ui-fg-muted", children: labels.soonMore(soon.length) }) : null
|
|
723
|
-
] }),
|
|
724
|
-
mean ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex shrink-0 items-center gap-x-2 border-l border-ui-border-base pl-3", children: [
|
|
725
|
-
/* @__PURE__ */ jsxRuntime.jsx(Stars, { rating: mean.value, size: 13 }),
|
|
726
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "txt-compact-small-plus tabular-nums text-ui-fg-base", children: labels.rating(mean.value) }),
|
|
727
|
-
/* @__PURE__ */ jsxRuntime.jsx(SourceMark, { review: mean.first, height: 10 })
|
|
728
|
-
] }) : null,
|
|
729
|
-
/* @__PURE__ */ jsxRuntime.jsx(icons.ChevronDownMini, { className: "-ml-1 shrink-0 text-ui-fg-muted" })
|
|
730
|
-
]
|
|
731
|
-
}
|
|
732
|
-
) }),
|
|
733
|
-
/* @__PURE__ */ jsxRuntime.jsxs(ui.Popover.Content, { align: "start", sideOffset: 8, className: "w-[min(460px,calc(100vw-32px))] p-0", children: [
|
|
734
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-0.5 border-b border-ui-border-base px-4 py-3", children: [
|
|
735
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", className: "text-ui-fg-base", children: labels.title }),
|
|
736
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-fg-subtle", children: labels.subtitle })
|
|
737
|
-
] }),
|
|
738
|
-
/* @__PURE__ */ jsxRuntime.jsxs("ul", { className: "flex max-h-[60vh] flex-col divide-y divide-ui-border-base overflow-y-auto", children: [
|
|
739
|
-
live.map((r) => {
|
|
740
|
-
var _a, _b;
|
|
741
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("li", { className: "flex flex-col gap-y-2 px-4 py-3", children: [
|
|
742
|
-
/* @__PURE__ */ jsxRuntime.jsxs("a", { href: r.url, target: "_blank", rel: "noreferrer", className: "group flex items-center gap-x-3", children: [
|
|
743
|
-
/* @__PURE__ */ jsxRuntime.jsx(StoreIcon, { reference: r, size: 32 }),
|
|
744
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex min-w-0 flex-col", children: [
|
|
745
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", className: "truncate text-ui-fg-base", children: r.name }),
|
|
746
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "truncate text-ui-fg-interactive group-hover:text-ui-fg-interactive-hover", children: host(r.url) })
|
|
747
|
-
] }),
|
|
748
|
-
/* @__PURE__ */ jsxRuntime.jsx(icons.ArrowUpRightOnBox, { className: "ml-auto shrink-0 text-ui-fg-muted group-hover:text-ui-fg-interactive" })
|
|
749
|
-
] }),
|
|
750
|
-
r.review ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-x-2 gap-y-1", children: [
|
|
751
|
-
/* @__PURE__ */ jsxRuntime.jsx(Stars, { rating: r.review.rating, scale: r.review.scale }),
|
|
752
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "txt-compact-xsmall-plus tabular-nums text-ui-fg-base", children: labels.rating(r.review.rating / (r.review.scale || 5) * 5) }),
|
|
753
|
-
/* @__PURE__ */ jsxRuntime.jsx(SourceMark, { review: r.review }),
|
|
754
|
-
r.review.url ? /* @__PURE__ */ jsxRuntime.jsxs("a", { href: r.review.url, target: "_blank", rel: "noreferrer", className: "txt-compact-xsmall-plus inline-flex items-center gap-x-0.5 text-ui-fg-interactive hover:text-ui-fg-interactive-hover", children: [
|
|
755
|
-
labels.review,
|
|
756
|
-
/* @__PURE__ */ jsxRuntime.jsx(icons.ArrowUpRightOnBox, { className: "h-3.5 w-3.5" })
|
|
757
|
-
] }) : null
|
|
758
|
-
] }) : null,
|
|
759
|
-
((_a = r.review) == null ? void 0 : _a.quote) ? /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "xsmall", className: "border-l-2 border-ui-border-strong pl-2 italic text-ui-fg-subtle", children: [
|
|
760
|
-
nb(r.review.quote),
|
|
761
|
-
r.review.author ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "not-italic text-ui-fg-muted", children: [
|
|
762
|
-
" ",
|
|
763
|
-
r.review.author
|
|
764
|
-
] }) : null
|
|
765
|
-
] }) : null,
|
|
766
|
-
r.description ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-fg-subtle", children: nb(r.description) }) : null,
|
|
767
|
-
((_b = r.metrics) == null ? void 0 : _b.length) ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap items-center gap-1.5", children: (r.metrics ?? []).map((m) => /* @__PURE__ */ jsxRuntime.jsxs(ui.Badge, { size: "2xsmall", color: "green", children: [
|
|
768
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "tabular-nums", children: m.value }),
|
|
769
|
-
" ",
|
|
770
|
-
m.label
|
|
771
|
-
] }, m.label)) }) : null,
|
|
772
|
-
(r.links ?? []).length ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-x-3 gap-y-1", children: (r.links ?? []).map((l) => /* @__PURE__ */ jsxRuntime.jsxs("a", { href: l.url, target: "_blank", rel: "noreferrer", className: "txt-compact-xsmall-plus inline-flex items-center gap-x-0.5 text-ui-fg-interactive hover:text-ui-fg-interactive-hover", children: [
|
|
773
|
-
l.label,
|
|
774
|
-
/* @__PURE__ */ jsxRuntime.jsx(icons.ArrowUpRightOnBox, { className: "h-3.5 w-3.5" })
|
|
775
|
-
] }, l.url)) }) : null
|
|
776
|
-
] }, r.url ?? r.name);
|
|
777
|
-
}),
|
|
778
|
-
soon.map((r) => /* @__PURE__ */ jsxRuntime.jsxs("li", { className: "flex flex-col gap-y-2 px-4 py-3", children: [
|
|
779
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-3", children: [
|
|
780
|
-
/* @__PURE__ */ jsxRuntime.jsx(StoreIcon, { reference: r, size: 32 }),
|
|
781
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex min-w-0 items-center gap-x-2", children: [
|
|
782
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", className: "truncate text-ui-fg-base", children: r.name }),
|
|
783
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { size: "2xsmall", color: "blue", className: "shrink-0", children: labels.soon })
|
|
784
|
-
] })
|
|
785
|
-
] }),
|
|
786
|
-
r.description ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-fg-subtle", children: nb(r.description) }) : null
|
|
787
|
-
] }, r.url ?? r.name))
|
|
419
|
+
function FeaturedBadge({ url, labels }) {
|
|
420
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
421
|
+
"a",
|
|
422
|
+
{
|
|
423
|
+
href: url,
|
|
424
|
+
target: "_blank",
|
|
425
|
+
rel: "noopener noreferrer",
|
|
426
|
+
title: labels.title,
|
|
427
|
+
"aria-label": `${labels.badge}. ${labels.title}`,
|
|
428
|
+
className: "inline-flex rounded-full outline-none transition-fg hover:opacity-80 focus-visible:shadow-borders-focus",
|
|
429
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Badge, { size: "2xsmall", rounded: "full", color: "green", className: "cursor-pointer gap-x-1", children: [
|
|
430
|
+
/* @__PURE__ */ jsxRuntime.jsx(icons.Medusa, { className: "h-3 w-3" }),
|
|
431
|
+
labels.badge,
|
|
432
|
+
/* @__PURE__ */ jsxRuntime.jsx(icons.ArrowUpRightOnBox, { className: "h-3 w-3 opacity-70" })
|
|
788
433
|
] })
|
|
789
|
-
|
|
790
|
-
|
|
434
|
+
}
|
|
435
|
+
);
|
|
791
436
|
}
|
|
792
437
|
const KODA_DISCORD = "https://koda.plus/discord";
|
|
793
438
|
const KODA_EMAIL = "hello@koda.plus";
|
|
794
439
|
const KODA_DEMO = "https://medusa.koda.plus";
|
|
795
440
|
const plain = (text) => text.split(NBSP).join(" ");
|
|
796
|
-
function communityLabels(t,
|
|
441
|
+
function communityLabels(t, _integration) {
|
|
797
442
|
const k = (key, options) => t(`community.${key}`, options);
|
|
798
443
|
return {
|
|
799
|
-
addStore: {
|
|
800
|
-
button: k("addStore.button"),
|
|
801
|
-
title: k("addStore.title"),
|
|
802
|
-
text: k("addStore.text"),
|
|
803
|
-
name: k("addStore.name"),
|
|
804
|
-
url: k("addStore.url"),
|
|
805
|
-
note: k("addStore.note"),
|
|
806
|
-
send: k("addStore.send"),
|
|
807
|
-
copy: k("addStore.copy"),
|
|
808
|
-
copied: k("addStore.copied"),
|
|
809
|
-
hint: k("addStore.hint", { email: KODA_EMAIL }),
|
|
810
|
-
subject: k("addStore.subject", { integration }),
|
|
811
|
-
greeting: k("addStore.greeting", { integration })
|
|
812
|
-
},
|
|
813
444
|
prompt: {
|
|
814
445
|
button: k("prompt.button"),
|
|
815
446
|
title: k("prompt.title"),
|
|
@@ -818,79 +449,10 @@ function communityLabels(t, integration) {
|
|
|
818
449
|
copied: k("prompt.copied"),
|
|
819
450
|
failed: k("prompt.failed")
|
|
820
451
|
},
|
|
821
|
-
discord: { button: k("discord.button"), title: k("discord.title") }
|
|
452
|
+
discord: { button: k("discord.button"), title: k("discord.title") },
|
|
453
|
+
featured: { badge: k("featured.badge"), title: k("featured.title") }
|
|
822
454
|
};
|
|
823
455
|
}
|
|
824
|
-
function AddStoreButton({ labels }) {
|
|
825
|
-
const [name, setName] = react.useState("");
|
|
826
|
-
const [url, setUrl] = react.useState("");
|
|
827
|
-
const [note, setNote] = react.useState("");
|
|
828
|
-
const ready = name.trim() !== "" && url.trim() !== "";
|
|
829
|
-
const subject = plain(labels.subject);
|
|
830
|
-
const body = plain(
|
|
831
|
-
[labels.greeting, "", `${labels.name}: ${name.trim()}`, `${labels.url}: ${url.trim()}`, ...note.trim() ? ["", note.trim()] : []].join("\n")
|
|
832
|
-
);
|
|
833
|
-
const send = () => {
|
|
834
|
-
window.location.href = `mailto:${KODA_EMAIL}?subject=${encodeURIComponent(subject)}&body=${encodeURIComponent(body)}`;
|
|
835
|
-
};
|
|
836
|
-
const copy = async () => {
|
|
837
|
-
try {
|
|
838
|
-
await navigator.clipboard.writeText(`${KODA_EMAIL}
|
|
839
|
-
${subject}
|
|
840
|
-
|
|
841
|
-
${body}`);
|
|
842
|
-
ui.toast.success(labels.copied);
|
|
843
|
-
} catch {
|
|
844
|
-
ui.toast.error(KODA_EMAIL);
|
|
845
|
-
}
|
|
846
|
-
};
|
|
847
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(ui.Popover, { children: [
|
|
848
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Popover.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
849
|
-
"button",
|
|
850
|
-
{
|
|
851
|
-
type: "button",
|
|
852
|
-
className: "txt-compact-small-plus inline-flex h-9 items-center gap-x-1.5 rounded-full px-3 text-ui-fg-subtle outline-none transition-fg hover:bg-ui-bg-base-hover hover:text-ui-fg-base focus-visible:shadow-borders-focus",
|
|
853
|
-
children: [
|
|
854
|
-
/* @__PURE__ */ jsxRuntime.jsx(icons.PlusMini, {}),
|
|
855
|
-
labels.button
|
|
856
|
-
]
|
|
857
|
-
}
|
|
858
|
-
) }),
|
|
859
|
-
/* @__PURE__ */ jsxRuntime.jsxs(ui.Popover.Content, { align: "start", sideOffset: 8, className: "w-[min(420px,calc(100vw-32px))] p-0", children: [
|
|
860
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-1 border-b border-ui-border-base px-4 py-3", children: [
|
|
861
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", className: "text-ui-fg-base", children: labels.title }),
|
|
862
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-fg-subtle", children: labels.text })
|
|
863
|
-
] }),
|
|
864
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-3 px-4 py-4", children: [
|
|
865
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-1.5", children: [
|
|
866
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Label, { size: "xsmall", weight: "plus", htmlFor: "koda-add-store-name", children: labels.name }),
|
|
867
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Input, { id: "koda-add-store-name", size: "small", value: name, onChange: (e) => setName(e.target.value) })
|
|
868
|
-
] }),
|
|
869
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-1.5", children: [
|
|
870
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Label, { size: "xsmall", weight: "plus", htmlFor: "koda-add-store-url", children: labels.url }),
|
|
871
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Input, { id: "koda-add-store-url", size: "small", type: "url", placeholder: "https://", value: url, onChange: (e) => setUrl(e.target.value) })
|
|
872
|
-
] }),
|
|
873
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-1.5", children: [
|
|
874
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Label, { size: "xsmall", weight: "plus", htmlFor: "koda-add-store-note", children: labels.note }),
|
|
875
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Textarea, { id: "koda-add-store-note", rows: 3, value: note, onChange: (e) => setNote(e.target.value) })
|
|
876
|
-
] })
|
|
877
|
-
] }),
|
|
878
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-3 border-t border-ui-border-base px-4 py-3", children: [
|
|
879
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-fg-muted", children: labels.hint }),
|
|
880
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center justify-end gap-2", children: [
|
|
881
|
-
/* @__PURE__ */ jsxRuntime.jsxs(ui.Button, { size: "small", variant: "secondary", disabled: !ready, onClick: () => void copy(), children: [
|
|
882
|
-
/* @__PURE__ */ jsxRuntime.jsx(icons.SquareTwoStack, {}),
|
|
883
|
-
labels.copy
|
|
884
|
-
] }),
|
|
885
|
-
/* @__PURE__ */ jsxRuntime.jsxs(ui.Button, { size: "small", variant: "primary", disabled: !ready, onClick: send, children: [
|
|
886
|
-
/* @__PURE__ */ jsxRuntime.jsx(icons.PaperPlane, {}),
|
|
887
|
-
labels.send
|
|
888
|
-
] })
|
|
889
|
-
] })
|
|
890
|
-
] })
|
|
891
|
-
] })
|
|
892
|
-
] });
|
|
893
|
-
}
|
|
894
456
|
function envNames(code) {
|
|
895
457
|
const names = /* @__PURE__ */ new Set();
|
|
896
458
|
for (const m of code.matchAll(/process\.env\.([A-Z][A-Z0-9_]*)/g)) names.add(m[1]);
|
|
@@ -1061,69 +623,6 @@ function SettingsView({
|
|
|
1061
623
|
children
|
|
1062
624
|
] });
|
|
1063
625
|
}
|
|
1064
|
-
function CardIcon({ reference }) {
|
|
1065
|
-
return reference.icon ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: reference.icon, alt: "", width: 36, height: 36, className: "h-9 w-9 shrink-0 rounded-md bg-white object-contain shadow-borders-base" }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "txt-compact-medium-plus flex h-9 w-9 shrink-0 items-center justify-center rounded-md bg-ui-bg-base text-ui-fg-base shadow-borders-base", children: reference.name.slice(0, 1).toUpperCase() });
|
|
1066
|
-
}
|
|
1067
|
-
function References({ items, title, subtitle, openLabel, soonLabel, reviewLabel, ratingLabel }) {
|
|
1068
|
-
const { live, soon } = splitReferences(items);
|
|
1069
|
-
if (live.length + soon.length === 0) return null;
|
|
1070
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "divide-y p-0", children: [
|
|
1071
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-1 px-6 py-4", children: [
|
|
1072
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", children: title }),
|
|
1073
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: subtitle })
|
|
1074
|
-
] }),
|
|
1075
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 gap-3 px-6 py-4 md:grid-cols-2 xl:grid-cols-3", children: [
|
|
1076
|
-
live.map((r) => {
|
|
1077
|
-
var _a;
|
|
1078
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-3 rounded-lg border border-ui-border-base bg-ui-bg-component px-4 py-3", children: [
|
|
1079
|
-
/* @__PURE__ */ jsxRuntime.jsxs("a", { href: r.url, target: "_blank", rel: "noreferrer", className: "group flex items-center gap-x-3", children: [
|
|
1080
|
-
/* @__PURE__ */ jsxRuntime.jsx(CardIcon, { reference: r }),
|
|
1081
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex min-w-0 flex-col", children: [
|
|
1082
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", className: "truncate text-ui-fg-base", children: r.name }),
|
|
1083
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "truncate text-ui-fg-interactive group-hover:text-ui-fg-interactive-hover", children: host(r.url) })
|
|
1084
|
-
] }),
|
|
1085
|
-
/* @__PURE__ */ jsxRuntime.jsx(icons.ArrowUpRightOnBox, { className: "ml-auto shrink-0 text-ui-fg-muted group-hover:text-ui-fg-interactive" })
|
|
1086
|
-
] }),
|
|
1087
|
-
r.review ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-x-2 gap-y-1", children: [
|
|
1088
|
-
/* @__PURE__ */ jsxRuntime.jsx(Stars, { rating: r.review.rating, scale: r.review.scale }),
|
|
1089
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "txt-compact-xsmall-plus tabular-nums text-ui-fg-base", children: (ratingLabel ?? ((v) => v.toFixed(1)))(r.review.rating / (r.review.scale || 5) * 5) }),
|
|
1090
|
-
/* @__PURE__ */ jsxRuntime.jsx(SourceMark, { review: r.review }),
|
|
1091
|
-
r.review.url && reviewLabel ? /* @__PURE__ */ jsxRuntime.jsxs("a", { href: r.review.url, target: "_blank", rel: "noreferrer", className: "txt-compact-xsmall-plus inline-flex items-center gap-x-0.5 text-ui-fg-interactive hover:text-ui-fg-interactive-hover", children: [
|
|
1092
|
-
reviewLabel,
|
|
1093
|
-
/* @__PURE__ */ jsxRuntime.jsx(icons.ArrowUpRightOnBox, { className: "h-3.5 w-3.5" })
|
|
1094
|
-
] }) : null
|
|
1095
|
-
] }) : null,
|
|
1096
|
-
r.description ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: nb(r.description) }) : null,
|
|
1097
|
-
((_a = r.metrics) == null ? void 0 : _a.length) ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap items-center gap-2", children: (r.metrics ?? []).map((m) => /* @__PURE__ */ jsxRuntime.jsxs(ui.Badge, { size: "2xsmall", color: "green", children: [
|
|
1098
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "tabular-nums", children: m.value }),
|
|
1099
|
-
" ",
|
|
1100
|
-
m.label
|
|
1101
|
-
] }, m.label)) }) : null,
|
|
1102
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-auto flex flex-col gap-y-1 border-t border-ui-border-base pt-2", children: [
|
|
1103
|
-
(r.links ?? []).map((l) => /* @__PURE__ */ jsxRuntime.jsxs("a", { href: l.url, target: "_blank", rel: "noreferrer", className: "txt-compact-small inline-flex w-fit items-center gap-x-1 text-ui-fg-interactive hover:text-ui-fg-interactive-hover", children: [
|
|
1104
|
-
l.label,
|
|
1105
|
-
/* @__PURE__ */ jsxRuntime.jsx(icons.ArrowUpRightOnBox, { className: "shrink-0" })
|
|
1106
|
-
] }, l.url)),
|
|
1107
|
-
/* @__PURE__ */ jsxRuntime.jsxs("a", { href: r.url, target: "_blank", rel: "noreferrer", className: "txt-compact-small-plus inline-flex w-fit items-center gap-x-1 text-ui-fg-interactive hover:text-ui-fg-interactive-hover", children: [
|
|
1108
|
-
openLabel,
|
|
1109
|
-
/* @__PURE__ */ jsxRuntime.jsx(icons.ArrowUpRightOnBox, { className: "shrink-0" })
|
|
1110
|
-
] })
|
|
1111
|
-
] })
|
|
1112
|
-
] }, r.url ?? r.name);
|
|
1113
|
-
}),
|
|
1114
|
-
soon.map((r) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-3 rounded-lg border border-ui-border-base bg-ui-bg-component px-4 py-3", children: [
|
|
1115
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-3", children: [
|
|
1116
|
-
/* @__PURE__ */ jsxRuntime.jsx(CardIcon, { reference: r }),
|
|
1117
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex min-w-0 items-center gap-x-2", children: [
|
|
1118
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", className: "truncate text-ui-fg-base", children: r.name }),
|
|
1119
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { size: "2xsmall", color: "blue", className: "shrink-0", children: soonLabel })
|
|
1120
|
-
] })
|
|
1121
|
-
] }),
|
|
1122
|
-
r.description ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: nb(r.description) }) : null
|
|
1123
|
-
] }, r.url ?? r.name))
|
|
1124
|
-
] })
|
|
1125
|
-
] });
|
|
1126
|
-
}
|
|
1127
626
|
function GuideIntro({ title, text, time, needs, needsLabel, timeLabel }) {
|
|
1128
627
|
return /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "divide-y p-0", children: [
|
|
1129
628
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-2 px-6 py-4", children: [
|
|
@@ -1285,10 +784,834 @@ function GuideFaq({ title, items }) {
|
|
|
1285
784
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", className: "text-ui-fg-base", children: it.q }),
|
|
1286
785
|
/* @__PURE__ */ jsxRuntime.jsx(icons.ChevronDownMini, { className: ui.clx("shrink-0 text-ui-fg-muted transition-transform", open === i && "rotate-180") })
|
|
1287
786
|
] }),
|
|
1288
|
-
open === i ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "txt-small flex max-w-3xl flex-col gap-y-2 pb-4 text-ui-fg-subtle", children: it.a }) : null
|
|
1289
|
-
] }, it.q))
|
|
1290
|
-
] });
|
|
1291
|
-
}
|
|
787
|
+
open === i ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "txt-small flex max-w-3xl flex-col gap-y-2 pb-4 text-ui-fg-subtle", children: it.a }) : null
|
|
788
|
+
] }, it.q))
|
|
789
|
+
] });
|
|
790
|
+
}
|
|
791
|
+
const TEXT$1 = {
|
|
792
|
+
en: {
|
|
793
|
+
search: "Search",
|
|
794
|
+
empty: "Nothing here yet",
|
|
795
|
+
now: "Now",
|
|
796
|
+
next: "In a moment",
|
|
797
|
+
counted: "Done",
|
|
798
|
+
stopped: "Stopped",
|
|
799
|
+
queued: "Waiting for a free slot on the server",
|
|
800
|
+
ready: "Ready",
|
|
801
|
+
error: "Error",
|
|
802
|
+
pctDone: "done",
|
|
803
|
+
pctError: "error",
|
|
804
|
+
pctQueued: "queued",
|
|
805
|
+
pctRunning: "working",
|
|
806
|
+
running: (time) => `running ${time}`,
|
|
807
|
+
left: (time) => `about ${time} left`,
|
|
808
|
+
clean: "no errors",
|
|
809
|
+
of: "of",
|
|
810
|
+
waiting: "waiting",
|
|
811
|
+
log: "Log",
|
|
812
|
+
retry: "Try again"
|
|
813
|
+
},
|
|
814
|
+
pl: {
|
|
815
|
+
search: "Szukaj",
|
|
816
|
+
empty: "Na razie pusto",
|
|
817
|
+
now: "Teraz",
|
|
818
|
+
next: "Za chwilę",
|
|
819
|
+
counted: "Gotowe",
|
|
820
|
+
stopped: "Przerwane",
|
|
821
|
+
queued: "Czekam na wolne miejsce na serwerze",
|
|
822
|
+
ready: "Gotowe",
|
|
823
|
+
error: "Błąd",
|
|
824
|
+
pctDone: "gotowe",
|
|
825
|
+
pctError: "błąd",
|
|
826
|
+
pctQueued: "w kolejce",
|
|
827
|
+
pctRunning: "liczę",
|
|
828
|
+
running: (time) => `trwa ${time}`,
|
|
829
|
+
left: (time) => nb(`zostało ok. ${time}`),
|
|
830
|
+
clean: "bez błędów",
|
|
831
|
+
of: "z",
|
|
832
|
+
waiting: "czeka",
|
|
833
|
+
log: "Przebieg",
|
|
834
|
+
retry: "Spróbuj ponownie"
|
|
835
|
+
}
|
|
836
|
+
};
|
|
837
|
+
function useKitText() {
|
|
838
|
+
const { i18n } = reactI18next.useTranslation();
|
|
839
|
+
const pl2 = String((i18n == null ? void 0 : i18n.language) ?? "en").startsWith("pl");
|
|
840
|
+
return { text: pl2 ? TEXT$1.pl : TEXT$1.en, locale: pl2 ? "pl-PL" : "en-GB" };
|
|
841
|
+
}
|
|
842
|
+
const DOT = {
|
|
843
|
+
green: "bg-ui-tag-green-icon",
|
|
844
|
+
orange: "bg-ui-tag-orange-icon",
|
|
845
|
+
red: "bg-ui-tag-red-icon",
|
|
846
|
+
blue: "bg-ui-tag-blue-icon",
|
|
847
|
+
grey: "bg-ui-tag-neutral-icon",
|
|
848
|
+
purple: "bg-ui-tag-purple-icon"
|
|
849
|
+
};
|
|
850
|
+
const ICON = {
|
|
851
|
+
green: "text-ui-tag-green-icon",
|
|
852
|
+
orange: "text-ui-tag-orange-icon",
|
|
853
|
+
red: "text-ui-tag-red-icon",
|
|
854
|
+
blue: "text-ui-tag-blue-icon",
|
|
855
|
+
grey: "text-ui-fg-muted",
|
|
856
|
+
purple: "text-ui-tag-purple-icon"
|
|
857
|
+
};
|
|
858
|
+
function ToneBadge({ tone = "grey", children, icon, dot = false, title, size = "2xsmall" }) {
|
|
859
|
+
if (dot) {
|
|
860
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("span", { title, className: "txt-compact-small inline-flex items-center gap-x-1.5 whitespace-nowrap text-ui-fg-subtle", children: [
|
|
861
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": true, className: ui.clx("size-1.5 shrink-0 rounded-full", DOT[tone]) }),
|
|
862
|
+
children
|
|
863
|
+
] });
|
|
864
|
+
}
|
|
865
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { size, color: tone, title, className: "whitespace-nowrap", children: icon ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-x-1 [&_svg]:size-3 [&_svg]:shrink-0", children: [
|
|
866
|
+
icon,
|
|
867
|
+
children
|
|
868
|
+
] }) : children });
|
|
869
|
+
}
|
|
870
|
+
function FilterBar({ children, className }) {
|
|
871
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: ui.clx("flex flex-wrap items-center gap-2 bg-ui-bg-subtle px-6 py-2.5", className), children });
|
|
872
|
+
}
|
|
873
|
+
function FilterButton({
|
|
874
|
+
icon,
|
|
875
|
+
label,
|
|
876
|
+
count,
|
|
877
|
+
active,
|
|
878
|
+
attention,
|
|
879
|
+
onClick,
|
|
880
|
+
title,
|
|
881
|
+
disabled
|
|
882
|
+
}) {
|
|
883
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(ui.Button, { size: "small", variant: active ? "primary" : "secondary", "aria-pressed": active, onClick, title, disabled, className: "shrink-0 gap-x-1.5 whitespace-nowrap [&_svg]:size-4", children: [
|
|
884
|
+
icon,
|
|
885
|
+
label,
|
|
886
|
+
typeof count === "number" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
887
|
+
"span",
|
|
888
|
+
{
|
|
889
|
+
className: ui.clx(
|
|
890
|
+
"txt-compact-xsmall-plus rounded-full px-1.5 tabular-nums",
|
|
891
|
+
active ? "bg-white/20" : attention && count > 0 ? "bg-ui-tag-orange-bg text-ui-tag-orange-text" : "bg-ui-bg-component text-ui-fg-muted"
|
|
892
|
+
),
|
|
893
|
+
children: count
|
|
894
|
+
}
|
|
895
|
+
) : null
|
|
896
|
+
] });
|
|
897
|
+
}
|
|
898
|
+
function FilterDivider() {
|
|
899
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": true, className: "mx-1 h-4 w-px shrink-0 bg-ui-border-base" });
|
|
900
|
+
}
|
|
901
|
+
function useDebouncedValue(value, ms = 300) {
|
|
902
|
+
const [out, setOut] = react.useState(value);
|
|
903
|
+
react.useEffect(() => {
|
|
904
|
+
const t = setTimeout(() => setOut(value), ms);
|
|
905
|
+
return () => clearTimeout(t);
|
|
906
|
+
}, [value, ms]);
|
|
907
|
+
return out;
|
|
908
|
+
}
|
|
909
|
+
function SearchInput({ value, onChange, placeholder, className, autoFocus, label }) {
|
|
910
|
+
const { text } = useKitText();
|
|
911
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
912
|
+
ui.Input,
|
|
913
|
+
{
|
|
914
|
+
size: "small",
|
|
915
|
+
type: "search",
|
|
916
|
+
autoFocus,
|
|
917
|
+
"aria-label": label ?? placeholder ?? text.search,
|
|
918
|
+
placeholder: placeholder ?? text.search,
|
|
919
|
+
value,
|
|
920
|
+
onChange: (e) => onChange(e.target.value),
|
|
921
|
+
className: ui.clx("w-full sm:w-64", className)
|
|
922
|
+
}
|
|
923
|
+
);
|
|
924
|
+
}
|
|
925
|
+
function RowActions({ actions, className }) {
|
|
926
|
+
const shown = actions.filter((a) => !a.hidden);
|
|
927
|
+
if (!shown.length) return null;
|
|
928
|
+
const stop = (e) => e.stopPropagation();
|
|
929
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: ui.clx("inline-flex items-center justify-end gap-0.5", className), onClick: stop, children: shown.map((a) => {
|
|
930
|
+
const icon = a.loading ? /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowPath, { className: "animate-spin" }) : a.icon;
|
|
931
|
+
const tone = a.danger ? "text-ui-tag-red-icon" : "text-ui-fg-subtle";
|
|
932
|
+
if (a.href && !a.disabled) {
|
|
933
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
934
|
+
"a",
|
|
935
|
+
{
|
|
936
|
+
href: a.href,
|
|
937
|
+
title: a.label,
|
|
938
|
+
"aria-label": a.label,
|
|
939
|
+
...a.external ? { target: "_blank", rel: "noreferrer" } : {},
|
|
940
|
+
className: ui.clx("inline-flex size-7 items-center justify-center rounded-md outline-none transition-fg hover:bg-ui-bg-base-hover focus-visible:shadow-borders-focus", tone),
|
|
941
|
+
children: icon
|
|
942
|
+
},
|
|
943
|
+
a.key
|
|
944
|
+
);
|
|
945
|
+
}
|
|
946
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { size: "small", variant: "transparent", title: a.label, "aria-label": a.label, disabled: a.disabled || a.loading, onClick: () => {
|
|
947
|
+
var _a;
|
|
948
|
+
return (_a = a.onClick) == null ? void 0 : _a.call(a);
|
|
949
|
+
}, className: tone, children: icon }, a.key);
|
|
950
|
+
}) });
|
|
951
|
+
}
|
|
952
|
+
function EmptyState({ icon, title, points, action, compact = false, className }) {
|
|
953
|
+
const { text } = useKitText();
|
|
954
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: ui.clx("flex flex-col items-center justify-center gap-y-2 px-6 text-center", compact ? "py-5" : "py-10", className), children: [
|
|
955
|
+
icon ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex size-9 items-center justify-center rounded-lg border border-ui-border-base bg-ui-bg-component text-ui-fg-muted shadow-elevation-card-rest [&_svg]:size-5", children: icon }) : null,
|
|
956
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", className: "text-ui-fg-subtle", children: title ?? text.empty }),
|
|
957
|
+
points ? /* @__PURE__ */ jsxRuntime.jsx(KeyPoints, { items: points, className: "max-w-full justify-center" }) : null,
|
|
958
|
+
action ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pt-1", children: action }) : null
|
|
959
|
+
] });
|
|
960
|
+
}
|
|
961
|
+
function EmptyTableRow({ cols, ...props }) {
|
|
962
|
+
return /* @__PURE__ */ jsxRuntime.jsx("tr", { children: /* @__PURE__ */ jsxRuntime.jsx("td", { colSpan: cols, children: /* @__PURE__ */ jsxRuntime.jsx(EmptyState, { compact: true, ...props }) }) });
|
|
963
|
+
}
|
|
964
|
+
function Section({
|
|
965
|
+
id,
|
|
966
|
+
icon,
|
|
967
|
+
title,
|
|
968
|
+
badges,
|
|
969
|
+
points,
|
|
970
|
+
pointsLabel,
|
|
971
|
+
description,
|
|
972
|
+
actions,
|
|
973
|
+
children,
|
|
974
|
+
className
|
|
975
|
+
}) {
|
|
976
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { id, className: ui.clx("scroll-mt-4 divide-y p-0", className), children: [
|
|
977
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-start justify-between gap-3 px-6 py-4", children: [
|
|
978
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-1 flex-col gap-y-1.5", children: [
|
|
979
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-wrap items-center gap-x-2 gap-y-1", children: [
|
|
980
|
+
icon ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex shrink-0 text-ui-fg-subtle [&_svg]:size-[18px]", children: icon }) : null,
|
|
981
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", children: title }),
|
|
982
|
+
badges ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex flex-wrap items-center gap-1.5", children: badges }) : null
|
|
983
|
+
] }),
|
|
984
|
+
points ? /* @__PURE__ */ jsxRuntime.jsx(KeyPoints, { items: points, label: pointsLabel }) : null,
|
|
985
|
+
description ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "txt-small min-w-0 text-ui-fg-subtle", children: description }) : null
|
|
986
|
+
] }),
|
|
987
|
+
actions ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap items-center gap-2", children: actions }) : null
|
|
988
|
+
] }),
|
|
989
|
+
children
|
|
990
|
+
] });
|
|
991
|
+
}
|
|
992
|
+
const GRID = {
|
|
993
|
+
2: "md:grid-cols-2",
|
|
994
|
+
3: "md:grid-cols-3",
|
|
995
|
+
4: "md:grid-cols-4",
|
|
996
|
+
5: "md:grid-cols-3 xl:grid-cols-5",
|
|
997
|
+
6: "md:grid-cols-3 xl:grid-cols-6",
|
|
998
|
+
7: "md:grid-cols-4 xl:grid-cols-7"
|
|
999
|
+
};
|
|
1000
|
+
function StatTiles({ children, columns = 4, className }) {
|
|
1001
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: ui.clx("grid grid-cols-2 gap-3 px-6 py-4", GRID[columns], className), children });
|
|
1002
|
+
}
|
|
1003
|
+
function StatTile({
|
|
1004
|
+
label,
|
|
1005
|
+
value,
|
|
1006
|
+
hint,
|
|
1007
|
+
tone = "grey",
|
|
1008
|
+
icon,
|
|
1009
|
+
active = false,
|
|
1010
|
+
onClick,
|
|
1011
|
+
title
|
|
1012
|
+
}) {
|
|
1013
|
+
const body = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1014
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex min-w-0 items-center gap-x-2", children: [
|
|
1015
|
+
icon ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: ui.clx("flex shrink-0 [&_svg]:size-3.5", ICON[tone]), children: icon }) : /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": true, className: ui.clx("size-1.5 shrink-0 rounded-full", DOT[tone]) }),
|
|
1016
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "truncate text-ui-fg-subtle", children: label })
|
|
1017
|
+
] }),
|
|
1018
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "txt-xlarge-plus max-w-full break-words tabular-nums text-ui-fg-base", children: value }),
|
|
1019
|
+
hint ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-fg-muted", children: hint }) : null
|
|
1020
|
+
] });
|
|
1021
|
+
const cls = ui.clx(
|
|
1022
|
+
"flex h-full min-w-0 flex-col items-start gap-y-1 rounded-lg border px-4 py-3 text-left transition-fg",
|
|
1023
|
+
active ? "border-ui-border-interactive bg-ui-bg-base shadow-borders-interactive-with-active" : "border-ui-border-base bg-ui-bg-subtle"
|
|
1024
|
+
);
|
|
1025
|
+
return onClick ? /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", "aria-pressed": active, title, onClick, className: ui.clx(cls, !active && "hover:bg-ui-bg-base-hover"), children: body }) : /* @__PURE__ */ jsxRuntime.jsx("div", { title, className: cls, children: body });
|
|
1026
|
+
}
|
|
1027
|
+
function runFromSteps(steps, startedAt, log = []) {
|
|
1028
|
+
var _a;
|
|
1029
|
+
const all = Object.values(steps);
|
|
1030
|
+
const status = all.some((s) => s.status === "error") ? "error" : all.some((s) => s.status === "running") ? "running" : all.length && all.every((s) => s.status === "done") ? "done" : all.some((s) => s.status === "done") ? "running" : "queued";
|
|
1031
|
+
return {
|
|
1032
|
+
status,
|
|
1033
|
+
started_at: new Date(startedAt).toISOString(),
|
|
1034
|
+
finished_at: status === "done" || status === "error" ? (/* @__PURE__ */ new Date()).toISOString() : null,
|
|
1035
|
+
steps,
|
|
1036
|
+
log,
|
|
1037
|
+
error: ((_a = all.find((s) => s.status === "error")) == null ? void 0 : _a.note) ?? null
|
|
1038
|
+
};
|
|
1039
|
+
}
|
|
1040
|
+
function formatDuration(ms) {
|
|
1041
|
+
const s = Math.max(0, Math.round(ms / 1e3));
|
|
1042
|
+
return s >= 60 ? `${Math.floor(s / 60)} min ${String(s % 60).padStart(2, "0")} s` : `${s} s`;
|
|
1043
|
+
}
|
|
1044
|
+
const GRID_STAGES = {
|
|
1045
|
+
3: "grid-cols-3",
|
|
1046
|
+
4: "grid-cols-2 sm:grid-cols-4",
|
|
1047
|
+
5: "grid-cols-3 lg:grid-cols-5",
|
|
1048
|
+
6: "grid-cols-3 lg:grid-cols-6"
|
|
1049
|
+
};
|
|
1050
|
+
function StagedLoader({ run, stages, doneTitle, columns = 6, onRetry }) {
|
|
1051
|
+
const { text, locale } = useKitText();
|
|
1052
|
+
const [openLog, setOpenLog] = react.useState(false);
|
|
1053
|
+
const [now, setNow] = react.useState(Date.now());
|
|
1054
|
+
const live = run.status === "running" || run.status === "queued";
|
|
1055
|
+
react.useEffect(() => {
|
|
1056
|
+
if (!live) return;
|
|
1057
|
+
const t = setInterval(() => setNow(Date.now()), 500);
|
|
1058
|
+
return () => clearInterval(t);
|
|
1059
|
+
}, [live]);
|
|
1060
|
+
const share = (key) => {
|
|
1061
|
+
const s = run.steps[key] ?? { status: "queued" };
|
|
1062
|
+
if (s.status === "done" || s.status === "error") return 1;
|
|
1063
|
+
if (s.status === "running") return s.total ? Math.min(1, (s.done ?? 0) / s.total) : 0.3;
|
|
1064
|
+
return 0;
|
|
1065
|
+
};
|
|
1066
|
+
const weights = stages.reduce((sum, e) => sum + e.weight, 0) || 1;
|
|
1067
|
+
const pct = Math.round(stages.reduce((sum, e) => sum + e.weight * share(e.key), 0) / weights * 100);
|
|
1068
|
+
const start = new Date(run.started_at).getTime();
|
|
1069
|
+
const end = run.finished_at ? new Date(run.finished_at).getTime() : now;
|
|
1070
|
+
const elapsed = Math.max(0, end - start);
|
|
1071
|
+
const left = run.status === "running" && pct >= 5 && pct < 100 ? elapsed * (100 - pct) / pct : null;
|
|
1072
|
+
const current = stages.find((e) => {
|
|
1073
|
+
var _a;
|
|
1074
|
+
return ((_a = run.steps[e.key]) == null ? void 0 : _a.status) === "running";
|
|
1075
|
+
});
|
|
1076
|
+
const cs = current ? run.steps[current.key] : null;
|
|
1077
|
+
const log = run.log ?? [];
|
|
1078
|
+
const number = (n) => new Intl.NumberFormat(locale).format(n);
|
|
1079
|
+
const R = 46;
|
|
1080
|
+
const C = 2 * Math.PI * R;
|
|
1081
|
+
const ring = run.status === "error" ? "var(--tag-red-icon)" : run.status === "done" ? "var(--tag-green-icon)" : "var(--fg-interactive)";
|
|
1082
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { role: "status", "aria-live": "polite", className: "flex flex-col gap-y-4 px-6 py-5", children: [
|
|
1083
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-6 rounded-xl border border-ui-border-base bg-ui-bg-subtle p-5 sm:flex-row", children: [
|
|
1084
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative size-32 shrink-0", children: [
|
|
1085
|
+
/* @__PURE__ */ jsxRuntime.jsxs("svg", { viewBox: "0 0 110 110", className: "size-32 -rotate-90", "aria-hidden": true, children: [
|
|
1086
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "55", cy: "55", r: R, fill: "none", stroke: "var(--border-base)", strokeWidth: "9" }),
|
|
1087
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "55", cy: "55", r: R, fill: "none", stroke: ring, strokeWidth: "9", strokeLinecap: "round", strokeDasharray: C, strokeDashoffset: C * (1 - pct / 100), style: { transition: "stroke-dashoffset .6s ease" } })
|
|
1088
|
+
] }),
|
|
1089
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute inset-0 flex flex-col items-center justify-center", children: [
|
|
1090
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "txt-xlarge-plus tabular-nums text-ui-fg-base", children: [
|
|
1091
|
+
pct,
|
|
1092
|
+
"%"
|
|
1093
|
+
] }),
|
|
1094
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "txt-compact-xsmall text-ui-fg-muted", children: run.status === "done" ? text.pctDone : run.status === "error" ? text.pctError : run.status === "queued" ? text.pctQueued : text.pctRunning })
|
|
1095
|
+
] })
|
|
1096
|
+
] }),
|
|
1097
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-1 flex-col gap-y-2", children: [
|
|
1098
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", weight: "plus", className: "uppercase tracking-wide text-ui-fg-muted", children: run.status === "running" ? text.now : run.status === "queued" ? text.next : run.status === "done" ? text.counted : text.stopped }),
|
|
1099
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex min-w-0 items-center gap-2 [&_svg]:size-5", children: [
|
|
1100
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: ui.clx("flex shrink-0", run.status === "error" ? "text-ui-tag-red-icon" : run.status === "done" ? "text-ui-tag-green-icon" : "text-ui-fg-interactive"), children: current ? current.icon : run.status === "error" ? /* @__PURE__ */ jsxRuntime.jsx(icons.XCircleSolid, {}) : run.status === "queued" ? /* @__PURE__ */ jsxRuntime.jsx(icons.Clock, {}) : /* @__PURE__ */ jsxRuntime.jsx(icons.CheckCircleSolid, {}) }),
|
|
1101
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "large", weight: "plus", className: "truncate", children: current ? current.name : run.status === "done" ? doneTitle ?? text.ready : run.status === "queued" ? text.queued : run.error ?? text.error })
|
|
1102
|
+
] }),
|
|
1103
|
+
(cs == null ? void 0 : cs.total) ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
1104
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-2 overflow-hidden rounded-full bg-ui-bg-component", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-full rounded-full bg-ui-fg-interactive transition-all", style: { width: `${Math.min(100, Math.round((cs.done ?? 0) / cs.total * 100))}%` } }) }),
|
|
1105
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "xsmall", className: "tabular-nums text-ui-fg-subtle", children: [
|
|
1106
|
+
number(cs.done ?? 0),
|
|
1107
|
+
" ",
|
|
1108
|
+
text.of,
|
|
1109
|
+
" ",
|
|
1110
|
+
number(cs.total),
|
|
1111
|
+
cs.note ? `, ${cs.note}` : ""
|
|
1112
|
+
] })
|
|
1113
|
+
] }) : (cs == null ? void 0 : cs.note) ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-fg-subtle", children: cs.note }) : null,
|
|
1114
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1115
|
+
KeyPoints,
|
|
1116
|
+
{
|
|
1117
|
+
items: [
|
|
1118
|
+
{ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.Clock, {}), text: text.running(formatDuration(elapsed)) },
|
|
1119
|
+
left !== null && { icon: /* @__PURE__ */ jsxRuntime.jsx(icons.Sparkles, {}), text: text.left(formatDuration(left)), tone: "blue" },
|
|
1120
|
+
run.status === "done" && { icon: /* @__PURE__ */ jsxRuntime.jsx(icons.CheckCircleSolid, {}), text: text.clean, tone: "green" }
|
|
1121
|
+
]
|
|
1122
|
+
}
|
|
1123
|
+
)
|
|
1124
|
+
] })
|
|
1125
|
+
] }),
|
|
1126
|
+
/* @__PURE__ */ jsxRuntime.jsx("ol", { className: ui.clx("grid gap-2", GRID_STAGES[columns]), children: stages.map((e) => {
|
|
1127
|
+
const s = run.steps[e.key] ?? { status: "queued" };
|
|
1128
|
+
const p = s.total ? Math.min(100, Math.round((s.done ?? 0) / s.total * 100)) : s.status === "done" ? 100 : 0;
|
|
1129
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1130
|
+
"li",
|
|
1131
|
+
{
|
|
1132
|
+
className: ui.clx(
|
|
1133
|
+
"relative flex min-w-0 flex-col gap-1 overflow-hidden rounded-lg border px-3 py-2.5",
|
|
1134
|
+
s.status === "running" ? "border-ui-border-interactive bg-ui-bg-highlight shadow-borders-interactive-with-active" : s.status === "done" ? "border-ui-tag-green-border bg-ui-tag-green-bg" : s.status === "error" ? "border-ui-tag-red-border bg-ui-tag-red-bg" : "border-ui-border-base bg-ui-bg-base opacity-70"
|
|
1135
|
+
),
|
|
1136
|
+
children: [
|
|
1137
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center justify-between gap-1", children: [
|
|
1138
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: ui.clx("flex [&_svg]:size-4", s.status === "running" ? "text-ui-fg-interactive" : s.status === "done" ? "text-ui-tag-green-icon" : s.status === "error" ? "text-ui-tag-red-icon" : "text-ui-fg-muted"), children: e.icon }),
|
|
1139
|
+
s.status === "done" ? /* @__PURE__ */ jsxRuntime.jsx(icons.CheckCircleSolid, { className: "size-4 text-ui-tag-green-icon" }) : s.status === "running" ? /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowPath, { className: "size-4 animate-spin text-ui-fg-interactive" }) : s.status === "error" ? /* @__PURE__ */ jsxRuntime.jsx(icons.XCircleSolid, { className: "size-4 text-ui-tag-red-icon" }) : null
|
|
1140
|
+
] }),
|
|
1141
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", weight: "plus", className: "truncate", children: e.short }),
|
|
1142
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "truncate tabular-nums text-ui-fg-subtle", children: s.total ? `${number(s.done ?? 0)} / ${number(s.total)}` : s.done !== void 0 ? number(s.done) : s.status === "queued" ? text.waiting : s.note ?? "" }),
|
|
1143
|
+
s.status === "running" ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute inset-x-0 bottom-0 h-0.5 bg-ui-fg-interactive transition-all", style: { width: `${p}%` } }) : null
|
|
1144
|
+
]
|
|
1145
|
+
},
|
|
1146
|
+
e.key
|
|
1147
|
+
);
|
|
1148
|
+
}) }),
|
|
1149
|
+
log.length ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base", children: [
|
|
1150
|
+
/* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", "aria-expanded": openLog, onClick: () => setOpenLog((v) => !v), className: "flex w-full items-center justify-between rounded-lg px-3 py-2 text-left hover:bg-ui-bg-base-hover", children: [
|
|
1151
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "xsmall", weight: "plus", className: "uppercase tracking-wide text-ui-fg-muted", children: [
|
|
1152
|
+
text.log,
|
|
1153
|
+
" (",
|
|
1154
|
+
log.length,
|
|
1155
|
+
")"
|
|
1156
|
+
] }),
|
|
1157
|
+
/* @__PURE__ */ jsxRuntime.jsx(icons.TriangleRightMini, { className: ui.clx("text-ui-fg-muted transition-transform", openLog && "rotate-90") })
|
|
1158
|
+
] }),
|
|
1159
|
+
openLog ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "txt-compact-xsmall flex max-h-56 flex-col gap-y-0.5 overflow-y-auto rounded-b-lg border-t border-ui-border-base bg-ui-bg-subtle px-3 py-2 font-mono text-ui-fg-subtle", children: log.map((l, i) => /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
1160
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-ui-fg-muted", children: new Date(l.at).toLocaleTimeString(locale) }),
|
|
1161
|
+
" ",
|
|
1162
|
+
l.text
|
|
1163
|
+
] }, i)) }) : null
|
|
1164
|
+
] }) : null,
|
|
1165
|
+
run.status === "error" && (run.error || onRetry) ? /* @__PURE__ */ jsxRuntime.jsx(ui.InlineTip, { variant: "error", label: text.error, children: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex flex-wrap items-center justify-between gap-2", children: [
|
|
1166
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: run.error }),
|
|
1167
|
+
onRetry ? /* @__PURE__ */ jsxRuntime.jsxs(ui.Button, { size: "small", variant: "secondary", onClick: onRetry, children: [
|
|
1168
|
+
/* @__PURE__ */ jsxRuntime.jsx(icons.ArrowPath, {}),
|
|
1169
|
+
text.retry
|
|
1170
|
+
] }) : null
|
|
1171
|
+
] }) }) : null
|
|
1172
|
+
] });
|
|
1173
|
+
}
|
|
1174
|
+
const TILE = '<rect width="192" height="192" rx="40" fill="#FFFFFF"/><rect x="0.75" y="0.75" width="190.5" height="190.5" rx="39.25" fill="none" stroke="#000000" stroke-opacity="0.1" stroke-width="1.5"/><image href="data:image/png;base64,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" x="24.00" y="77.25" width="144" height="37.49"/>';
|
|
1175
|
+
function SubiektIcon({ width = 15, height = 15, ...props }) {
|
|
1176
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1177
|
+
"svg",
|
|
1178
|
+
{
|
|
1179
|
+
width,
|
|
1180
|
+
height,
|
|
1181
|
+
viewBox: "0 0 192 192",
|
|
1182
|
+
fill: "none",
|
|
1183
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
1184
|
+
"aria-hidden": "true",
|
|
1185
|
+
...props,
|
|
1186
|
+
dangerouslySetInnerHTML: { __html: TILE }
|
|
1187
|
+
}
|
|
1188
|
+
);
|
|
1189
|
+
}
|
|
1190
|
+
function fmtDateTime(value, lang) {
|
|
1191
|
+
if (!value) return "";
|
|
1192
|
+
const d = new Date(value);
|
|
1193
|
+
if (!Number.isFinite(d.getTime())) return "";
|
|
1194
|
+
try {
|
|
1195
|
+
return new Intl.DateTimeFormat(lang, { dateStyle: "medium", timeStyle: "short" }).format(d);
|
|
1196
|
+
} catch {
|
|
1197
|
+
return d.toISOString().slice(0, 16).replace("T", " ");
|
|
1198
|
+
}
|
|
1199
|
+
}
|
|
1200
|
+
function fmtDuration(ms) {
|
|
1201
|
+
if (!Number.isFinite(ms) || ms <= 0) return "0 s";
|
|
1202
|
+
return ms < 1e4 ? `${(ms / 1e3).toFixed(1)} s` : `${Math.round(ms / 1e3)} s`;
|
|
1203
|
+
}
|
|
1204
|
+
function fmtNumber(value, lang) {
|
|
1205
|
+
const n = typeof value === "number" ? value : Number(value);
|
|
1206
|
+
if (!Number.isFinite(n)) return "0";
|
|
1207
|
+
try {
|
|
1208
|
+
return new Intl.NumberFormat(lang).format(n);
|
|
1209
|
+
} catch {
|
|
1210
|
+
return String(n);
|
|
1211
|
+
}
|
|
1212
|
+
}
|
|
1213
|
+
const TASK_TONE = {
|
|
1214
|
+
waiting: "grey",
|
|
1215
|
+
pending: "blue",
|
|
1216
|
+
running: "blue",
|
|
1217
|
+
unknown: "orange",
|
|
1218
|
+
succeeded: "green",
|
|
1219
|
+
failed: "red",
|
|
1220
|
+
canceled: "grey"
|
|
1221
|
+
};
|
|
1222
|
+
function taskTone(status) {
|
|
1223
|
+
return TASK_TONE[status] ?? "grey";
|
|
1224
|
+
}
|
|
1225
|
+
function TaskStatusBadge({ status, dot = false }) {
|
|
1226
|
+
const { t } = reactI18next.useTranslation("subiekt");
|
|
1227
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ToneBadge, { tone: taskTone(status), dot, children: t(`tasks.statuses.${status}`) });
|
|
1228
|
+
}
|
|
1229
|
+
const RUN_TONE = { success: "green", partial: "orange", error: "red", skipped: "grey" };
|
|
1230
|
+
function RunStatusBadge({ status, dot = false }) {
|
|
1231
|
+
const { t } = reactI18next.useTranslation("subiekt");
|
|
1232
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ToneBadge, { tone: RUN_TONE[status] ?? "grey", dot, children: t(`runs.statuses.${status}`) });
|
|
1233
|
+
}
|
|
1234
|
+
function DocumentStatusBadge({ status, dot = false }) {
|
|
1235
|
+
const { t } = reactI18next.useTranslation("subiekt");
|
|
1236
|
+
const tone = status === "canceled" ? "grey" : status === "completed" ? "green" : "blue";
|
|
1237
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ToneBadge, { tone, dot, children: t(`documents.statuses.${status}`, { defaultValue: status }) });
|
|
1238
|
+
}
|
|
1239
|
+
const CATALOG_TONE = {
|
|
1240
|
+
planned: "blue",
|
|
1241
|
+
applied: "green",
|
|
1242
|
+
simulated: "blue",
|
|
1243
|
+
over_cap: "grey",
|
|
1244
|
+
stale: "orange",
|
|
1245
|
+
failed: "red",
|
|
1246
|
+
quarantined: "red",
|
|
1247
|
+
skipped: "grey"
|
|
1248
|
+
};
|
|
1249
|
+
function CatalogStatusBadge({ status, dot = false }) {
|
|
1250
|
+
const { t } = reactI18next.useTranslation("subiekt");
|
|
1251
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ToneBadge, { tone: CATALOG_TONE[status] ?? "grey", dot, children: t(`products.statuses.${status}`, { defaultValue: status }) });
|
|
1252
|
+
}
|
|
1253
|
+
function SampleList({ label, items }) {
|
|
1254
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-1", children: [
|
|
1255
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-fg-subtle", children: label }),
|
|
1256
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-1", children: items.map((item) => /* @__PURE__ */ jsxRuntime.jsx(ToneBadge, { children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono", children: item }) }, item)) })
|
|
1257
|
+
] });
|
|
1258
|
+
}
|
|
1259
|
+
function RichText({ text }) {
|
|
1260
|
+
const parts = text.split("`");
|
|
1261
|
+
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: parts.map(
|
|
1262
|
+
(part, i) => i % 2 === 1 ? /* @__PURE__ */ jsxRuntime.jsx("code", { className: "txt-compact-xsmall rounded border border-ui-border-base bg-ui-bg-subtle px-1 font-mono text-ui-fg-base", children: part }, i) : /* @__PURE__ */ jsxRuntime.jsx("span", { children: part }, i)
|
|
1263
|
+
) });
|
|
1264
|
+
}
|
|
1265
|
+
function connectionState(s) {
|
|
1266
|
+
var _a;
|
|
1267
|
+
if (!s) return { key: "unknown", tone: "grey" };
|
|
1268
|
+
if (s.mode === "demo") return { key: "demo", tone: "blue" };
|
|
1269
|
+
if (!s.configured) return { key: "notConfigured", tone: "orange" };
|
|
1270
|
+
if (!s.connection.checkedAt && !s.connection.lastErrorAt) return { key: "unknown", tone: "grey" };
|
|
1271
|
+
if (!s.connection.reachable) return { key: "unreachable", tone: "red" };
|
|
1272
|
+
if (s.connection.health && !((_a = s.connection.health.subiekt) == null ? void 0 : _a.connected)) return { key: "subiektDown", tone: "orange" };
|
|
1273
|
+
return { key: "connected", tone: "green" };
|
|
1274
|
+
}
|
|
1275
|
+
function ConnectionBadge({ status }) {
|
|
1276
|
+
const { t } = reactI18next.useTranslation("subiekt");
|
|
1277
|
+
const state = connectionState(status);
|
|
1278
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ToneBadge, { tone: state.tone, children: t(`mode.${state.key}`) });
|
|
1279
|
+
}
|
|
1280
|
+
function Field({ label, children }) {
|
|
1281
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-[minmax(120px,1fr)_2fr] items-start gap-x-4 px-6 py-2", children: [
|
|
1282
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", className: "text-ui-fg-subtle", children: label }),
|
|
1283
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "txt-compact-small text-ui-fg-base min-w-0 break-words", children })
|
|
1284
|
+
] });
|
|
1285
|
+
}
|
|
1286
|
+
function Pager({ offset, limit, count, onChange }) {
|
|
1287
|
+
const { t } = reactI18next.useTranslation("subiekt");
|
|
1288
|
+
if (count <= limit) return null;
|
|
1289
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between px-6 py-3", children: [
|
|
1290
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle tabular-nums", children: t("tasks.page", { from: offset + 1, to: Math.min(offset + limit, count), count }) }),
|
|
1291
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-x-2", children: [
|
|
1292
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", disabled: offset === 0, onClick: () => onChange(Math.max(0, offset - limit)), children: t("tasks.prev") }),
|
|
1293
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", disabled: offset + limit >= count, onClick: () => onChange(offset + limit), children: t("tasks.next") })
|
|
1294
|
+
] })
|
|
1295
|
+
] });
|
|
1296
|
+
}
|
|
1297
|
+
const num$1 = (v) => typeof v === "number" && Number.isFinite(v) ? v : 0;
|
|
1298
|
+
function runSummary(run, t) {
|
|
1299
|
+
const s = run.stats ?? {};
|
|
1300
|
+
if (run.status === "error" || run.status === "skipped" || !run.stats) return run.message ?? "";
|
|
1301
|
+
if (run.kind === "stock") {
|
|
1302
|
+
const changes = num$1(s.toUpdate) + num$1(s.toCreate);
|
|
1303
|
+
return t(run.dryRun ? "runs.summary.stockDry" : "runs.summary.stock", { changes, unchanged: num$1(s.unchanged) });
|
|
1304
|
+
}
|
|
1305
|
+
if (run.kind === "tasks") {
|
|
1306
|
+
const vars = { succeeded: num$1(s.succeeded), retry: num$1(s.retry), failed: num$1(s.failed) };
|
|
1307
|
+
return t(vars.retry || vars.failed ? "runs.summary.tasksIssues" : "runs.summary.tasks", vars);
|
|
1308
|
+
}
|
|
1309
|
+
if (run.kind === "events") return num$1(s.read) > 0 ? t("runs.summary.events", { applied: num$1(s.applied) }) : t("runs.summary.eventsNone");
|
|
1310
|
+
if (run.kind === "health" && run.status === "success") return t("runs.summary.health");
|
|
1311
|
+
if (run.kind === "products") {
|
|
1312
|
+
const applied = num$1(s.applied) + num$1(s.simulated);
|
|
1313
|
+
return t(run.dryRun ? "runs.summary.productsPlan" : "runs.summary.productsApplied", {
|
|
1314
|
+
prices: num$1(s.priceChanges),
|
|
1315
|
+
creates: num$1(s.toCreate),
|
|
1316
|
+
applied,
|
|
1317
|
+
failed: num$1(s.failed)
|
|
1318
|
+
});
|
|
1319
|
+
}
|
|
1320
|
+
if (run.kind === "catchup") {
|
|
1321
|
+
const vars = { queued: num$1(s.queued) + num$1(s.waiting), released: num$1(s.released), errors: num$1(s.errors) };
|
|
1322
|
+
return t(vars.errors ? "runs.summary.catchupErrors" : "runs.summary.catchup", vars);
|
|
1323
|
+
}
|
|
1324
|
+
return run.message ?? "";
|
|
1325
|
+
}
|
|
1326
|
+
function fmtMoney(value, currency, lang) {
|
|
1327
|
+
if (typeof value !== "number" || !Number.isFinite(value)) return "-";
|
|
1328
|
+
try {
|
|
1329
|
+
return new Intl.NumberFormat(lang, { style: "currency", currency: currency.toUpperCase() }).format(value);
|
|
1330
|
+
} catch {
|
|
1331
|
+
return `${value.toFixed(2)} ${currency.toUpperCase()}`;
|
|
1332
|
+
}
|
|
1333
|
+
}
|
|
1334
|
+
function fmtMs(ms) {
|
|
1335
|
+
if (typeof ms !== "number" || !Number.isFinite(ms)) return "-";
|
|
1336
|
+
const abs = Math.abs(ms);
|
|
1337
|
+
return abs < 1e3 ? `${Math.round(ms)} ms` : `${(ms / 1e3).toFixed(abs < 1e4 ? 1 : 0)} s`;
|
|
1338
|
+
}
|
|
1339
|
+
function MedusaMark({ className }) {
|
|
1340
|
+
return /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 36 38", fill: "none", "aria-hidden": true, className, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1341
|
+
"path",
|
|
1342
|
+
{
|
|
1343
|
+
d: "M30.85 6.16832L22.2453 1.21782C19.4299 -0.405941 15.9801 -0.405941 13.1648 1.21782L4.52043 6.16832C1.74473 7.79208 0 10.802 0 14.0099V23.9505C0 27.198 1.74473 30.1683 4.52043 31.7921L13.1251 36.7822C15.9405 38.4059 19.3903 38.4059 22.2056 36.7822L30.8103 31.7921C33.6257 30.1683 35.3307 27.198 35.3307 23.9505V14.0099C35.41 10.802 33.6653 7.79208 30.85 6.16832ZM17.6852 27.8317C12.8079 27.8317 8.8426 23.8713 8.8426 19C8.8426 14.1287 12.8079 10.1683 17.6852 10.1683C22.5625 10.1683 26.5674 14.1287 26.5674 19C26.5674 23.8713 22.6022 27.8317 17.6852 27.8317Z",
|
|
1344
|
+
fill: "currentColor"
|
|
1345
|
+
}
|
|
1346
|
+
) });
|
|
1347
|
+
}
|
|
1348
|
+
function StoreColumn({ label, hint }) {
|
|
1349
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-x-1.5", title: hint, children: [
|
|
1350
|
+
/* @__PURE__ */ jsxRuntime.jsx(MedusaMark, { className: "h-3.5 w-3.5 text-ui-fg-muted" }),
|
|
1351
|
+
label
|
|
1352
|
+
] });
|
|
1353
|
+
}
|
|
1354
|
+
function StoreLink({ to, title, mono, monoTitle, action }) {
|
|
1355
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(reactRouterDom.Link, { to, className: "group flex items-center gap-x-2.5", title: action, children: [
|
|
1356
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-md bg-ui-bg-component shadow-borders-base transition-fg group-hover:bg-ui-bg-component-hover", children: /* @__PURE__ */ jsxRuntime.jsx(MedusaMark, { className: "h-4 w-4 text-ui-fg-base" }) }),
|
|
1357
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex min-w-0 flex-col", children: [
|
|
1358
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "txt-compact-small-plus truncate text-ui-fg-base group-hover:text-ui-fg-interactive", children: title }),
|
|
1359
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex min-w-0 items-center gap-x-1.5", children: [
|
|
1360
|
+
mono ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate font-mono text-ui-fg-muted txt-compact-xsmall", title: monoTitle, children: mono }) : null,
|
|
1361
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "txt-compact-xsmall-plus inline-flex shrink-0 items-center gap-x-0.5 text-ui-fg-interactive", children: [
|
|
1362
|
+
action,
|
|
1363
|
+
/* @__PURE__ */ jsxRuntime.jsx(icons.ArrowUpRightMini, {})
|
|
1364
|
+
] })
|
|
1365
|
+
] })
|
|
1366
|
+
] })
|
|
1367
|
+
] });
|
|
1368
|
+
}
|
|
1369
|
+
function StoreUnlinked({ label, hint, mono }) {
|
|
1370
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-start gap-y-1", title: hint, children: [
|
|
1371
|
+
/* @__PURE__ */ jsxRuntime.jsx(ToneBadge, { tone: "orange", children: label }),
|
|
1372
|
+
mono ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono text-ui-fg-muted txt-compact-xsmall", children: mono }) : null
|
|
1373
|
+
] });
|
|
1374
|
+
}
|
|
1375
|
+
function StoreOrderCell({ orderId, displayId }) {
|
|
1376
|
+
const { t } = reactI18next.useTranslation("subiekt");
|
|
1377
|
+
if (!orderId) return /* @__PURE__ */ jsxRuntime.jsx(StoreUnlinked, { label: t("store.noOrder"), hint: t("store.noOrderHint") });
|
|
1378
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1379
|
+
StoreLink,
|
|
1380
|
+
{
|
|
1381
|
+
to: `/orders/${orderId}`,
|
|
1382
|
+
title: displayId ? `#${displayId}` : orderId,
|
|
1383
|
+
mono: displayId ? orderId : null,
|
|
1384
|
+
monoTitle: orderId,
|
|
1385
|
+
action: t("store.openOrder")
|
|
1386
|
+
}
|
|
1387
|
+
);
|
|
1388
|
+
}
|
|
1389
|
+
const BUSY = /* @__PURE__ */ new Set(["pending", "running", "unknown"]);
|
|
1390
|
+
function taskRun(task, hasDocument) {
|
|
1391
|
+
const s = task.status;
|
|
1392
|
+
const queue = s === "pending" && task.attempts === 0 ? { status: "running" } : { status: "done" };
|
|
1393
|
+
const bridge = s === "pending" && task.attempts === 0 ? { status: "queued" } : s === "failed" ? { status: "error", note: task.lastError ?? void 0 } : s === "succeeded" ? { status: "done" } : { status: "running", note: task.lastError ?? void 0 };
|
|
1394
|
+
const document2 = s === "succeeded" ? hasDocument ? { status: "done" } : { status: "running" } : { status: "queued" };
|
|
1395
|
+
return runFromSteps({ queue, bridge, document: document2 }, task.updatedAt ?? task.createdAt ?? Date.now());
|
|
1396
|
+
}
|
|
1397
|
+
function DocumentLine({ d, lang }) {
|
|
1398
|
+
const { t } = reactI18next.useTranslation("subiekt");
|
|
1399
|
+
const meta = [
|
|
1400
|
+
fmtDateTime(d.issuedAt, lang),
|
|
1401
|
+
t(`documents.sources.${d.source}`, { defaultValue: d.source }),
|
|
1402
|
+
d.warehouse ? t("widget.warehouse", { warehouse: d.warehouse }) : null
|
|
1403
|
+
].filter(Boolean);
|
|
1404
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-x-2", children: [
|
|
1405
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-col", children: [
|
|
1406
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-fg-muted", children: t(`widget.kinds.${d.kind}`, { defaultValue: d.kind }) }),
|
|
1407
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", className: "break-all font-mono", children: d.number }),
|
|
1408
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-fg-muted", children: meta.join(", ") }),
|
|
1409
|
+
d.related.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-fg-subtle", children: t("widget.related", { numbers: d.related.map((r) => r.number).join(", ") }) }) : null,
|
|
1410
|
+
d.kind === "ZK" && d.status === "completed" ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-fg-subtle", children: t("widget.zkCompleted") }) : null,
|
|
1411
|
+
d.kind === "FS" && d.status !== "canceled" ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: d.ksefNumber ? "break-all font-mono text-ui-fg-subtle" : "text-ui-fg-muted", children: d.ksefNumber ? t("widget.ksef", { number: d.ksefNumber }) : t("widget.ksefWaiting") }) : null
|
|
1412
|
+
] }),
|
|
1413
|
+
/* @__PURE__ */ jsxRuntime.jsx(DocumentStatusBadge, { status: d.status })
|
|
1414
|
+
] });
|
|
1415
|
+
}
|
|
1416
|
+
const ENTRY_TONE = { missing: "orange", status_differs: "orange", same: "green", only_local: "grey" };
|
|
1417
|
+
function CheckResult({
|
|
1418
|
+
result,
|
|
1419
|
+
lang,
|
|
1420
|
+
linking,
|
|
1421
|
+
onLink
|
|
1422
|
+
}) {
|
|
1423
|
+
const { t } = reactI18next.useTranslation("subiekt");
|
|
1424
|
+
const status = (v) => t(`documents.statuses.${v ?? "open"}`, { defaultValue: v ?? "" });
|
|
1425
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-3 px-6 py-4", children: [
|
|
1426
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-x-2", children: [
|
|
1427
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: t("widget.check.title") }),
|
|
1428
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-fg-muted", children: t("widget.check.at", { time: fmtDateTime(result.checkedAt, lang) }) })
|
|
1429
|
+
] }),
|
|
1430
|
+
result.entries.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-fg-muted", children: t("widget.check.nothing") }) : result.entries.map((e) => {
|
|
1431
|
+
const key = `${e.kind}|${e.number}`;
|
|
1432
|
+
const where = e.state === "only_local" ? t("widget.check.notReported") : [t("widget.check.inSubiekt", { status: status(e.remoteStatus) }), e.issuedAt ? fmtDateTime(e.issuedAt, lang) : null].filter(Boolean).join(", ");
|
|
1433
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-1", children: [
|
|
1434
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-x-2", children: [
|
|
1435
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-col", children: [
|
|
1436
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "break-all font-mono", children: e.number }),
|
|
1437
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-fg-muted", children: where })
|
|
1438
|
+
] }),
|
|
1439
|
+
/* @__PURE__ */ jsxRuntime.jsx(ToneBadge, { tone: ENTRY_TONE[e.state], children: e.state === "status_differs" ? t("widget.check.states.status_differs", { status: status(e.localStatus) }) : t(`widget.check.states.${e.state}`) })
|
|
1440
|
+
] }),
|
|
1441
|
+
e.kind === "ZK" && e.remoteStatus === "completed" ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-fg-subtle", children: t("widget.zkCompleted") }) : null,
|
|
1442
|
+
e.remoteStatus === "canceled" ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-fg-subtle", children: t("widget.check.canceledThere") }) : null,
|
|
1443
|
+
e.state === "missing" || e.state === "status_differs" ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-1", children: [
|
|
1444
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Button, { size: "small", variant: "secondary", isLoading: linking === key, onClick: () => onLink(e), children: [
|
|
1445
|
+
/* @__PURE__ */ jsxRuntime.jsx(icons.Link, {}),
|
|
1446
|
+
e.state === "missing" ? t("widget.check.link") : t("widget.check.update")
|
|
1447
|
+
] }) }),
|
|
1448
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-fg-muted", children: e.state === "missing" ? t("widget.check.linkHint") : t("widget.check.updateHint") })
|
|
1449
|
+
] }) : null
|
|
1450
|
+
] }, key);
|
|
1451
|
+
})
|
|
1452
|
+
] });
|
|
1453
|
+
}
|
|
1454
|
+
const SubiektOrderWidget = ({ data }) => {
|
|
1455
|
+
var _a, _b, _c, _d;
|
|
1456
|
+
const { t, i18n } = reactI18next.useTranslation("subiekt");
|
|
1457
|
+
const lang = i18n.language || "en";
|
|
1458
|
+
const q = useSubiektOrder(data.id);
|
|
1459
|
+
const send = useSubiektSendOrder(data.id);
|
|
1460
|
+
const issue = useSubiektIssueDocument(data.id);
|
|
1461
|
+
const retry = useSubiektRetry();
|
|
1462
|
+
const check = useSubiektOrderCheck(data.id);
|
|
1463
|
+
const link = useSubiektLinkDocument(data.id);
|
|
1464
|
+
const [checked, setChecked] = react.useState(null);
|
|
1465
|
+
const documents = ((_a = q.data) == null ? void 0 : _a.documents) ?? [];
|
|
1466
|
+
const tasks = ((_b = q.data) == null ? void 0 : _b.tasks) ?? [];
|
|
1467
|
+
const sales = (_c = q.data) == null ? void 0 : _c.salesDocument;
|
|
1468
|
+
const create = tasks.find((task) => task.kind === "order.create");
|
|
1469
|
+
const documentTask = tasks.find((task) => task.kind === "order.document");
|
|
1470
|
+
const hasZk = documents.some((d) => d.kind === "ZK" && d.status !== "canceled");
|
|
1471
|
+
const hasSales = documents.some((d) => (d.kind === "FS" || d.kind === "PA") && d.status !== "canceled");
|
|
1472
|
+
const busy = (create == null ? void 0 : create.status) === "pending" || (create == null ? void 0 : create.status) === "running";
|
|
1473
|
+
const documentBusy = documentTask ? BUSY.has(documentTask.status) : false;
|
|
1474
|
+
const canceled = data.status === "canceled";
|
|
1475
|
+
const offerIssue = Boolean(sales && sales.option !== "none" && sales.supported && hasZk && !hasSales && !documentBusy && !canceled);
|
|
1476
|
+
const inFlight = tasks.find((task) => (task.kind === "order.create" || task.kind === "order.document") && BUSY.has(task.status));
|
|
1477
|
+
const failed = tasks.some((task) => task.status === "failed");
|
|
1478
|
+
const state = failed ? { tone: "red", key: "attention" } : inFlight ? { tone: "blue", key: "sending" } : hasZk ? { tone: "green", key: "inSubiekt" } : (create == null ? void 0 : create.status) === "waiting" ? { tone: "grey", key: "waiting" } : { tone: "grey", key: "notSent" };
|
|
1479
|
+
const onSend = async () => {
|
|
1480
|
+
try {
|
|
1481
|
+
await send.mutateAsync();
|
|
1482
|
+
ui.toast.success(t("widget.sent"));
|
|
1483
|
+
} catch (err) {
|
|
1484
|
+
ui.toast.error(t("toast.error", { error: errorMessage(err) }));
|
|
1485
|
+
}
|
|
1486
|
+
};
|
|
1487
|
+
const onIssue = async (kind) => {
|
|
1488
|
+
try {
|
|
1489
|
+
await issue.mutateAsync(kind);
|
|
1490
|
+
ui.toast.success(t("widget.issued"));
|
|
1491
|
+
} catch (err) {
|
|
1492
|
+
ui.toast.error(t("toast.error", { error: errorMessage(err) }));
|
|
1493
|
+
}
|
|
1494
|
+
};
|
|
1495
|
+
const onCheck = async () => {
|
|
1496
|
+
try {
|
|
1497
|
+
setChecked(await check.mutateAsync());
|
|
1498
|
+
} catch (err) {
|
|
1499
|
+
ui.toast.error(t("toast.error", { error: errorMessage(err) }));
|
|
1500
|
+
}
|
|
1501
|
+
};
|
|
1502
|
+
const onLink = async (e) => {
|
|
1503
|
+
try {
|
|
1504
|
+
const r = await link.mutateAsync({ kind: e.kind, number: e.number });
|
|
1505
|
+
setChecked(r.check);
|
|
1506
|
+
ui.toast.success(e.state === "missing" ? t("widget.check.linked", { number: e.number }) : t("widget.check.updated", { number: e.number }));
|
|
1507
|
+
} catch (err) {
|
|
1508
|
+
ui.toast.error(t("toast.error", { error: errorMessage(err) }));
|
|
1509
|
+
}
|
|
1510
|
+
};
|
|
1511
|
+
const onRetry = async (id) => {
|
|
1512
|
+
try {
|
|
1513
|
+
await retry.mutateAsync(id);
|
|
1514
|
+
ui.toast.success(t("toast.retried"));
|
|
1515
|
+
void q.refetch();
|
|
1516
|
+
} catch (err) {
|
|
1517
|
+
ui.toast.error(t("toast.error", { error: errorMessage(err) }));
|
|
1518
|
+
}
|
|
1519
|
+
};
|
|
1520
|
+
const header = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-x-2 px-6 py-4", children: [
|
|
1521
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-wrap items-center gap-2", children: [
|
|
1522
|
+
/* @__PURE__ */ jsxRuntime.jsx(SubiektIcon, { width: 18, height: 18, className: "shrink-0" }),
|
|
1523
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", children: t("widget.title") }),
|
|
1524
|
+
q.data ? /* @__PURE__ */ jsxRuntime.jsx(ToneBadge, { tone: state.tone, children: t(`widget.state.${state.key}`) }) : null,
|
|
1525
|
+
((_d = q.data) == null ? void 0 : _d.mode) === "demo" ? /* @__PURE__ */ jsxRuntime.jsx(ToneBadge, { tone: "blue", children: t("widget.demo") }) : null
|
|
1526
|
+
] }),
|
|
1527
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1528
|
+
"a",
|
|
1529
|
+
{
|
|
1530
|
+
href: `/app/subiekt?q=${encodeURIComponent(String(data.display_id ?? data.id))}`,
|
|
1531
|
+
className: "txt-compact-small inline-flex shrink-0 items-center gap-x-1 text-ui-fg-interactive hover:text-ui-fg-interactive-hover",
|
|
1532
|
+
children: [
|
|
1533
|
+
t("widget.more"),
|
|
1534
|
+
/* @__PURE__ */ jsxRuntime.jsx(icons.ArrowUpRightOnBox, {})
|
|
1535
|
+
]
|
|
1536
|
+
}
|
|
1537
|
+
)
|
|
1538
|
+
] });
|
|
1539
|
+
const sendingDocument = (inFlight == null ? void 0 : inFlight.kind) === "order.document";
|
|
1540
|
+
const inFlightHasDocument = sendingDocument ? hasSales : hasZk;
|
|
1541
|
+
return /* @__PURE__ */ jsxRuntime.jsx(WidgetFrame, { header, children: q.isLoading ? /* @__PURE__ */ jsxRuntime.jsx(KitLoading, { className: "min-h-0 py-6" }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1542
|
+
inFlight ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
1543
|
+
StagedLoader,
|
|
1544
|
+
{
|
|
1545
|
+
run: taskRun(inFlight, inFlightHasDocument),
|
|
1546
|
+
columns: 3,
|
|
1547
|
+
doneTitle: t("widget.run.done"),
|
|
1548
|
+
stages: [
|
|
1549
|
+
{ key: "queue", name: t("widget.run.queue"), short: t("widget.run.queueShort"), icon: /* @__PURE__ */ jsxRuntime.jsx(icons.QueueList, {}), weight: 20 },
|
|
1550
|
+
{ key: "bridge", name: t("widget.run.bridge"), short: t("widget.run.bridgeShort"), icon: /* @__PURE__ */ jsxRuntime.jsx(icons.ServerStack, {}), weight: 60 },
|
|
1551
|
+
{
|
|
1552
|
+
key: "document",
|
|
1553
|
+
name: t("widget.run.document"),
|
|
1554
|
+
short: t("widget.run.documentShort"),
|
|
1555
|
+
icon: sendingDocument ? /* @__PURE__ */ jsxRuntime.jsx(icons.Receipt, {}) : /* @__PURE__ */ jsxRuntime.jsx(icons.DocumentText, {}),
|
|
1556
|
+
weight: 20
|
|
1557
|
+
}
|
|
1558
|
+
]
|
|
1559
|
+
}
|
|
1560
|
+
) : null,
|
|
1561
|
+
documents.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-y-2 px-6 py-4", children: documents.map((d) => /* @__PURE__ */ jsxRuntime.jsx(DocumentLine, { d, lang }, d.id)) }) : inFlight ? null : /* @__PURE__ */ jsxRuntime.jsx(EmptyState, { compact: true, icon: /* @__PURE__ */ jsxRuntime.jsx(icons.DocumentText, {}), title: (create == null ? void 0 : create.status) === "waiting" ? t("widget.waiting") : t("widget.none") }),
|
|
1562
|
+
tasks.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-y-3 px-6 py-4", children: tasks.map((task) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-1", children: [
|
|
1563
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-x-2", children: [
|
|
1564
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", children: task.kind === "order.document" && (task.documentKind === "fs" || task.documentKind === "pa") ? t(`tasks.documentKinds.${task.documentKind}`) : t(`tasks.kinds.${task.kind}`) }),
|
|
1565
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center gap-x-1", children: [
|
|
1566
|
+
/* @__PURE__ */ jsxRuntime.jsx(TaskStatusBadge, { status: task.status }),
|
|
1567
|
+
task.status === "failed" ? /* @__PURE__ */ jsxRuntime.jsxs(ui.Button, { size: "small", variant: "secondary", isLoading: retry.isPending && retry.variables === task.id, onClick: () => onRetry(task.id), children: [
|
|
1568
|
+
/* @__PURE__ */ jsxRuntime.jsx(icons.ArrowPath, {}),
|
|
1569
|
+
t("actions.retry")
|
|
1570
|
+
] }) : null
|
|
1571
|
+
] })
|
|
1572
|
+
] }),
|
|
1573
|
+
task.buyer ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-fg-subtle", children: task.buyer.source === "retail" ? t("tasks.buyer.retail") : t(`tasks.buyer.${task.buyer.source}`, { name: task.buyer.name ?? task.buyer.symbol ?? "?", nip: task.buyer.nip ?? "?" }) }) : null,
|
|
1574
|
+
task.warnings.map((w) => /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-tag-orange-text", children: w }, w)),
|
|
1575
|
+
task.lastError && task.status !== "succeeded" ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: task.status === "failed" ? "text-ui-tag-red-text" : "text-ui-fg-muted", children: task.lastError }) : null,
|
|
1576
|
+
task.status === "unknown" ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-tag-orange-text", children: t("tasks.unknownHint") }) : null,
|
|
1577
|
+
task.manualAction ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-tag-orange-text", children: t("tasks.manual") }) : null
|
|
1578
|
+
] }, task.id)) }) : null,
|
|
1579
|
+
checked ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
1580
|
+
CheckResult,
|
|
1581
|
+
{
|
|
1582
|
+
result: checked,
|
|
1583
|
+
lang,
|
|
1584
|
+
linking: link.isPending && link.variables ? `${link.variables.kind}|${link.variables.number}` : null,
|
|
1585
|
+
onLink: (e) => void onLink(e)
|
|
1586
|
+
}
|
|
1587
|
+
) : null,
|
|
1588
|
+
!inFlight || !hasZk && !busy && !canceled && (create == null ? void 0 : create.status) !== "failed" || offerIssue && sales ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-2 px-6 py-4", children: [
|
|
1589
|
+
offerIssue && sales ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-fg-muted", children: sales.writerActive ? t("widget.autoOn", { after: sales.after.toUpperCase() }) : t("widget.autoOff") }) : null,
|
|
1590
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-2", children: [
|
|
1591
|
+
!hasZk && !busy && !canceled && (create == null ? void 0 : create.status) !== "failed" ? /* @__PURE__ */ jsxRuntime.jsxs(ui.Button, { size: "small", variant: "secondary", isLoading: send.isPending, onClick: onSend, children: [
|
|
1592
|
+
/* @__PURE__ */ jsxRuntime.jsx(icons.PaperPlane, {}),
|
|
1593
|
+
t("widget.send")
|
|
1594
|
+
] }) : null,
|
|
1595
|
+
offerIssue && sales && (sales.option === "fs" || sales.option === "auto") ? /* @__PURE__ */ jsxRuntime.jsxs(ui.Button, { size: "small", variant: "secondary", isLoading: issue.isPending && issue.variables === "fs", onClick: () => onIssue("fs"), children: [
|
|
1596
|
+
/* @__PURE__ */ jsxRuntime.jsx(icons.DocumentText, {}),
|
|
1597
|
+
t("widget.issueFs")
|
|
1598
|
+
] }) : null,
|
|
1599
|
+
offerIssue && sales && (sales.option === "pa" || sales.option === "auto") ? /* @__PURE__ */ jsxRuntime.jsxs(ui.Button, { size: "small", variant: "secondary", isLoading: issue.isPending && issue.variables === "pa", onClick: () => onIssue("pa"), children: [
|
|
1600
|
+
/* @__PURE__ */ jsxRuntime.jsx(icons.Receipt, {}),
|
|
1601
|
+
t("widget.issuePa")
|
|
1602
|
+
] }) : null,
|
|
1603
|
+
!inFlight ? /* @__PURE__ */ jsxRuntime.jsxs(ui.Button, { size: "small", variant: "secondary", isLoading: check.isPending, onClick: () => void onCheck(), children: [
|
|
1604
|
+
/* @__PURE__ */ jsxRuntime.jsx(icons.MagnifyingGlass, {}),
|
|
1605
|
+
checked ? t("widget.check.again") : t("widget.check.button")
|
|
1606
|
+
] }) : null
|
|
1607
|
+
] }),
|
|
1608
|
+
!checked && !inFlight && (failed || !hasZk && !canceled) ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-fg-muted", children: t("widget.check.hint") }) : null
|
|
1609
|
+
] }) : null
|
|
1610
|
+
] }) });
|
|
1611
|
+
};
|
|
1612
|
+
adminSdk.defineWidgetConfig({
|
|
1613
|
+
zone: "order.details.side.after"
|
|
1614
|
+
});
|
|
1292
1615
|
const CLOCK_SKEW_WARN_SECONDS = 60;
|
|
1293
1616
|
const CLOCK_SKEW_LIMIT_SECONDS = 300;
|
|
1294
1617
|
function skewLevel(skewMs) {
|
|
@@ -1416,7 +1739,7 @@ maxProductsPerRun: 20,`;
|
|
|
1416
1739
|
const DOCUMENTS_CODE = `salesDocument: "auto",
|
|
1417
1740
|
salesDocumentAfter: "wz",
|
|
1418
1741
|
createContractors: true,`;
|
|
1419
|
-
function GuideView({ status
|
|
1742
|
+
function GuideView({ status }) {
|
|
1420
1743
|
const { t } = reactI18next.useTranslation("subiekt");
|
|
1421
1744
|
function list(key) {
|
|
1422
1745
|
const value = t(key, { returnObjects: true });
|
|
@@ -1449,7 +1772,6 @@ function GuideView({ status, lang }) {
|
|
|
1449
1772
|
q: item.q,
|
|
1450
1773
|
a: (item.a ?? []).map((p, i) => /* @__PURE__ */ jsxRuntime.jsx("p", { children: /* @__PURE__ */ jsxRuntime.jsx(RichText, { text: p }) }, i))
|
|
1451
1774
|
}));
|
|
1452
|
-
const references = referencesFor(s.references, lang);
|
|
1453
1775
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-3", children: [
|
|
1454
1776
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1455
1777
|
GuideIntro,
|
|
@@ -1493,31 +1815,249 @@ function GuideView({ status, lang }) {
|
|
|
1493
1815
|
}))
|
|
1494
1816
|
}
|
|
1495
1817
|
),
|
|
1496
|
-
/* @__PURE__ */ jsxRuntime.jsx(GuideFaq, { title: t("guide.faq.title"), items: faq })
|
|
1497
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1498
|
-
References,
|
|
1499
|
-
{
|
|
1500
|
-
items: references,
|
|
1501
|
-
title: t("references.title"),
|
|
1502
|
-
subtitle: t("references.subtitle"),
|
|
1503
|
-
openLabel: t("references.open"),
|
|
1504
|
-
soonLabel: t("references.soon"),
|
|
1505
|
-
reviewLabel: t("references.review"),
|
|
1506
|
-
ratingLabel: (value) => fmtRating(value, lang)
|
|
1507
|
-
}
|
|
1508
|
-
)
|
|
1818
|
+
/* @__PURE__ */ jsxRuntime.jsx(GuideFaq, { title: t("guide.faq.title"), items: faq })
|
|
1509
1819
|
] });
|
|
1510
1820
|
}
|
|
1511
|
-
const
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1821
|
+
const FIELDS = [
|
|
1822
|
+
"id",
|
|
1823
|
+
"currency_code",
|
|
1824
|
+
"items.id",
|
|
1825
|
+
"items.title",
|
|
1826
|
+
"items.product_title",
|
|
1827
|
+
"items.variant_title",
|
|
1828
|
+
"items.thumbnail",
|
|
1829
|
+
"items.quantity",
|
|
1830
|
+
"items.unit_price",
|
|
1831
|
+
"items.variant_sku",
|
|
1832
|
+
"items.variant_barcode",
|
|
1833
|
+
/* Totals come from the order module. Their relations in FULL (.*): with partial fields
|
|
1834
|
+
(e.g. adjustments.code alone) the module computes from incomplete rows. */
|
|
1835
|
+
"total",
|
|
1836
|
+
"shipping_total",
|
|
1837
|
+
"discount_total",
|
|
1838
|
+
"items.tax_lines.*",
|
|
1839
|
+
"items.adjustments.*",
|
|
1840
|
+
"shipping_methods.*",
|
|
1841
|
+
"shipping_methods.tax_lines.*",
|
|
1842
|
+
"shipping_methods.adjustments.*"
|
|
1843
|
+
].join(",");
|
|
1844
|
+
const TEXT = {
|
|
1845
|
+
en: { productsLine: "Products (before discount)", shippingLine: "Shipping (after its discount)", free: "free", discountLine: "Discount", codesLine: "Discount, codes", button: "View", show: "Show products", title: "Products", ofOrder: "of order", lines: "lines", pcs: "pcs", components: "components", close: "Close", showParts: "Show components", hideParts: "Hide components", empty: "This order has no items." },
|
|
1846
|
+
pl: { productsLine: "Produkty (przed rabatem)", shippingLine: "Dostawa (po rabacie na dostawę)", free: "gratis", discountLine: "Rabat", codesLine: "Rabat, kupony", button: "Zobacz", show: "Pokaż produkty", title: "Produkty", ofOrder: "zamówienia", lines: "poz.", pcs: "szt.", components: "składników", close: "Zamknij", showParts: "Pokaż składniki", hideParts: "Ukryj składniki", empty: "Zamówienie nie ma pozycji." }
|
|
1847
|
+
};
|
|
1848
|
+
function useText() {
|
|
1849
|
+
const { i18n } = reactI18next.useTranslation();
|
|
1850
|
+
return String((i18n == null ? void 0 : i18n.language) ?? "en").startsWith("pl") ? TEXT.pl : TEXT.en;
|
|
1851
|
+
}
|
|
1852
|
+
const num = (v) => {
|
|
1853
|
+
const n = typeof v === "number" ? v : typeof v === "string" ? Number(v) : NaN;
|
|
1854
|
+
return Number.isFinite(n) ? n : null;
|
|
1855
|
+
};
|
|
1856
|
+
function amountsOf(o) {
|
|
1857
|
+
const total = num(o.total);
|
|
1858
|
+
const shipping = num(o.shipping_total);
|
|
1859
|
+
const discount = num(o.discount_total) ?? 0;
|
|
1860
|
+
if (total == null || shipping == null) return null;
|
|
1861
|
+
const codes = /* @__PURE__ */ new Set();
|
|
1862
|
+
const adjustments = [...(o.items ?? []).flatMap((it) => it.adjustments ?? []), ...(o.shipping_methods ?? []).flatMap((sm) => sm.adjustments ?? [])];
|
|
1863
|
+
for (const a of adjustments) if (typeof (a == null ? void 0 : a.code) === "string" && a.code.trim()) codes.add(a.code.trim().toUpperCase());
|
|
1864
|
+
const r2 = (n) => Math.round(n * 100) / 100;
|
|
1865
|
+
return { total: r2(total), shipping: r2(shipping), discount: r2(discount), products: r2(total - shipping + discount), codes: [...codes] };
|
|
1866
|
+
}
|
|
1867
|
+
function itemOf(it) {
|
|
1868
|
+
const unitPrice = Number(it.unit_price ?? 0);
|
|
1869
|
+
return {
|
|
1870
|
+
id: it.id,
|
|
1871
|
+
title: it.product_title || it.title || "Product",
|
|
1872
|
+
variant: it.variant_title && it.variant_title !== "Default variant" ? it.variant_title : null,
|
|
1873
|
+
thumbnail: it.thumbnail ?? null,
|
|
1874
|
+
quantity: Number(it.quantity ?? 0),
|
|
1875
|
+
unitPrice,
|
|
1876
|
+
sku: it.variant_sku ?? null,
|
|
1877
|
+
barcode: it.variant_barcode ?? null,
|
|
1878
|
+
component: unitPrice <= 0.05
|
|
1879
|
+
};
|
|
1880
|
+
}
|
|
1881
|
+
async function load(ids) {
|
|
1882
|
+
const out = {};
|
|
1883
|
+
for (let i = 0; i < ids.length; i += 100) {
|
|
1884
|
+
const batch = ids.slice(i, i + 100);
|
|
1885
|
+
const qs = [`fields=${encodeURIComponent(FIELDS)}`, `limit=${batch.length}`, ...batch.map((id) => `id=${encodeURIComponent(id)}`)].join("&");
|
|
1886
|
+
const r = await kitFetch(`/admin/orders?${qs}`);
|
|
1887
|
+
for (const o of r.orders ?? []) {
|
|
1888
|
+
out[o.id] = {
|
|
1889
|
+
currency: String(o.currency_code ?? "usd"),
|
|
1890
|
+
amounts: amountsOf(o),
|
|
1891
|
+
items: (o.items ?? []).map(itemOf)
|
|
1892
|
+
};
|
|
1893
|
+
}
|
|
1894
|
+
}
|
|
1895
|
+
return out;
|
|
1896
|
+
}
|
|
1897
|
+
function useKitOrderProducts(ids) {
|
|
1898
|
+
const unique = [...new Set(ids.filter((x) => typeof x === "string" && x.startsWith("order_")))].sort();
|
|
1899
|
+
return reactQuery.useQuery({
|
|
1900
|
+
queryKey: ["koda-kit-order-products", unique],
|
|
1901
|
+
queryFn: () => load(unique),
|
|
1902
|
+
enabled: unique.length > 0,
|
|
1903
|
+
staleTime: 6e4
|
|
1904
|
+
});
|
|
1905
|
+
}
|
|
1906
|
+
function money(n, currency, lang) {
|
|
1907
|
+
try {
|
|
1908
|
+
return new Intl.NumberFormat(lang, { style: "currency", currency: currency.toUpperCase() }).format(n);
|
|
1909
|
+
} catch {
|
|
1910
|
+
return `${n.toFixed(2)} ${currency.toUpperCase()}`;
|
|
1911
|
+
}
|
|
1912
|
+
}
|
|
1913
|
+
function Thumb({ src, size, title }) {
|
|
1914
|
+
const [broken, setBroken] = react.useState(false);
|
|
1915
|
+
const style = { width: size, height: size };
|
|
1916
|
+
if (!src || broken)
|
|
1917
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { style, className: "flex shrink-0 items-center justify-center rounded-lg border border-ui-border-base bg-ui-bg-component text-ui-fg-muted", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: size * 0.5, height: size * 0.5, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z" }) }) });
|
|
1918
|
+
return /* @__PURE__ */ jsxRuntime.jsx("img", { src, alt: title, title, style, loading: "lazy", onError: () => setBroken(true), className: "shrink-0 rounded-lg border border-ui-border-base bg-ui-bg-base object-cover" });
|
|
1919
|
+
}
|
|
1920
|
+
function Dialog({ data, displayId, onClose }) {
|
|
1921
|
+
const t = useText();
|
|
1922
|
+
const lang = t === TEXT.pl ? "pl-PL" : "en-GB";
|
|
1923
|
+
const [partsOpen, setPartsOpen] = react.useState(false);
|
|
1924
|
+
react.useEffect(() => {
|
|
1925
|
+
const k = (e) => e.key === "Escape" && onClose();
|
|
1926
|
+
window.addEventListener("keydown", k);
|
|
1927
|
+
return () => window.removeEventListener("keydown", k);
|
|
1928
|
+
}, [onClose]);
|
|
1929
|
+
const main = data.items.filter((p) => !p.component);
|
|
1930
|
+
const parts = data.items.filter((p) => p.component);
|
|
1931
|
+
const pcs = main.reduce((s, p) => s + p.quantity, 0);
|
|
1932
|
+
const value = data.items.reduce((s, p) => s + p.unitPrice * p.quantity, 0);
|
|
1933
|
+
return reactDom.createPortal(
|
|
1934
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "fixed inset-0 z-[100] flex items-center justify-center bg-black/40 p-4", onClick: onClose, role: "presentation", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { role: "dialog", "aria-modal": "true", "aria-label": `${t.title} ${displayId ? `#${displayId}` : ""}`, className: "flex max-h-[85vh] w-full max-w-2xl flex-col overflow-hidden rounded-xl border border-ui-border-base bg-ui-bg-base shadow-elevation-modal", onClick: (e) => e.stopPropagation(), children: [
|
|
1935
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-4 border-b border-ui-border-base px-5 py-4", children: [
|
|
1936
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1937
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { weight: "plus", children: [
|
|
1938
|
+
t.title,
|
|
1939
|
+
displayId ? ` ${t.ofOrder} #${displayId}` : ""
|
|
1940
|
+
] }),
|
|
1941
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: [
|
|
1942
|
+
main.length,
|
|
1943
|
+
" ",
|
|
1944
|
+
t.lines,
|
|
1945
|
+
", ",
|
|
1946
|
+
pcs,
|
|
1947
|
+
" ",
|
|
1948
|
+
t.pcs,
|
|
1949
|
+
parts.length ? `, ${parts.length} ${t.components}` : "",
|
|
1950
|
+
", ",
|
|
1951
|
+
money(value, data.currency, lang)
|
|
1952
|
+
] })
|
|
1953
|
+
] }),
|
|
1954
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", onClick: onClose, children: t.close })
|
|
1955
|
+
] }),
|
|
1956
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 overflow-y-auto px-5 py-2", children: [
|
|
1957
|
+
main.map((p) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 border-b border-ui-border-base py-3 last:border-0", children: [
|
|
1958
|
+
/* @__PURE__ */ jsxRuntime.jsx(Thumb, { src: p.thumbnail, size: 48, title: p.title }),
|
|
1959
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
1960
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", className: "truncate", children: p.title }),
|
|
1961
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-fg-subtle", children: [p.variant, p.sku ? `SKU ${p.sku}` : null, p.barcode ? `EAN ${p.barcode}` : null].filter(Boolean).join(", ") || "-" })
|
|
1962
|
+
] }),
|
|
1963
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-right", children: [
|
|
1964
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "small", weight: "plus", className: "tabular-nums", children: [
|
|
1965
|
+
p.quantity,
|
|
1966
|
+
" × ",
|
|
1967
|
+
money(p.unitPrice, data.currency, lang)
|
|
1968
|
+
] }),
|
|
1969
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "tabular-nums text-ui-fg-subtle", children: money(p.unitPrice * p.quantity, data.currency, lang) })
|
|
1970
|
+
] })
|
|
1971
|
+
] }, p.id)),
|
|
1972
|
+
parts.length ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "py-3", children: [
|
|
1973
|
+
/* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", className: "txt-small-plus text-ui-fg-interactive", onClick: () => setPartsOpen((v) => !v), children: [
|
|
1974
|
+
partsOpen ? t.hideParts : t.showParts,
|
|
1975
|
+
" (",
|
|
1976
|
+
parts.length,
|
|
1977
|
+
")"
|
|
1978
|
+
] }),
|
|
1979
|
+
partsOpen ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-2 grid grid-cols-1 gap-x-4 gap-y-1 sm:grid-cols-2", children: parts.map((p) => /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "xsmall", className: "text-ui-fg-subtle", children: [
|
|
1980
|
+
p.quantity,
|
|
1981
|
+
" × ",
|
|
1982
|
+
p.title,
|
|
1983
|
+
p.variant ? ` (${p.variant})` : ""
|
|
1984
|
+
] }, p.id)) }) : null
|
|
1985
|
+
] }) : null,
|
|
1986
|
+
!data.items.length ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "py-6 text-center text-ui-fg-subtle", children: t.empty }) : null
|
|
1987
|
+
] })
|
|
1988
|
+
] }) }),
|
|
1989
|
+
document.body
|
|
1990
|
+
);
|
|
1991
|
+
}
|
|
1992
|
+
function KitOpenDialogIcon({ size = 14 }) {
|
|
1993
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
|
|
1994
|
+
/* @__PURE__ */ jsxRuntime.jsx("rect", { x: "3", y: "3", width: "18", height: "18", rx: "3" }),
|
|
1995
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M14 7h3v3" }),
|
|
1996
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M17 7l-4 4" }),
|
|
1997
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M10 17H7v-3" }),
|
|
1998
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M7 17l4-4" })
|
|
1999
|
+
] });
|
|
2000
|
+
}
|
|
2001
|
+
const SINGLE = 88;
|
|
2002
|
+
const CARD = 72;
|
|
2003
|
+
const MAX_CARDS = 4;
|
|
2004
|
+
function KitOrderProductsCell({ data, loading, displayId }) {
|
|
2005
|
+
const t = useText();
|
|
2006
|
+
const [open, setOpen] = react.useState(false);
|
|
2007
|
+
if (!data)
|
|
2008
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-fg-muted", children: loading ? "…" : "-" });
|
|
2009
|
+
const main = data.items.filter((p) => !p.component);
|
|
2010
|
+
const pool = main.length ? main : data.items;
|
|
2011
|
+
if (!pool.length)
|
|
2012
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-fg-muted", children: "-" });
|
|
2013
|
+
const shown = pool.slice(0, pool.length > MAX_CARDS ? MAX_CARDS - 1 : MAX_CARDS);
|
|
2014
|
+
const rest = pool.length - shown.length;
|
|
2015
|
+
const size = pool.length === 1 ? SINGLE : CARD;
|
|
2016
|
+
const show = (e) => {
|
|
2017
|
+
e.stopPropagation();
|
|
2018
|
+
e.preventDefault();
|
|
2019
|
+
setOpen(true);
|
|
2020
|
+
};
|
|
2021
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-start gap-y-2", onClick: (e) => e.stopPropagation(), children: [
|
|
2022
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2023
|
+
"button",
|
|
2024
|
+
{
|
|
2025
|
+
type: "button",
|
|
2026
|
+
onClick: show,
|
|
2027
|
+
className: "inline-flex items-center gap-x-1 txt-compact-small-plus text-ui-fg-interactive underline-offset-2 transition-fg hover:text-ui-fg-interactive-hover hover:underline",
|
|
2028
|
+
title: t.show,
|
|
2029
|
+
children: [
|
|
2030
|
+
t.button,
|
|
2031
|
+
/* @__PURE__ */ jsxRuntime.jsx(KitOpenDialogIcon, {})
|
|
2032
|
+
]
|
|
2033
|
+
}
|
|
2034
|
+
),
|
|
2035
|
+
/* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", onClick: show, className: "isolate flex items-center py-1", "aria-label": `${t.title}${displayId ? ` #${displayId}` : ""}: ${pool.length}`, children: [
|
|
2036
|
+
shown.map((p, i) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
2037
|
+
"span",
|
|
2038
|
+
{
|
|
2039
|
+
style: { marginLeft: i ? -40 : 0, zIndex: i + 1 },
|
|
2040
|
+
className: "relative rounded-lg bg-ui-bg-base shadow-elevation-card-rest ring-2 ring-ui-bg-base transition-transform duration-200 ease-out hover:!z-30 hover:scale-[1.15]",
|
|
2041
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Thumb, { src: p.thumbnail, size, title: `${p.quantity} × ${p.title}${p.variant ? ` (${p.variant})` : ""}` })
|
|
2042
|
+
},
|
|
2043
|
+
p.id
|
|
2044
|
+
)),
|
|
2045
|
+
rest > 0 ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2046
|
+
"span",
|
|
2047
|
+
{
|
|
2048
|
+
style: { marginLeft: -40, zIndex: shown.length + 1, width: CARD, height: CARD },
|
|
2049
|
+
className: "relative flex items-center justify-end rounded-lg bg-ui-bg-component pr-3 shadow-elevation-card-rest ring-2 ring-ui-bg-base txt-compact-small-plus text-ui-fg-subtle",
|
|
2050
|
+
children: [
|
|
2051
|
+
"+",
|
|
2052
|
+
rest
|
|
2053
|
+
]
|
|
2054
|
+
}
|
|
2055
|
+
) : null
|
|
1517
2056
|
] }),
|
|
1518
|
-
|
|
2057
|
+
open ? /* @__PURE__ */ jsxRuntime.jsx(Dialog, { data, displayId: displayId ?? null, onClose: () => setOpen(false) }) : null
|
|
1519
2058
|
] });
|
|
1520
2059
|
}
|
|
2060
|
+
const PAGE_SIZE$1 = 15;
|
|
1521
2061
|
const LEVEL_TEXT = {
|
|
1522
2062
|
ok: "text-ui-fg-base",
|
|
1523
2063
|
warn: "text-ui-tag-orange-text",
|
|
@@ -1538,54 +2078,65 @@ function BridgeSection({ status, lang }) {
|
|
|
1538
2078
|
const licence = ((_a = h == null ? void 0 : h.subiekt) == null ? void 0 : _a.licence) === "ok" || ((_b = h == null ? void 0 : h.subiekt) == null ? void 0 : _b.licence) === "refused" ? h.subiekt.licence : "unknown";
|
|
1539
2079
|
const signatureTone = d.signature === "ok" ? LEVEL_TEXT.ok : d.signature === "unknown" ? LEVEL_TEXT.unknown : LEVEL_TEXT.error;
|
|
1540
2080
|
const rejectedLater = Boolean(d.webhook.rejectedAt && (!d.webhook.lastAt || d.webhook.rejectedAt > d.webhook.lastAt));
|
|
1541
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
hint
|
|
1582
|
-
"
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
2081
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2082
|
+
Section,
|
|
2083
|
+
{
|
|
2084
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(icons.ComputerDesktop, {}),
|
|
2085
|
+
title: t("bridge.title"),
|
|
2086
|
+
points: [
|
|
2087
|
+
{ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.Clock, {}), text: t("bridge.points.last") },
|
|
2088
|
+
{ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.ShieldCheck, {}), text: t("bridge.points.fresh") }
|
|
2089
|
+
],
|
|
2090
|
+
pointsLabel: t("bridge.subtitle"),
|
|
2091
|
+
children: [
|
|
2092
|
+
d.legacy ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-6 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(ui.InlineTip, { variant: "warning", label: t("bridge.title"), children: t("bridge.legacy") }) }) : null,
|
|
2093
|
+
status.mode === "live" && ((_c = h == null ? void 0 : h.bridge) == null ? void 0 : _c.mode) === "fake" ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-6 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(ui.InlineTip, { variant: "warning", label: t("bridge.title"), children: t("bridge.fakeMode") }) }) : null,
|
|
2094
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "py-2", children: [
|
|
2095
|
+
/* @__PURE__ */ jsxRuntime.jsx(Field, { label: t("bridge.versions"), children: t("bridge.versionsValue", { bridge: ((_d = h == null ? void 0 : h.bridge) == null ? void 0 : _d.version) ?? "?", contract: ((_e = h == null ? void 0 : h.bridge) == null ? void 0 : _e.contract) ?? "?", plugin: status.pluginVersion }) }),
|
|
2096
|
+
/* @__PURE__ */ jsxRuntime.jsx(Field, { label: t("bridge.sdk"), children: h ? t("bridge.sdkValue", { sdk: ((_f = h.bridge) == null ? void 0 : _f.sdk_version) ?? none, db: ((_g = h.subiekt) == null ? void 0 : _g.database_version) ?? none }) : none }),
|
|
2097
|
+
/* @__PURE__ */ jsxRuntime.jsx(Field, { label: t("bridge.licence"), children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: licence === "refused" ? LEVEL_TEXT.error : licence === "ok" ? LEVEL_TEXT.ok : LEVEL_TEXT.unknown, children: t(`bridge.licenceStates.${licence}`) }) }),
|
|
2098
|
+
/* @__PURE__ */ jsxRuntime.jsx(Field, { label: t("bridge.started"), children: fmtDateTime((_h = h == null ? void 0 : h.bridge) == null ? void 0 : _h.started_at, lang) || none }),
|
|
2099
|
+
/* @__PURE__ */ jsxRuntime.jsx(Field, { label: t("bridge.latency"), children: fmtMs(d.latencyMs) }),
|
|
2100
|
+
/* @__PURE__ */ jsxRuntime.jsx(Field, { label: t("bridge.skew"), children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: LEVEL_TEXT[skew], children: t(`bridge.skewStates.${skew}`, { value: d.clockSkewMs === null ? "" : signedMs(d.clockSkewMs) }) }) }),
|
|
2101
|
+
/* @__PURE__ */ jsxRuntime.jsx(Field, { label: t("bridge.signature"), children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: signatureTone, children: t(`bridge.signatureStates.${d.signature}`, { defaultValue: d.signature }) }) }),
|
|
2102
|
+
/* @__PURE__ */ jsxRuntime.jsx(Field, { label: t("bridge.lastEvent"), children: (h == null ? void 0 : h.events) ? t("bridge.lastEventValue", { id: h.events.last_id, time: fmtDateTime(h.events.last_at, lang) || none }) : none }),
|
|
2103
|
+
/* @__PURE__ */ jsxRuntime.jsx(Field, { label: t("bridge.queues"), children: (h == null ? void 0 : h.queues) ? t("bridge.queuesValue", { sfera: h.queues.sfera_pending, webhook: h.queues.webhook_pending }) : none }),
|
|
2104
|
+
/* @__PURE__ */ jsxRuntime.jsx(Field, { label: t("bridge.webhook"), children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
|
|
2105
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: d.webhook.lastAt ? t("bridge.webhookValue", { time: fmtDateTime(d.webhook.lastAt, lang) }) : t("bridge.webhookNever") }),
|
|
2106
|
+
rejectedLater ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: LEVEL_TEXT.warn, children: t("bridge.webhookRejected", {
|
|
2107
|
+
time: fmtDateTime(d.webhook.rejectedAt, lang),
|
|
2108
|
+
reason: t(`bridge.webhookReasons.${d.webhook.rejectReason ?? "missing"}`, { defaultValue: d.webhook.rejectReason ?? "" })
|
|
2109
|
+
}) }) : null
|
|
2110
|
+
] }) }),
|
|
2111
|
+
/* @__PURE__ */ jsxRuntime.jsx(Field, { label: t("connection.checkedAt"), children: fmtDateTime(d.checkedAt, lang) || t("connection.never") })
|
|
2112
|
+
] }),
|
|
2113
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-3 px-6 py-4", children: [
|
|
2114
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-1", children: [
|
|
2115
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-fg-subtle", children: t("bridge.capabilities") }),
|
|
2116
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-1", children: d.capabilities.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: none }) : d.capabilities.map((c) => /* @__PURE__ */ jsxRuntime.jsx(ToneBadge, { tone: "green", children: t(`bridge.capabilityNames.${c}`, { defaultValue: c }) }, c)) })
|
|
2117
|
+
] }),
|
|
2118
|
+
d.missing.length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-1", children: [
|
|
2119
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-fg-subtle", children: t("bridge.cannot") }),
|
|
2120
|
+
/* @__PURE__ */ jsxRuntime.jsx("ul", { className: "flex flex-col gap-y-1", children: d.missing.map((m) => {
|
|
2121
|
+
const hint = m.reason === "bridge_config" ? t(`bridge.capabilityHints.${m.capability}`, { defaultValue: "" }) : "";
|
|
2122
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("li", { className: "txt-compact-small flex flex-wrap gap-x-1", children: [
|
|
2123
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-ui-fg-base", children: [
|
|
2124
|
+
t(`bridge.capabilityNames.${m.capability}`, { defaultValue: m.capability }),
|
|
2125
|
+
":"
|
|
2126
|
+
] }),
|
|
2127
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-ui-fg-subtle", children: t(`bridge.reasons.${m.reason}`, { defaultValue: m.reason }) }),
|
|
2128
|
+
hint ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-mono text-ui-fg-muted", children: [
|
|
2129
|
+
"(",
|
|
2130
|
+
hint,
|
|
2131
|
+
")"
|
|
2132
|
+
] }) : null
|
|
2133
|
+
] }, m.capability);
|
|
2134
|
+
}) })
|
|
2135
|
+
] }) : null
|
|
2136
|
+
] })
|
|
2137
|
+
]
|
|
2138
|
+
}
|
|
2139
|
+
);
|
|
1589
2140
|
}
|
|
1590
2141
|
const WRITER_ORDER = ["documents", "contractors", "prices", "products"];
|
|
1591
2142
|
function WriterRow({ writer, status, lang }) {
|
|
@@ -1619,15 +2170,14 @@ function WriterRow({ writer, status, lang }) {
|
|
|
1619
2170
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-col gap-1.5", children: [
|
|
1620
2171
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
1621
2172
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", className: "text-ui-fg-base", children: name }),
|
|
1622
|
-
writer.active ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
1623
|
-
/* @__PURE__ */ jsxRuntime.
|
|
1624
|
-
writer.allowed ? null : /* @__PURE__ */ jsxRuntime.jsx(icons.LockClosedSolid, {}),
|
|
2173
|
+
writer.active ? /* @__PURE__ */ jsxRuntime.jsx(ToneBadge, { tone: "green", children: t("writers.active") }) : writer.armed ? /* @__PURE__ */ jsxRuntime.jsx(ToneBadge, { tone: "orange", children: t("writers.blocked") }) : /* @__PURE__ */ jsxRuntime.jsx(ToneBadge, { children: t("writers.disarmed") }),
|
|
2174
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ToneBadge, { icon: writer.allowed ? void 0 : /* @__PURE__ */ jsxRuntime.jsx(icons.LockClosedSolid, {}), children: [
|
|
1625
2175
|
t("writers.option", { option: writer.option }),
|
|
1626
2176
|
" ",
|
|
1627
2177
|
writer.allowed ? t("writers.allowed") : t("writers.forbidden")
|
|
1628
|
-
] })
|
|
2178
|
+
] })
|
|
1629
2179
|
] }),
|
|
1630
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "
|
|
2180
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: description }),
|
|
1631
2181
|
writer.unsupported ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-tag-orange-text", children: t("writers.unsupported") }) : null,
|
|
1632
2182
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-fg-muted", children: writer.changedAt ? t(writer.armed ? "writers.armedBy" : "writers.disarmedBy", { who: writer.changedBy ?? "?", time: fmtDateTime(writer.changedAt, lang) }) : t("writers.never") })
|
|
1633
2183
|
] }),
|
|
@@ -1637,13 +2187,34 @@ function WriterRow({ writer, status, lang }) {
|
|
|
1637
2187
|
function WritersSection({ status, lang }) {
|
|
1638
2188
|
const { t } = reactI18next.useTranslation("subiekt");
|
|
1639
2189
|
const writers = WRITER_ORDER.map((k) => status.writers.find((w) => w.key === k)).filter((w) => Boolean(w));
|
|
1640
|
-
return /* @__PURE__ */ jsxRuntime.
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
2190
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2191
|
+
Section,
|
|
2192
|
+
{
|
|
2193
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(icons.LockClosedSolid, {}),
|
|
2194
|
+
title: t("writers.title"),
|
|
2195
|
+
badges: status.mode === "demo" ? /* @__PURE__ */ jsxRuntime.jsx(ToneBadge, { tone: "blue", title: t("writers.demoNote"), children: t("widget.demo") }) : null,
|
|
2196
|
+
points: [
|
|
2197
|
+
{ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.PencilSquare, {}), text: t("writers.points.option") },
|
|
2198
|
+
{ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.User, {}), text: t("writers.points.person") },
|
|
2199
|
+
{ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.LockClosedSolid, {}), text: t("writers.points.falseWins") }
|
|
2200
|
+
],
|
|
2201
|
+
pointsLabel: t("writers.subtitle"),
|
|
2202
|
+
children: writers.map((w) => /* @__PURE__ */ jsxRuntime.jsx(WriterRow, { writer: w, status, lang }, w.key))
|
|
2203
|
+
}
|
|
2204
|
+
);
|
|
1645
2205
|
}
|
|
1646
2206
|
const STATUS_FILTERS = ["planned", "applied", "simulated", "over_cap", "stale", "failed", "quarantined", "skipped"];
|
|
2207
|
+
const STATUS_ICON = {
|
|
2208
|
+
planned: /* @__PURE__ */ jsxRuntime.jsx(icons.Clock, {}),
|
|
2209
|
+
applied: /* @__PURE__ */ jsxRuntime.jsx(icons.CheckCircle, {}),
|
|
2210
|
+
simulated: /* @__PURE__ */ jsxRuntime.jsx(icons.Beaker, {}),
|
|
2211
|
+
over_cap: /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowLongRight, {}),
|
|
2212
|
+
stale: /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowPath, {}),
|
|
2213
|
+
failed: /* @__PURE__ */ jsxRuntime.jsx(icons.XCircle, {}),
|
|
2214
|
+
quarantined: /* @__PURE__ */ jsxRuntime.jsx(icons.ExclamationCircle, {}),
|
|
2215
|
+
skipped: /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowUturnLeft, {})
|
|
2216
|
+
};
|
|
2217
|
+
const STATUS_ATTENTION = /* @__PURE__ */ new Set(["failed", "quarantined", "stale"]);
|
|
1647
2218
|
function ChangeCell({ change, lang }) {
|
|
1648
2219
|
const { t } = reactI18next.useTranslation("subiekt");
|
|
1649
2220
|
if (change.kind === "create") return /* @__PURE__ */ jsxRuntime.jsx("span", { children: t("products.newProduct", { price: fmtMoney(change.to, change.currency, lang) }) });
|
|
@@ -1689,7 +2260,7 @@ function ProductsSection({ status, lang, poll, onAction }) {
|
|
|
1689
2260
|
const [filter, setFilter] = react.useState("all");
|
|
1690
2261
|
const [search, setSearch] = react.useState("");
|
|
1691
2262
|
const [offset, setOffset] = react.useState(0);
|
|
1692
|
-
const q = search.trim();
|
|
2263
|
+
const q = useDebouncedValue(search).trim();
|
|
1693
2264
|
const running = status.running.includes("products");
|
|
1694
2265
|
const products = useSubiektProducts(kind, filter, q, offset, PAGE_SIZE$1, poll || running);
|
|
1695
2266
|
const sync = useSubiektSync();
|
|
@@ -1738,112 +2309,147 @@ function ProductsSection({ status, lang, poll, onAction }) {
|
|
|
1738
2309
|
["unmatchedVariants", stats.unmatchedVariants, true],
|
|
1739
2310
|
["noPrice", stats.noPrice, true]
|
|
1740
2311
|
] : [];
|
|
1741
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
/* @__PURE__ */ jsxRuntime.
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-1 px-6 py-3", children: [
|
|
1751
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", children: settings }),
|
|
1752
|
-
run ? /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "xsmall", className: "text-ui-fg-muted", children: [
|
|
1753
|
-
runSummary(run, t),
|
|
1754
|
-
" ",
|
|
1755
|
-
fmtDateTime(run.startedAt, lang),
|
|
1756
|
-
", ",
|
|
1757
|
-
fmtDuration(run.durationMs)
|
|
1758
|
-
] }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-fg-muted", children: t("products.never") })
|
|
1759
|
-
] }),
|
|
1760
|
-
!o.productSyncEnabled ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-6 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(ui.InlineTip, { variant: "info", label: t("products.title"), children: t("products.disabled") }) }) : !supported ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-6 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(ui.InlineTip, { variant: "warning", label: t("products.title"), children: t("products.unsupported") }) }) : null,
|
|
1761
|
-
(stats == null ? void 0 : stats.blocked) ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-6 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(ui.InlineTip, { variant: "warning", label: t("products.title"), children: t(`products.blocked.${stats.blocked}`) }) }) : null,
|
|
1762
|
-
counters.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 gap-x-4 gap-y-2 px-6 py-4 sm:grid-cols-4", children: counters.map(([key, value, warn]) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
|
|
1763
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-fg-subtle", children: t(`products.counters.${key}`) }),
|
|
1764
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", className: ui.clx("tabular-nums", warn && value ? "text-ui-tag-orange-text" : void 0), children: fmtNumber(value ?? 0, lang) })
|
|
1765
|
-
] }, key)) }) : null,
|
|
1766
|
-
(stats == null ? void 0 : stats.samples) && (((_a = stats.samples.conflicts) == null ? void 0 : _a.length) || ((_b = stats.samples.unmatchedVariants) == null ? void 0 : _b.length) || ((_c = stats.samples.noPrice) == null ? void 0 : _c.length)) ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-3 px-6 py-4", children: [
|
|
1767
|
-
((_d = stats.samples.conflicts) == null ? void 0 : _d.length) ? /* @__PURE__ */ jsxRuntime.jsx(SampleList, { label: t("products.samples.conflicts"), items: stats.samples.conflicts }) : null,
|
|
1768
|
-
((_e = stats.samples.unmatchedVariants) == null ? void 0 : _e.length) ? /* @__PURE__ */ jsxRuntime.jsx(SampleList, { label: t("products.samples.unmatchedVariants"), items: stats.samples.unmatchedVariants }) : null,
|
|
1769
|
-
((_f = stats.samples.noPrice) == null ? void 0 : _f.length) ? /* @__PURE__ */ jsxRuntime.jsx(SampleList, { label: t("products.samples.noPrice"), items: stats.samples.noPrice }) : null
|
|
1770
|
-
] }) : null,
|
|
1771
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 px-6 py-3", children: [
|
|
1772
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
|
|
1773
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1774
|
-
FilterPills,
|
|
1775
|
-
{
|
|
1776
|
-
value: kind,
|
|
1777
|
-
onChange: setKind,
|
|
1778
|
-
options: [
|
|
1779
|
-
{ value: "all", label: t("products.statuses.all") },
|
|
1780
|
-
{ value: "price", label: t("products.kinds.price") },
|
|
1781
|
-
{ value: "create", label: t("products.kinds.create") }
|
|
1782
|
-
]
|
|
1783
|
-
}
|
|
1784
|
-
),
|
|
1785
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full md:w-56", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { size: "small", type: "search", placeholder: t("products.search"), value: search, onChange: (e) => setSearch(e.target.value) }) })
|
|
2312
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2313
|
+
Section,
|
|
2314
|
+
{
|
|
2315
|
+
id: "subiekt-products",
|
|
2316
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(icons.Tag, {}),
|
|
2317
|
+
title: t("products.title"),
|
|
2318
|
+
badges: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2319
|
+
(run == null ? void 0 : run.dryRun) ? /* @__PURE__ */ jsxRuntime.jsx(ToneBadge, { tone: "blue", children: t("stock.dryRun") }) : null,
|
|
2320
|
+
run ? /* @__PURE__ */ jsxRuntime.jsx(RunStatusBadge, { status: run.status }) : null
|
|
1786
2321
|
] }),
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
{
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
] }),
|
|
1799
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-x-auto", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Table, { children: [
|
|
1800
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.Header, { children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Table.Row, { children: [
|
|
1801
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { children: t("products.columns.product") }),
|
|
1802
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { children: t("products.columns.change") }),
|
|
1803
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { children: /* @__PURE__ */ jsxRuntime.jsx(StoreColumn, { label: t("products.columns.store"), hint: t("products.matching") }) }),
|
|
1804
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { children: t("products.columns.status") }),
|
|
1805
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { children: t("products.columns.details") })
|
|
1806
|
-
] }) }),
|
|
1807
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.Body, { children: rows.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(ui.Table.Row, { children: /* @__PURE__ */ jsxRuntime.jsx("td", { colSpan: 5, className: "px-6 py-6 text-center", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: products.isLoading ? "" : t("products.empty") }) }) }) : rows.map((c) => /* @__PURE__ */ jsxRuntime.jsxs(ui.Table.Row, { className: "[&_td]:py-2.5", children: [
|
|
1808
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { className: "max-w-[240px]", children: /* @__PURE__ */ jsxRuntime.jsx(SubiektProductCell, { change: c }) }),
|
|
1809
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(ChangeCell, { change: c, lang }) }),
|
|
1810
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { className: "max-w-[300px]", children: /* @__PURE__ */ jsxRuntime.jsx(StoreProductCell, { change: c }) }),
|
|
1811
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(CatalogStatusBadge, { status: c.status }) }),
|
|
1812
|
-
/* @__PURE__ */ jsxRuntime.jsxs(ui.Table.Cell, { className: "max-w-md", children: [
|
|
1813
|
-
c.lastError ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: c.status === "failed" || c.status === "quarantined" ? "text-ui-tag-red-text" : "text-ui-fg-subtle", children: c.lastError }) : null,
|
|
1814
|
-
c.appliedAt ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-fg-muted", children: fmtDateTime(c.appliedAt, lang) }) : null
|
|
2322
|
+
points: [
|
|
2323
|
+
{ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.ListBullet, {}), text: t("products.points.plan") },
|
|
2324
|
+
{ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.MagnifyingGlass, {}), text: t("products.points.match"), title: t("products.matching") },
|
|
2325
|
+
{ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.LockClosedSolid, {}), text: t("products.points.writer") }
|
|
2326
|
+
],
|
|
2327
|
+
pointsLabel: t("products.subtitle"),
|
|
2328
|
+
actions: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2329
|
+
/* @__PURE__ */ jsxRuntime.jsx(SearchInput, { value: search, onChange: setSearch, placeholder: t("products.search") }),
|
|
2330
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Button, { size: "small", variant: "secondary", disabled: !ready || !supported || !o.productSyncEnabled || running, isLoading: sync.isPending, onClick: onRead, children: [
|
|
2331
|
+
/* @__PURE__ */ jsxRuntime.jsx(icons.ArrowPath, {}),
|
|
2332
|
+
running ? t("actions.running") : t("actions.products")
|
|
1815
2333
|
] })
|
|
1816
|
-
] },
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-fg-muted", children: t("products.quarantineHint") }),
|
|
1822
|
-
/* @__PURE__ */ jsxRuntime.jsx("ul", { className: "flex flex-col divide-y", children: data.quarantined.map((item) => /* @__PURE__ */ jsxRuntime.jsxs("li", { className: "flex items-start justify-between gap-x-4 py-2", children: [
|
|
1823
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-col", children: [
|
|
1824
|
-
/* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "small", className: "font-mono", children: [
|
|
1825
|
-
t(`products.kinds.${item.kind}`),
|
|
1826
|
-
": ",
|
|
1827
|
-
item.key
|
|
1828
|
-
] }),
|
|
1829
|
-
item.lastError ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-tag-red-text", children: item.lastError }) : null
|
|
2334
|
+
] }),
|
|
2335
|
+
children: [
|
|
2336
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-1 px-6 py-3", children: [
|
|
2337
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", children: settings }),
|
|
2338
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-fg-muted", children: run ? `${runSummary(run, t)} ${fmtDateTime(run.startedAt, lang)}, ${fmtDuration(run.durationMs)}` : t("products.never") })
|
|
1830
2339
|
] }),
|
|
1831
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
2340
|
+
!o.productSyncEnabled ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-6 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(ui.InlineTip, { variant: "info", label: t("products.title"), children: t("products.disabled") }) }) : !supported ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-6 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(ui.InlineTip, { variant: "warning", label: t("products.title"), children: t("products.unsupported") }) }) : null,
|
|
2341
|
+
(stats == null ? void 0 : stats.blocked) ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-6 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(ui.InlineTip, { variant: "warning", label: t("products.title"), children: t(`products.blocked.${stats.blocked}`) }) }) : null,
|
|
2342
|
+
counters.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(StatTiles, { columns: 4, children: counters.map(([key, value, warn]) => /* @__PURE__ */ jsxRuntime.jsx(StatTile, { label: t(`products.counters.${key}`), value: fmtNumber(value ?? 0, lang), tone: warn && value ? "orange" : "grey" }, key)) }) : null,
|
|
2343
|
+
(stats == null ? void 0 : stats.samples) && (((_a = stats.samples.conflicts) == null ? void 0 : _a.length) || ((_b = stats.samples.unmatchedVariants) == null ? void 0 : _b.length) || ((_c = stats.samples.noPrice) == null ? void 0 : _c.length)) ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-3 px-6 py-4", children: [
|
|
2344
|
+
((_d = stats.samples.conflicts) == null ? void 0 : _d.length) ? /* @__PURE__ */ jsxRuntime.jsx(SampleList, { label: t("products.samples.conflicts"), items: stats.samples.conflicts }) : null,
|
|
2345
|
+
((_e = stats.samples.unmatchedVariants) == null ? void 0 : _e.length) ? /* @__PURE__ */ jsxRuntime.jsx(SampleList, { label: t("products.samples.unmatchedVariants"), items: stats.samples.unmatchedVariants }) : null,
|
|
2346
|
+
((_f = stats.samples.noPrice) == null ? void 0 : _f.length) ? /* @__PURE__ */ jsxRuntime.jsx(SampleList, { label: t("products.samples.noPrice"), items: stats.samples.noPrice }) : null
|
|
2347
|
+
] }) : null,
|
|
2348
|
+
/* @__PURE__ */ jsxRuntime.jsxs(FilterBar, { children: [
|
|
2349
|
+
/* @__PURE__ */ jsxRuntime.jsx(FilterButton, { icon: /* @__PURE__ */ jsxRuntime.jsx(icons.ListBullet, {}), label: t("products.statuses.all"), count: summary == null ? void 0 : summary.total, active: kind === "all" && filter === "all", onClick: () => (setKind("all"), setFilter("all")) }),
|
|
2350
|
+
/* @__PURE__ */ jsxRuntime.jsx(FilterButton, { icon: /* @__PURE__ */ jsxRuntime.jsx(icons.Tag, {}), label: t("products.kinds.price"), active: kind === "price", onClick: () => setKind(kind === "price" ? "all" : "price") }),
|
|
2351
|
+
/* @__PURE__ */ jsxRuntime.jsx(FilterButton, { icon: /* @__PURE__ */ jsxRuntime.jsx(icons.Plus, {}), label: t("products.kinds.create"), active: kind === "create", onClick: () => setKind(kind === "create" ? "all" : "create") }),
|
|
2352
|
+
STATUS_FILTERS.some((st) => ((summary == null ? void 0 : summary[st]) ?? 0) > 0 || st === filter) ? /* @__PURE__ */ jsxRuntime.jsx(FilterDivider, {}) : null,
|
|
2353
|
+
STATUS_FILTERS.filter((st) => ((summary == null ? void 0 : summary[st]) ?? 0) > 0 || st === filter).map((st) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
2354
|
+
FilterButton,
|
|
2355
|
+
{
|
|
2356
|
+
icon: STATUS_ICON[st],
|
|
2357
|
+
label: t(`products.statuses.${st}`),
|
|
2358
|
+
count: summary == null ? void 0 : summary[st],
|
|
2359
|
+
attention: STATUS_ATTENTION.has(st),
|
|
2360
|
+
active: filter === st,
|
|
2361
|
+
onClick: () => setFilter(filter === st ? "all" : st)
|
|
2362
|
+
},
|
|
2363
|
+
st
|
|
2364
|
+
))
|
|
2365
|
+
] }),
|
|
2366
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-x-auto", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Table, { children: [
|
|
2367
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.Header, { children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Table.Row, { children: [
|
|
2368
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { children: t("products.columns.product") }),
|
|
2369
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { children: t("products.columns.change") }),
|
|
2370
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { children: /* @__PURE__ */ jsxRuntime.jsx(StoreColumn, { label: t("products.columns.store"), hint: t("products.matching") }) }),
|
|
2371
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { children: t("products.columns.status") }),
|
|
2372
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { children: t("products.columns.details") })
|
|
2373
|
+
] }) }),
|
|
2374
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.Body, { children: products.isLoading ? /* @__PURE__ */ jsxRuntime.jsx(KitSkeletonRows, { cols: 5, rows: 4 }) : rows.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(EmptyTableRow, { cols: 5, icon: /* @__PURE__ */ jsxRuntime.jsx(icons.Tag, {}), title: t("products.empty") }) : rows.map((c) => /* @__PURE__ */ jsxRuntime.jsxs(ui.Table.Row, { className: "[&_td]:py-2.5", children: [
|
|
2375
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { className: "max-w-[240px]", children: /* @__PURE__ */ jsxRuntime.jsx(SubiektProductCell, { change: c }) }),
|
|
2376
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(ChangeCell, { change: c, lang }) }),
|
|
2377
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { className: "max-w-[300px]", children: /* @__PURE__ */ jsxRuntime.jsx(StoreProductCell, { change: c }) }),
|
|
2378
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(CatalogStatusBadge, { status: c.status, dot: true }) }),
|
|
2379
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Table.Cell, { className: "max-w-md", children: [
|
|
2380
|
+
c.lastError ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: c.status === "failed" || c.status === "quarantined" ? "text-ui-tag-red-text" : "text-ui-fg-subtle", children: c.lastError }) : null,
|
|
2381
|
+
c.appliedAt ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-fg-muted", children: fmtDateTime(c.appliedAt, lang) }) : null
|
|
2382
|
+
] })
|
|
2383
|
+
] }, c.id)) })
|
|
2384
|
+
] }) }),
|
|
2385
|
+
/* @__PURE__ */ jsxRuntime.jsx(Pager, { offset, limit: PAGE_SIZE$1, count: (data == null ? void 0 : data.count) ?? 0, onChange: setOffset }),
|
|
2386
|
+
data && data.quarantined.length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-2 px-6 py-4", children: [
|
|
2387
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex flex-wrap items-center gap-2", children: [
|
|
2388
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: t("products.quarantine") }),
|
|
2389
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2390
|
+
KeyPoints,
|
|
2391
|
+
{
|
|
2392
|
+
items: [
|
|
2393
|
+
{ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.ExclamationCircle, {}), text: t("products.quarantinePoints.skipped"), tone: "orange" },
|
|
2394
|
+
{ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.PencilSquare, {}), text: t("products.quarantinePoints.fix") }
|
|
2395
|
+
],
|
|
2396
|
+
label: t("products.quarantineHint")
|
|
2397
|
+
}
|
|
2398
|
+
)
|
|
2399
|
+
] }),
|
|
2400
|
+
/* @__PURE__ */ jsxRuntime.jsx("ul", { className: "flex flex-col divide-y", children: data.quarantined.map((item) => /* @__PURE__ */ jsxRuntime.jsxs("li", { className: "flex items-start justify-between gap-x-4 py-2", children: [
|
|
2401
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-col", children: [
|
|
2402
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "small", className: "font-mono", children: [
|
|
2403
|
+
t(`products.kinds.${item.kind}`),
|
|
2404
|
+
": ",
|
|
2405
|
+
item.key
|
|
2406
|
+
] }),
|
|
2407
|
+
item.lastError ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-tag-red-text", children: item.lastError }) : null
|
|
2408
|
+
] }),
|
|
2409
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2410
|
+
RowActions,
|
|
2411
|
+
{
|
|
2412
|
+
actions: [
|
|
2413
|
+
{
|
|
2414
|
+
key: "release",
|
|
2415
|
+
label: t("actions.release"),
|
|
2416
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowUturnLeft, {}),
|
|
2417
|
+
loading: release.isPending && release.variables === item.id,
|
|
2418
|
+
onClick: () => void onRelease(item.id)
|
|
2419
|
+
}
|
|
2420
|
+
]
|
|
2421
|
+
}
|
|
2422
|
+
)
|
|
2423
|
+
] }, item.id)) })
|
|
2424
|
+
] }) : null
|
|
2425
|
+
]
|
|
2426
|
+
}
|
|
2427
|
+
);
|
|
1835
2428
|
}
|
|
1836
2429
|
const PAGE_SIZE = 15;
|
|
1837
2430
|
const SETTINGS_TABS = ["connection", "bridge", "writers", "stock", "runs"];
|
|
2431
|
+
const TASK_FILTERS = ["attention", "open", "done", "all"];
|
|
2432
|
+
function scrollToSection(id) {
|
|
2433
|
+
requestAnimationFrame(() => {
|
|
2434
|
+
var _a;
|
|
2435
|
+
return (_a = document.getElementById(id)) == null ? void 0 : _a.scrollIntoView({ behavior: "smooth", block: "start" });
|
|
2436
|
+
});
|
|
2437
|
+
}
|
|
1838
2438
|
const SubiektPage = () => {
|
|
1839
2439
|
const { t, i18n } = reactI18next.useTranslation("subiekt");
|
|
1840
2440
|
const lang = i18n.language || "en";
|
|
1841
2441
|
const client = reactQuery.useQueryClient();
|
|
1842
2442
|
const nav = usePageNav(SETTINGS_TABS);
|
|
2443
|
+
const [params] = reactRouterDom.useSearchParams();
|
|
1843
2444
|
const [pollUntil, setPollUntil] = react.useState(0);
|
|
1844
2445
|
const status = useSubiektStatus(pollUntil);
|
|
1845
2446
|
const s = status.data;
|
|
1846
2447
|
const polling = ((s == null ? void 0 : s.running.length) ?? 0) > 0 || Date.now() < pollUntil;
|
|
2448
|
+
const asked = params.get("filter") ?? "";
|
|
2449
|
+
const [taskFilter, setTaskFilter] = react.useState(TASK_FILTERS.includes(asked) ? asked : null);
|
|
2450
|
+
const [docKind, setDocKind] = react.useState("all");
|
|
2451
|
+
const initialQuery = (params.get("q") ?? "").slice(0, 80);
|
|
2452
|
+
const filter = taskFilter ?? (s && s.counts.failed > 0 ? "attention" : "all");
|
|
1847
2453
|
const runKey = JSON.stringify(Object.values((s == null ? void 0 : s.lastRuns) ?? {}).map((r) => (r == null ? void 0 : r.id) ?? ""));
|
|
1848
2454
|
const seen = react.useRef(void 0);
|
|
1849
2455
|
react.useEffect(() => {
|
|
@@ -1853,32 +2459,45 @@ const SubiektPage = () => {
|
|
|
1853
2459
|
seen.current = runKey;
|
|
1854
2460
|
}, [runKey, client]);
|
|
1855
2461
|
const poll = () => setPollUntil(Date.now() + 3e4);
|
|
2462
|
+
const toggleTasks = (f) => {
|
|
2463
|
+
setTaskFilter(filter === f ? "all" : f);
|
|
2464
|
+
scrollToSection("subiekt-tasks");
|
|
2465
|
+
};
|
|
2466
|
+
const toggleDocs = (k) => {
|
|
2467
|
+
setDocKind(docKind === k ? "all" : k);
|
|
2468
|
+
scrollToSection("subiekt-documents");
|
|
2469
|
+
};
|
|
2470
|
+
const c = s == null ? void 0 : s.counts;
|
|
2471
|
+
const queued = c ? c.pending + c.running + c.unknown : 0;
|
|
1856
2472
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-3", children: [
|
|
1857
2473
|
/* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "divide-y p-0", children: [
|
|
1858
|
-
/* @__PURE__ */ jsxRuntime.jsx(Header, { status: s, loading: status.isLoading, lang, nav, onAction: poll }),
|
|
2474
|
+
/* @__PURE__ */ jsxRuntime.jsx(Header, { status: s, loading: status.isLoading, fetching: status.isFetching, lang, nav, onAction: poll }),
|
|
1859
2475
|
status.isError ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-6 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(ui.InlineTip, { variant: "error", label: t("title"), children: errorMessage(status.error) }) }) : null,
|
|
1860
2476
|
s ? /* @__PURE__ */ jsxRuntime.jsx(Warnings, { status: s }) : null,
|
|
1861
|
-
|
|
1862
|
-
/* @__PURE__ */ jsxRuntime.jsx(StatTile, { label: t("stats.sent24h"), value: fmtNumber(
|
|
1863
|
-
/* @__PURE__ */ jsxRuntime.jsx(StatTile, { label: t("stats.waiting"), value: fmtNumber(
|
|
2477
|
+
c && nav.view === "panel" ? /* @__PURE__ */ jsxRuntime.jsxs(StatTiles, { columns: 7, children: [
|
|
2478
|
+
/* @__PURE__ */ jsxRuntime.jsx(StatTile, { label: t("stats.sent24h"), value: fmtNumber(c.succeeded24h, lang), tone: c.succeeded24h ? "green" : "grey", active: filter === "done", onClick: () => toggleTasks("done") }),
|
|
2479
|
+
/* @__PURE__ */ jsxRuntime.jsx(StatTile, { label: t("stats.waiting"), value: fmtNumber(c.waiting, lang), hint: c.waiting ? t("stats.hintWaiting") : void 0 }),
|
|
2480
|
+
/* @__PURE__ */ jsxRuntime.jsx(StatTile, { label: t("stats.queue"), value: fmtNumber(queued, lang), tone: queued ? "blue" : "grey", active: filter === "open", onClick: () => toggleTasks("open") }),
|
|
1864
2481
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1865
2482
|
StatTile,
|
|
1866
2483
|
{
|
|
1867
|
-
label: t("stats.
|
|
1868
|
-
value: fmtNumber(
|
|
1869
|
-
tone:
|
|
2484
|
+
label: t("stats.attention"),
|
|
2485
|
+
value: fmtNumber(c.failed, lang),
|
|
2486
|
+
tone: c.failed ? "red" : "grey",
|
|
2487
|
+
hint: c.failed ? t("stats.hintAttention") : void 0,
|
|
2488
|
+
active: filter === "attention",
|
|
2489
|
+
onClick: () => toggleTasks("attention")
|
|
1870
2490
|
}
|
|
1871
2491
|
),
|
|
1872
|
-
/* @__PURE__ */ jsxRuntime.jsx(StatTile, { label: t("stats.
|
|
1873
|
-
/* @__PURE__ */ jsxRuntime.jsx(StatTile, { label: t("stats.
|
|
1874
|
-
/* @__PURE__ */ jsxRuntime.jsx(StatTile, { label: t("stats.
|
|
1875
|
-
/* @__PURE__ */ jsxRuntime.jsx(StatTile, { label: t("stats.sales"), value: fmtNumber(s.counts.fs + s.counts.pa, lang), tone: s.counts.fs + s.counts.pa ? void 0 : "muted" })
|
|
2492
|
+
/* @__PURE__ */ jsxRuntime.jsx(StatTile, { label: t("stats.zk"), value: fmtNumber(c.zk, lang), active: docKind === "ZK", onClick: () => toggleDocs("ZK") }),
|
|
2493
|
+
/* @__PURE__ */ jsxRuntime.jsx(StatTile, { label: t("stats.wz"), value: fmtNumber(c.wz, lang), active: docKind === "WZ", onClick: () => toggleDocs("WZ") }),
|
|
2494
|
+
/* @__PURE__ */ jsxRuntime.jsx(StatTile, { label: t("stats.sales"), value: fmtNumber(c.fs + c.pa, lang) })
|
|
1876
2495
|
] }) : null
|
|
1877
2496
|
] }),
|
|
1878
|
-
s && nav.view === "guide" ? /* @__PURE__ */ jsxRuntime.jsx(GuideView, { status: s
|
|
2497
|
+
s && nav.view === "guide" ? /* @__PURE__ */ jsxRuntime.jsx(GuideView, { status: s }) : null,
|
|
1879
2498
|
nav.view === "panel" ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1880
|
-
s ? /* @__PURE__ */ jsxRuntime.jsx(TasksSection, { status: s, lang, poll: polling, onAction: poll }) : null,
|
|
1881
|
-
/* @__PURE__ */ jsxRuntime.jsx(DocumentsSection, { lang, poll: polling }),
|
|
2499
|
+
s ? /* @__PURE__ */ jsxRuntime.jsx(TasksSection, { status: s, lang, poll: polling, onAction: poll, filter, onFilter: setTaskFilter, initialQuery }) : null,
|
|
2500
|
+
/* @__PURE__ */ jsxRuntime.jsx(DocumentsSection, { lang, poll: polling, kind: docKind, onKind: setDocKind, counts: c, initialQuery }),
|
|
1882
2501
|
s ? /* @__PURE__ */ jsxRuntime.jsx(ProductsSection, { status: s, lang, poll: polling, onAction: poll }) : null
|
|
1883
2502
|
] }) : null,
|
|
1884
2503
|
nav.view === "settings" ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -1892,7 +2511,7 @@ const SubiektPage = () => {
|
|
|
1892
2511
|
{ id: "connection", label: t("settings.tab.connection") },
|
|
1893
2512
|
{ id: "bridge", label: t("settings.tab.bridge") },
|
|
1894
2513
|
{ id: "writers", label: t("settings.tab.writers"), badge: s == null ? void 0 : s.writers.filter((w) => w.active).length, tone: "orange" },
|
|
1895
|
-
{ id: "stock", label: t("settings.tab.stock"), badge: (s == null ? void 0 : s.options.stockDryRun) ? t("stock.dryRun") : null, tone: "
|
|
2514
|
+
{ id: "stock", label: t("settings.tab.stock"), badge: (s == null ? void 0 : s.options.stockDryRun) ? t("stock.dryRun") : null, tone: "blue" },
|
|
1896
2515
|
{ id: "runs", label: t("settings.tab.runs") }
|
|
1897
2516
|
],
|
|
1898
2517
|
children: [
|
|
@@ -1909,17 +2528,18 @@ const SubiektPage = () => {
|
|
|
1909
2528
|
function Header({
|
|
1910
2529
|
status,
|
|
1911
2530
|
loading,
|
|
2531
|
+
fetching,
|
|
1912
2532
|
lang,
|
|
1913
2533
|
nav,
|
|
1914
2534
|
onAction
|
|
1915
2535
|
}) {
|
|
1916
2536
|
const { t } = reactI18next.useTranslation("subiekt");
|
|
2537
|
+
const client = reactQuery.useQueryClient();
|
|
1917
2538
|
const sync = useSubiektSync();
|
|
1918
2539
|
const check = useSubiektCheck();
|
|
1919
2540
|
const ready = Boolean(status && (status.mode === "demo" || status.configured));
|
|
1920
2541
|
const running = new Set((status == null ? void 0 : status.running) ?? []);
|
|
1921
2542
|
const state = connectionState(status);
|
|
1922
|
-
const references = status ? referencesFor(status.references, lang) : [];
|
|
1923
2543
|
const promptSpec = usePromptSpec();
|
|
1924
2544
|
const community = communityLabels((key, options) => t(key, options), `${t("title")} ${t("by")}`);
|
|
1925
2545
|
const start = async (what) => {
|
|
@@ -1943,34 +2563,30 @@ function Header({
|
|
|
1943
2563
|
}
|
|
1944
2564
|
};
|
|
1945
2565
|
const panel = nav.view !== "guide";
|
|
1946
|
-
const
|
|
2566
|
+
const refreshAction = {
|
|
2567
|
+
key: "refresh",
|
|
2568
|
+
label: t("actions.refresh"),
|
|
2569
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowPath, {}),
|
|
2570
|
+
loading: fetching && !loading,
|
|
2571
|
+
onClick: () => void client.invalidateQueries({ queryKey: subiektKeys.all })
|
|
2572
|
+
};
|
|
2573
|
+
const checkAction = { key: "check", label: t("actions.check"), icon: /* @__PURE__ */ jsxRuntime.jsx(icons.ShieldCheck, {}), loading: check.isPending, disabled: !ready, onClick: () => void onCheck() };
|
|
1947
2574
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1948
2575
|
IntegrationHeader,
|
|
1949
2576
|
{
|
|
1950
2577
|
icon: /* @__PURE__ */ jsxRuntime.jsx(SubiektIcon, { width: 28, height: 28 }),
|
|
1951
2578
|
title: t("title"),
|
|
1952
|
-
|
|
2579
|
+
featured: { url: "https://medusajs.com/integrations/@koda-plusmedusa-plugin-subiekt-nexo", labels: community.featured },
|
|
1953
2580
|
badges: !loading ? /* @__PURE__ */ jsxRuntime.jsx(ModeBadge, { color: state.tone, label: t(`mode.${state.key}`), title: t("demo.label"), children: (status == null ? void 0 : status.mode) === "demo" ? /* @__PURE__ */ jsxRuntime.jsx("span", { children: t("demo.text") }) : null }) : null,
|
|
1954
2581
|
description: t("subtitle"),
|
|
1955
|
-
|
|
1956
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
soon: t("references.soon"),
|
|
1964
|
-
title: t("references.title"),
|
|
1965
|
-
subtitle: t("references.subtitle"),
|
|
1966
|
-
open: t("references.open"),
|
|
1967
|
-
review: t("references.review"),
|
|
1968
|
-
rating: (value) => fmtRating(value, lang)
|
|
1969
|
-
}
|
|
1970
|
-
}
|
|
1971
|
-
),
|
|
1972
|
-
/* @__PURE__ */ jsxRuntime.jsx(AddStoreButton, { labels: community.addStore })
|
|
1973
|
-
] }),
|
|
2582
|
+
points: [
|
|
2583
|
+
{ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.ShoppingCart, {}), text: t("points.orders") },
|
|
2584
|
+
{ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.ArchiveBox, {}), text: t("points.wz") },
|
|
2585
|
+
{ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.Receipt, {}), text: t("points.sales") },
|
|
2586
|
+
{ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.CubeSolid, {}), text: t("points.stock") },
|
|
2587
|
+
{ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.Tag, {}), text: t("points.prices") },
|
|
2588
|
+
{ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.LockClosedSolid, {}), text: t("points.safe"), tone: "green" }
|
|
2589
|
+
],
|
|
1974
2590
|
help: /* @__PURE__ */ jsxRuntime.jsx(HelpButtons, { spec: promptSpec, lang, labels: community }),
|
|
1975
2591
|
view: nav.view,
|
|
1976
2592
|
onView: (v) => nav.go(v),
|
|
@@ -1978,19 +2594,21 @@ function Header({
|
|
|
1978
2594
|
primary: panel ? {
|
|
1979
2595
|
key: "stock",
|
|
1980
2596
|
label: running.has("stock") ? t("actions.running") : t("actions.stock"),
|
|
1981
|
-
icon: /* @__PURE__ */ jsxRuntime.jsx(icons.
|
|
2597
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(icons.CubeSolid, {}),
|
|
1982
2598
|
disabled: !ready || running.has("stock"),
|
|
1983
2599
|
onClick: () => void start("stock")
|
|
1984
2600
|
} : null,
|
|
1985
2601
|
actions: panel ? [
|
|
2602
|
+
refreshAction,
|
|
1986
2603
|
{
|
|
1987
2604
|
key: "events",
|
|
1988
2605
|
label: running.has("events") ? t("actions.running") : t("actions.events"),
|
|
2606
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowDownTray, {}),
|
|
1989
2607
|
disabled: !ready || running.has("events"),
|
|
1990
2608
|
onClick: () => void start("events")
|
|
1991
2609
|
},
|
|
1992
2610
|
checkAction
|
|
1993
|
-
] : [checkAction]
|
|
2611
|
+
] : [refreshAction, checkAction]
|
|
1994
2612
|
}
|
|
1995
2613
|
);
|
|
1996
2614
|
}
|
|
@@ -2006,39 +2624,48 @@ function ConnectionSection({ status, lang }) {
|
|
|
2006
2624
|
const { t } = reactI18next.useTranslation("subiekt");
|
|
2007
2625
|
const c = status.connection;
|
|
2008
2626
|
const h = c.health;
|
|
2009
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
"
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2627
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2628
|
+
Section,
|
|
2629
|
+
{
|
|
2630
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(icons.Link, {}),
|
|
2631
|
+
title: t("connection.title"),
|
|
2632
|
+
badges: /* @__PURE__ */ jsxRuntime.jsx(ConnectionBadge, { status }),
|
|
2633
|
+
points: [
|
|
2634
|
+
{ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.Clock, {}), text: t("connection.points.queue") },
|
|
2635
|
+
{ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.Clock, {}), text: t("connection.points.documents") },
|
|
2636
|
+
{ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.Clock, {}), text: t("connection.points.stock") },
|
|
2637
|
+
{ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.Clock, {}), text: t("connection.points.products") }
|
|
2638
|
+
],
|
|
2639
|
+
children: [
|
|
2640
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "py-2", children: [
|
|
2641
|
+
/* @__PURE__ */ jsxRuntime.jsxs(Field, { label: t("connection.bridge"), children: [
|
|
2642
|
+
h ? /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
2643
|
+
(_a = h.bridge) == null ? void 0 : _a.name,
|
|
2644
|
+
" ",
|
|
2645
|
+
(_b = h.bridge) == null ? void 0 : _b.version,
|
|
2646
|
+
" ",
|
|
2647
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-ui-fg-muted", children: [
|
|
2648
|
+
"(",
|
|
2649
|
+
t("connection.contract", { version: (_c = h.bridge) == null ? void 0 : _c.contract }),
|
|
2650
|
+
")"
|
|
2651
|
+
] })
|
|
2652
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-ui-fg-muted", children: status.bridgeHost ?? t("connection.none") }),
|
|
2653
|
+
status.bridgeHost && h ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-ui-fg-muted", children: status.bridgeHost }) : null
|
|
2654
|
+
] }),
|
|
2655
|
+
/* @__PURE__ */ jsxRuntime.jsx(Field, { label: t("connection.subiekt"), children: (h == null ? void 0 : h.subiekt) ? [h.subiekt.product, h.subiekt.version].filter(Boolean).join(" ") || t("connection.none") : t("connection.none") }),
|
|
2656
|
+
/* @__PURE__ */ jsxRuntime.jsx(Field, { label: t("connection.database"), children: ((_d = h == null ? void 0 : h.subiekt) == null ? void 0 : _d.database) ?? t("connection.none") }),
|
|
2657
|
+
/* @__PURE__ */ jsxRuntime.jsx(Field, { label: t("connection.company"), children: ((_e = h == null ? void 0 : h.subiekt) == null ? void 0 : _e.company) ?? t("connection.none") }),
|
|
2658
|
+
/* @__PURE__ */ jsxRuntime.jsx(Field, { label: t("connection.warehouse"), children: ((_f = h == null ? void 0 : h.subiekt) == null ? void 0 : _f.warehouse) ?? t("connection.none") }),
|
|
2659
|
+
/* @__PURE__ */ jsxRuntime.jsx(Field, { label: t("connection.checkedAt"), children: fmtDateTime(c.checkedAt, lang) || t("connection.never") }),
|
|
2660
|
+
/* @__PURE__ */ jsxRuntime.jsx(Field, { label: t("connection.eventsReadAt"), children: fmtDateTime(c.eventsReadAt, lang) || t("connection.never") })
|
|
2661
|
+
] }),
|
|
2662
|
+
c.lastError && (!c.reachable || h && !((_g = h.subiekt) == null ? void 0 : _g.connected)) ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-6 py-4", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.InlineTip, { variant: "error", label: t("connection.lastError"), children: [
|
|
2663
|
+
c.lastError,
|
|
2664
|
+
c.consecutiveFailures > 1 ? ` (${t("connection.failures", { count: c.consecutiveFailures })})` : ""
|
|
2665
|
+
] }) }) : null
|
|
2666
|
+
]
|
|
2667
|
+
}
|
|
2668
|
+
);
|
|
2042
2669
|
}
|
|
2043
2670
|
function StockSection({ run, lang }) {
|
|
2044
2671
|
const { t } = reactI18next.useTranslation("subiekt");
|
|
@@ -2054,44 +2681,45 @@ function StockSection({ run, lang }) {
|
|
|
2054
2681
|
["conflicts", stats.conflicts, true]
|
|
2055
2682
|
] : [];
|
|
2056
2683
|
const samples = stats == null ? void 0 : stats.samples;
|
|
2057
|
-
return /* @__PURE__ */ jsxRuntime.
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
(run == null ? void 0 : run.dryRun) ? /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { size: "2xsmall", color: "purple", children: t("stock.dryRun") }) : null,
|
|
2684
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2685
|
+
Section,
|
|
2686
|
+
{
|
|
2687
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(icons.CubeSolid, {}),
|
|
2688
|
+
title: t("stock.title"),
|
|
2689
|
+
badges: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2690
|
+
(run == null ? void 0 : run.dryRun) ? /* @__PURE__ */ jsxRuntime.jsx(ToneBadge, { tone: "blue", children: t("stock.dryRun") }) : null,
|
|
2065
2691
|
run ? /* @__PURE__ */ jsxRuntime.jsx(RunStatusBadge, { status: run.status }) : null
|
|
2066
|
-
] })
|
|
2067
|
-
] }),
|
|
2068
|
-
!run ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-6 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: t("stock.never") }) }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2069
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-6 py-3", children: [
|
|
2070
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", children: runSummary(run, t) }),
|
|
2071
|
-
/* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "xsmall", className: "text-ui-fg-muted", children: [
|
|
2072
|
-
fmtDateTime(run.startedAt, lang),
|
|
2073
|
-
", ",
|
|
2074
|
-
fmtDuration(run.durationMs)
|
|
2075
|
-
] })
|
|
2076
2692
|
] }),
|
|
2077
|
-
|
|
2078
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2079
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2080
|
-
]
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
{
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2693
|
+
points: [
|
|
2694
|
+
{ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowLongRight, {}), text: t("stock.points.direction") },
|
|
2695
|
+
{ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.MagnifyingGlass, {}), text: t("stock.points.match") }
|
|
2696
|
+
],
|
|
2697
|
+
pointsLabel: t("stock.subtitle"),
|
|
2698
|
+
children: !run ? /* @__PURE__ */ jsxRuntime.jsx(EmptyState, { icon: /* @__PURE__ */ jsxRuntime.jsx(icons.CubeSolid, {}), title: t("stock.never"), compact: true }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2699
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-6 py-3", children: [
|
|
2700
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", children: runSummary(run, t) }),
|
|
2701
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "xsmall", className: "text-ui-fg-muted", children: [
|
|
2702
|
+
fmtDateTime(run.startedAt, lang),
|
|
2703
|
+
", ",
|
|
2704
|
+
fmtDuration(run.durationMs)
|
|
2705
|
+
] })
|
|
2706
|
+
] }),
|
|
2707
|
+
counters.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(StatTiles, { columns: 4, children: counters.map(([key, value, warn]) => /* @__PURE__ */ jsxRuntime.jsx(StatTile, { label: t(`stock.counters.${key}`), value: fmtNumber(value ?? 0, lang), tone: warn && value ? "orange" : "grey" }, key)) }) : null,
|
|
2708
|
+
samples ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-3 px-6 py-4", children: [
|
|
2709
|
+
samples.changes && samples.changes.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2710
|
+
SampleList,
|
|
2711
|
+
{
|
|
2712
|
+
label: t("stock.samples.changes"),
|
|
2713
|
+
items: samples.changes.map((ch) => `${ch.sku ?? "?"}: ${ch.from === null ? "-" : fmtNumber(ch.from, lang)} → ${fmtNumber(ch.to, lang)}`)
|
|
2714
|
+
}
|
|
2715
|
+
) : null,
|
|
2716
|
+
samples.unmatchedVariants && samples.unmatchedVariants.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(SampleList, { label: t("stock.samples.unmatchedVariants"), items: samples.unmatchedVariants }) : null,
|
|
2717
|
+
samples.unmatchedSubiekt && samples.unmatchedSubiekt.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(SampleList, { label: t("stock.samples.unmatchedSubiekt"), items: samples.unmatchedSubiekt }) : null,
|
|
2718
|
+
samples.conflicts && samples.conflicts.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(SampleList, { label: t("stock.samples.conflicts"), items: samples.conflicts }) : null
|
|
2719
|
+
] }) : null
|
|
2720
|
+
] })
|
|
2721
|
+
}
|
|
2722
|
+
);
|
|
2095
2723
|
}
|
|
2096
2724
|
function TaskDetails({ task, lang }) {
|
|
2097
2725
|
const { t } = reactI18next.useTranslation("subiekt");
|
|
@@ -2112,17 +2740,26 @@ function TaskDetails({ task, lang }) {
|
|
|
2112
2740
|
(task.status === "pending" || task.status === "unknown") && task.nextAttemptAt && task.attempts > 0 ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-fg-muted", children: t("tasks.nextAttempt", { time: fmtDateTime(task.nextAttemptAt, lang) }) }) : null
|
|
2113
2741
|
] });
|
|
2114
2742
|
}
|
|
2115
|
-
function TasksSection({
|
|
2743
|
+
function TasksSection({
|
|
2744
|
+
status,
|
|
2745
|
+
lang,
|
|
2746
|
+
poll,
|
|
2747
|
+
onAction,
|
|
2748
|
+
filter,
|
|
2749
|
+
onFilter,
|
|
2750
|
+
initialQuery
|
|
2751
|
+
}) {
|
|
2116
2752
|
var _a, _b;
|
|
2117
2753
|
const { t } = reactI18next.useTranslation("subiekt");
|
|
2118
|
-
const [
|
|
2119
|
-
const [search, setSearch] = react.useState("");
|
|
2754
|
+
const [search, setSearch] = react.useState(initialQuery);
|
|
2120
2755
|
const [offset, setOffset] = react.useState(0);
|
|
2121
|
-
const q = search.trim();
|
|
2122
|
-
const
|
|
2123
|
-
const
|
|
2756
|
+
const q = useDebouncedValue(search).trim();
|
|
2757
|
+
const c = status.counts;
|
|
2758
|
+
const open = c.waiting + c.pending + c.running + c.unknown;
|
|
2759
|
+
const tasks = useSubiektTasks(filter, q, offset, PAGE_SIZE, poll || c.pending + c.running + c.unknown > 0);
|
|
2124
2760
|
const retry = useSubiektRetry();
|
|
2125
2761
|
const rows = ((_a = tasks.data) == null ? void 0 : _a.tasks) ?? [];
|
|
2762
|
+
const products = useKitOrderProducts(rows.map((task) => task.orderId));
|
|
2126
2763
|
react.useEffect(() => setOffset(0), [filter, q]);
|
|
2127
2764
|
const onRetry = async (task) => {
|
|
2128
2765
|
try {
|
|
@@ -2133,146 +2770,198 @@ function TasksSection({ status, lang, poll, onAction }) {
|
|
|
2133
2770
|
ui.toast.error(t("toast.error", { error: errorMessage(err) }));
|
|
2134
2771
|
}
|
|
2135
2772
|
};
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
{
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2773
|
+
const pick = (f) => onFilter(filter === f && f !== "all" ? "all" : f);
|
|
2774
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2775
|
+
Section,
|
|
2776
|
+
{
|
|
2777
|
+
id: "subiekt-tasks",
|
|
2778
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(icons.QueueList, {}),
|
|
2779
|
+
title: t("tasks.title"),
|
|
2780
|
+
points: [
|
|
2781
|
+
{ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.ListBullet, {}), text: t("tasks.points.order") },
|
|
2782
|
+
{ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowPath, {}), text: t("tasks.points.retries") },
|
|
2783
|
+
{ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.ExclamationCircle, {}), text: t("tasks.points.failed"), tone: c.failed ? "orange" : "grey" }
|
|
2784
|
+
],
|
|
2785
|
+
pointsLabel: t("tasks.subtitle"),
|
|
2786
|
+
actions: /* @__PURE__ */ jsxRuntime.jsx(SearchInput, { value: search, onChange: setSearch, placeholder: t("tasks.search") }),
|
|
2787
|
+
children: [
|
|
2788
|
+
/* @__PURE__ */ jsxRuntime.jsxs(FilterBar, { children: [
|
|
2789
|
+
/* @__PURE__ */ jsxRuntime.jsx(FilterButton, { icon: /* @__PURE__ */ jsxRuntime.jsx(icons.ListBullet, {}), label: t("tasks.filters.all"), active: filter === "all", onClick: () => pick("all") }),
|
|
2790
|
+
/* @__PURE__ */ jsxRuntime.jsx(FilterDivider, {}),
|
|
2791
|
+
/* @__PURE__ */ jsxRuntime.jsx(FilterButton, { icon: /* @__PURE__ */ jsxRuntime.jsx(icons.ExclamationCircle, {}), label: t("tasks.filters.attention"), count: c.failed, attention: true, active: filter === "attention", onClick: () => pick("attention") }),
|
|
2792
|
+
/* @__PURE__ */ jsxRuntime.jsx(FilterButton, { icon: /* @__PURE__ */ jsxRuntime.jsx(icons.Clock, {}), label: t("tasks.filters.open"), count: open, active: filter === "open", onClick: () => pick("open") }),
|
|
2793
|
+
/* @__PURE__ */ jsxRuntime.jsx(FilterButton, { icon: /* @__PURE__ */ jsxRuntime.jsx(icons.CheckCircle, {}), label: t("tasks.filters.done"), active: filter === "done", onClick: () => pick("done") })
|
|
2794
|
+
] }),
|
|
2795
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-x-auto", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Table, { children: [
|
|
2796
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.Header, { children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Table.Row, { children: [
|
|
2797
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { children: /* @__PURE__ */ jsxRuntime.jsx(StoreColumn, { label: t("tasks.columns.order"), hint: t("store.orderMatching") }) }),
|
|
2798
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { children: t("tasks.columns.products") }),
|
|
2799
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { children: t("tasks.columns.operation") }),
|
|
2800
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { children: t("tasks.columns.document") }),
|
|
2801
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { children: t("tasks.columns.status") }),
|
|
2802
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { className: "text-right", children: t("tasks.columns.attempts") }),
|
|
2803
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { children: t("tasks.columns.details") }),
|
|
2804
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, {})
|
|
2805
|
+
] }) }),
|
|
2806
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.Body, { children: tasks.isLoading ? /* @__PURE__ */ jsxRuntime.jsx(KitSkeletonRows, { cols: 8, rows: 4 }) : rows.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(EmptyTableRow, { cols: 8, icon: filter === "attention" ? /* @__PURE__ */ jsxRuntime.jsx(icons.CheckCircle, {}) : /* @__PURE__ */ jsxRuntime.jsx(icons.QueueList, {}), title: t(`tasks.emptyBy.${filter}`) }) : rows.map((task) => {
|
|
2807
|
+
var _a2;
|
|
2808
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(ui.Table.Row, { className: "[&_td]:py-2.5", children: [
|
|
2809
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { className: "max-w-[260px]", children: /* @__PURE__ */ jsxRuntime.jsx(StoreOrderCell, { orderId: task.orderId, displayId: task.displayId }) }),
|
|
2810
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(KitOrderProductsCell, { data: (_a2 = products.data) == null ? void 0 : _a2[task.orderId], loading: products.isLoading, displayId: task.displayId }) }),
|
|
2811
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { className: "whitespace-nowrap", children: task.kind === "order.document" && (task.documentKind === "fs" || task.documentKind === "pa") ? t(`tasks.documentKinds.${task.documentKind}`) : t(`tasks.kinds.${task.kind}`) }),
|
|
2812
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { className: "whitespace-nowrap font-mono txt-compact-xsmall", children: task.documentNumber ?? "" }),
|
|
2813
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(TaskStatusBadge, { status: task.status, dot: true }) }),
|
|
2814
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { className: "text-right tabular-nums", children: task.attempts }),
|
|
2815
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { className: "max-w-md", children: /* @__PURE__ */ jsxRuntime.jsx(TaskDetails, { task, lang }) }),
|
|
2816
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { className: "text-right", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2817
|
+
RowActions,
|
|
2818
|
+
{
|
|
2819
|
+
actions: [
|
|
2820
|
+
{
|
|
2821
|
+
key: "send",
|
|
2822
|
+
label: task.status === "waiting" ? t("actions.send") : t("actions.retry"),
|
|
2823
|
+
icon: task.status === "waiting" ? /* @__PURE__ */ jsxRuntime.jsx(icons.PaperPlane, {}) : /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowPath, {}),
|
|
2824
|
+
loading: retry.isPending && retry.variables === task.id,
|
|
2825
|
+
hidden: !(task.status === "failed" || task.status === "unknown" || task.status === "pending" && task.attempts > 0 || task.status === "waiting"),
|
|
2826
|
+
onClick: () => void onRetry(task)
|
|
2827
|
+
}
|
|
2828
|
+
]
|
|
2829
|
+
}
|
|
2830
|
+
) })
|
|
2831
|
+
] }, task.id);
|
|
2832
|
+
}) })
|
|
2833
|
+
] }) }),
|
|
2834
|
+
/* @__PURE__ */ jsxRuntime.jsx(Pager, { offset, limit: PAGE_SIZE, count: ((_b = tasks.data) == null ? void 0 : _b.count) ?? 0, onChange: setOffset })
|
|
2835
|
+
]
|
|
2836
|
+
}
|
|
2837
|
+
);
|
|
2179
2838
|
}
|
|
2180
|
-
|
|
2839
|
+
const DOC_KINDS = [
|
|
2840
|
+
{ kind: "ZK", icon: /* @__PURE__ */ jsxRuntime.jsx(icons.ShoppingCart, {}), count: (c) => c.zk },
|
|
2841
|
+
{ kind: "WZ", icon: /* @__PURE__ */ jsxRuntime.jsx(icons.ArchiveBox, {}), count: (c) => c.wz },
|
|
2842
|
+
{ kind: "FS", icon: /* @__PURE__ */ jsxRuntime.jsx(icons.DocumentText, {}), count: (c) => c.fs },
|
|
2843
|
+
{ kind: "PA", icon: /* @__PURE__ */ jsxRuntime.jsx(icons.Receipt, {}), count: (c) => c.pa }
|
|
2844
|
+
];
|
|
2845
|
+
function DocumentsSection({
|
|
2846
|
+
lang,
|
|
2847
|
+
poll,
|
|
2848
|
+
kind,
|
|
2849
|
+
onKind,
|
|
2850
|
+
counts,
|
|
2851
|
+
initialQuery
|
|
2852
|
+
}) {
|
|
2181
2853
|
var _a, _b;
|
|
2182
2854
|
const { t } = reactI18next.useTranslation("subiekt");
|
|
2183
|
-
const [
|
|
2855
|
+
const [search, setSearch] = react.useState(initialQuery);
|
|
2856
|
+
const q = useDebouncedValue(search).trim();
|
|
2184
2857
|
const [offset, setOffset] = react.useState(0);
|
|
2185
|
-
const docs = useSubiektDocuments(kind,
|
|
2858
|
+
const docs = useSubiektDocuments(kind, q, offset, PAGE_SIZE, poll);
|
|
2186
2859
|
const rows = ((_a = docs.data) == null ? void 0 : _a.documents) ?? [];
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
{
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
)
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
d.related.map((r) => r.number).join(", ")
|
|
2218
|
-
] }) : null
|
|
2860
|
+
const products = useKitOrderProducts(rows.map((d) => d.orderId));
|
|
2861
|
+
react.useEffect(() => setOffset(0), [kind, q]);
|
|
2862
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2863
|
+
Section,
|
|
2864
|
+
{
|
|
2865
|
+
id: "subiekt-documents",
|
|
2866
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(icons.DocumentText, {}),
|
|
2867
|
+
title: t("documents.title"),
|
|
2868
|
+
points: [
|
|
2869
|
+
{ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.Link, {}), text: t("documents.points.tag") },
|
|
2870
|
+
{ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.ArchiveBox, {}), text: t("documents.points.warehouse") },
|
|
2871
|
+
{ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.Receipt, {}), text: t("documents.points.ksef") }
|
|
2872
|
+
],
|
|
2873
|
+
pointsLabel: t("documents.subtitle"),
|
|
2874
|
+
actions: /* @__PURE__ */ jsxRuntime.jsx(SearchInput, { value: search, onChange: setSearch, placeholder: t("documents.search") }),
|
|
2875
|
+
children: [
|
|
2876
|
+
/* @__PURE__ */ jsxRuntime.jsxs(FilterBar, { children: [
|
|
2877
|
+
/* @__PURE__ */ jsxRuntime.jsx(FilterButton, { icon: /* @__PURE__ */ jsxRuntime.jsx(icons.ListBullet, {}), label: t("documents.filters.all"), count: counts == null ? void 0 : counts.documents, active: kind === "all", onClick: () => onKind("all") }),
|
|
2878
|
+
/* @__PURE__ */ jsxRuntime.jsx(FilterDivider, {}),
|
|
2879
|
+
DOC_KINDS.map((d) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
2880
|
+
FilterButton,
|
|
2881
|
+
{
|
|
2882
|
+
icon: d.icon,
|
|
2883
|
+
label: t(`documents.filters.${d.kind}`),
|
|
2884
|
+
count: counts ? d.count(counts) : void 0,
|
|
2885
|
+
active: kind === d.kind,
|
|
2886
|
+
onClick: () => onKind(kind === d.kind ? "all" : d.kind)
|
|
2887
|
+
},
|
|
2888
|
+
d.kind
|
|
2889
|
+
))
|
|
2219
2890
|
] }),
|
|
2220
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2891
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-x-auto", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Table, { children: [
|
|
2892
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.Header, { children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Table.Row, { children: [
|
|
2893
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { children: t("documents.columns.number") }),
|
|
2894
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { children: /* @__PURE__ */ jsxRuntime.jsx(StoreColumn, { label: t("documents.columns.order"), hint: t("store.orderMatching") }) }),
|
|
2895
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { children: t("documents.columns.products") }),
|
|
2896
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { children: t("documents.columns.issued") }),
|
|
2897
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { children: t("documents.columns.source") }),
|
|
2898
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { children: t("documents.columns.ksef") }),
|
|
2899
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { children: t("documents.columns.status") })
|
|
2900
|
+
] }) }),
|
|
2901
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.Body, { children: docs.isLoading ? /* @__PURE__ */ jsxRuntime.jsx(KitSkeletonRows, { cols: 7, rows: 4 }) : rows.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(EmptyTableRow, { cols: 7, icon: /* @__PURE__ */ jsxRuntime.jsx(icons.DocumentText, {}), title: t("documents.empty") }) : rows.map((d) => {
|
|
2902
|
+
var _a2;
|
|
2903
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(ui.Table.Row, { className: "[&_td]:py-2.5", children: [
|
|
2904
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Table.Cell, { className: "whitespace-nowrap font-mono txt-compact-xsmall", children: [
|
|
2905
|
+
d.number,
|
|
2906
|
+
d.related.length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-ui-fg-muted", children: [
|
|
2907
|
+
" ← ",
|
|
2908
|
+
d.related.map((r) => r.number).join(", ")
|
|
2909
|
+
] }) : null
|
|
2910
|
+
] }),
|
|
2911
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { className: "max-w-[260px]", children: /* @__PURE__ */ jsxRuntime.jsx(StoreOrderCell, { orderId: d.orderId, displayId: d.displayId }) }),
|
|
2912
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { children: d.orderId ? /* @__PURE__ */ jsxRuntime.jsx(KitOrderProductsCell, { data: (_a2 = products.data) == null ? void 0 : _a2[d.orderId], loading: products.isLoading, displayId: d.displayId }) : null }),
|
|
2913
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { className: "whitespace-nowrap", children: fmtDateTime(d.issuedAt, lang) }),
|
|
2914
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { children: t(`documents.sources.${d.source}`, { defaultValue: d.source }) }),
|
|
2915
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { className: "whitespace-nowrap font-mono txt-compact-xsmall", children: d.ksefNumber ? d.ksefNumber : d.kind === "FS" && d.status !== "canceled" ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-sans text-ui-fg-muted", children: t("documents.ksefWaiting") }) : "" }),
|
|
2916
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(DocumentStatusBadge, { status: d.status, dot: true }) })
|
|
2917
|
+
] }, d.id);
|
|
2918
|
+
}) })
|
|
2919
|
+
] }) }),
|
|
2920
|
+
/* @__PURE__ */ jsxRuntime.jsx(Pager, { offset, limit: PAGE_SIZE, count: ((_b = docs.data) == null ? void 0 : _b.count) ?? 0, onChange: setOffset })
|
|
2921
|
+
]
|
|
2922
|
+
}
|
|
2923
|
+
);
|
|
2229
2924
|
}
|
|
2230
2925
|
function RunsSection({ lang, poll }) {
|
|
2231
2926
|
var _a;
|
|
2232
2927
|
const { t } = reactI18next.useTranslation("subiekt");
|
|
2233
2928
|
const runs = useSubiektRuns(poll);
|
|
2234
2929
|
const rows = ((_a = runs.data) == null ? void 0 : _a.runs) ?? [];
|
|
2235
|
-
return /* @__PURE__ */ jsxRuntime.
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2242
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2930
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2931
|
+
Section,
|
|
2932
|
+
{
|
|
2933
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(icons.Clock, {}),
|
|
2934
|
+
title: t("runs.title"),
|
|
2935
|
+
points: [
|
|
2936
|
+
{ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.BarsArrowDown, {}), text: t("runs.points.newest") },
|
|
2937
|
+
{ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.Bolt, {}), text: t("runs.points.jobs") }
|
|
2938
|
+
],
|
|
2939
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-x-auto", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Table, { children: [
|
|
2940
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.Header, { children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Table.Row, { children: [
|
|
2941
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { children: t("runs.columns.kind") }),
|
|
2942
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { children: t("runs.columns.trigger") }),
|
|
2943
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { children: t("runs.columns.status") }),
|
|
2944
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { children: t("runs.columns.message") }),
|
|
2945
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { children: t("runs.columns.started") }),
|
|
2946
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { className: "text-right", children: t("runs.columns.duration") })
|
|
2947
|
+
] }) }),
|
|
2948
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.Body, { children: runs.isLoading ? /* @__PURE__ */ jsxRuntime.jsx(KitSkeletonRows, { cols: 6, rows: 4 }) : rows.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(EmptyTableRow, { cols: 6, icon: /* @__PURE__ */ jsxRuntime.jsx(icons.Clock, {}), title: t("runs.empty") }) : rows.map((r) => /* @__PURE__ */ jsxRuntime.jsxs(ui.Table.Row, { className: "[&_td]:py-2.5", children: [
|
|
2949
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { className: "whitespace-nowrap", children: t(`runs.kinds.${r.kind}`) }),
|
|
2950
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { className: "whitespace-nowrap text-ui-fg-subtle", children: t(`runs.triggers.${r.trigger}`, { defaultValue: r.trigger }) }),
|
|
2951
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(RunStatusBadge, { status: r.status, dot: true }) }),
|
|
2952
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { className: "max-w-lg", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", children: runSummary(r, t) }) }),
|
|
2953
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { className: "whitespace-nowrap", children: fmtDateTime(r.startedAt, lang) }),
|
|
2954
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { className: "text-right tabular-nums", children: fmtDuration(r.durationMs) })
|
|
2955
|
+
] }, r.id)) })
|
|
2956
|
+
] }) })
|
|
2957
|
+
}
|
|
2958
|
+
);
|
|
2256
2959
|
}
|
|
2257
2960
|
const config = adminSdk.defineRouteConfig({
|
|
2258
2961
|
label: "Subiekt nexo",
|
|
2259
2962
|
icon: SubiektIcon
|
|
2260
2963
|
});
|
|
2261
2964
|
const communityEn = {
|
|
2262
|
-
addStore: {
|
|
2263
|
-
button: "Add your store",
|
|
2264
|
-
title: "Does your store run on this integration?",
|
|
2265
|
-
text: "Tell us about it. Once we check it, the store joins this list with a link and its rating.",
|
|
2266
|
-
name: "Store name",
|
|
2267
|
-
url: "Store address",
|
|
2268
|
-
note: "A few words about the setup (optional)",
|
|
2269
|
-
send: "Send the request",
|
|
2270
|
-
copy: "Copy the text",
|
|
2271
|
-
copied: "Request copied, paste it into a mail to hello@koda.plus",
|
|
2272
|
-
hint: "Your mail app opens with the message to {{email}} ready to send.",
|
|
2273
|
-
subject: "A store for {{integration}}",
|
|
2274
|
-
greeting: "Hello, my store runs on {{integration}}. Please add it to the list of stores."
|
|
2275
|
-
},
|
|
2276
2965
|
prompt: {
|
|
2277
2966
|
button: "Copy prompt",
|
|
2278
2967
|
title: "Add this integration to your store",
|
|
@@ -2284,23 +2973,13 @@ const communityEn = {
|
|
|
2284
2973
|
discord: {
|
|
2285
2974
|
button: "Help on Discord",
|
|
2286
2975
|
title: "Join the Koda Plus server on Discord"
|
|
2976
|
+
},
|
|
2977
|
+
featured: {
|
|
2978
|
+
badge: "Medusa featured integration",
|
|
2979
|
+
title: "Featured in the Medusa integrations catalog. Opens its page there in a new tab."
|
|
2287
2980
|
}
|
|
2288
2981
|
};
|
|
2289
2982
|
const communityPl = {
|
|
2290
|
-
addStore: {
|
|
2291
|
-
button: "Dodaj swój sklep",
|
|
2292
|
-
title: "Twój sklep działa na tej integracji?",
|
|
2293
|
-
text: "Daj nam znać. Po sprawdzeniu dodamy go do tej listy z linkiem i oceną.",
|
|
2294
|
-
name: "Nazwa sklepu",
|
|
2295
|
-
url: "Adres sklepu",
|
|
2296
|
-
note: "Kilka słów o wdrożeniu (opcjonalnie)",
|
|
2297
|
-
send: "Wyślij zgłoszenie",
|
|
2298
|
-
copy: "Kopiuj treść",
|
|
2299
|
-
copied: "Treść skopiowana, wklej ją w mail do hello@koda.plus",
|
|
2300
|
-
hint: "Otworzy się Twoja poczta z gotową wiadomością do {{email}}.",
|
|
2301
|
-
subject: "Zgłoszenie sklepu: {{integration}}",
|
|
2302
|
-
greeting: "Dzień dobry, mój sklep działa na integracji {{integration}}. Proszę o dodanie go do listy sklepów."
|
|
2303
|
-
},
|
|
2304
2983
|
prompt: {
|
|
2305
2984
|
button: "Kopiuj prompt",
|
|
2306
2985
|
title: "Dodaj tę integrację do swojego sklepu",
|
|
@@ -2312,16 +2991,28 @@ const communityPl = {
|
|
|
2312
2991
|
discord: {
|
|
2313
2992
|
button: "Pomoc na Discordzie",
|
|
2314
2993
|
title: "Dołącz do serwera Koda Plus na Discordzie"
|
|
2994
|
+
},
|
|
2995
|
+
featured: {
|
|
2996
|
+
badge: "Wyróżniona przez Medusę",
|
|
2997
|
+
title: "Wyróżniona w katalogu integracji Medusy. Otwiera jej stronę w katalogu w nowej karcie."
|
|
2315
2998
|
}
|
|
2316
2999
|
};
|
|
2317
3000
|
const en = {
|
|
2318
3001
|
title: "Subiekt nexo",
|
|
2319
3002
|
by: "by Koda Plus",
|
|
2320
3003
|
subtitle: "Orders become ZK documents in Subiekt nexo PRO, the WZ issued in the warehouse comes back to the order, sales documents carry their KSeF number, and stock and prices flow from Subiekt to Medusa.",
|
|
3004
|
+
points: {
|
|
3005
|
+
orders: "Order becomes a ZK",
|
|
3006
|
+
wz: "WZ back from the warehouse",
|
|
3007
|
+
sales: "Invoices with KSeF numbers",
|
|
3008
|
+
stock: "Stock from Subiekt",
|
|
3009
|
+
prices: "Prices as a plan first",
|
|
3010
|
+
safe: "Writes only once armed"
|
|
3011
|
+
},
|
|
2321
3012
|
view: { panel: "Panel", guide: "Setup guide" },
|
|
2322
3013
|
settings: {
|
|
2323
3014
|
title: "Settings",
|
|
2324
|
-
subtitle: "The technical side of the integration
|
|
3015
|
+
subtitle: "The technical side of the integration",
|
|
2325
3016
|
tab: {
|
|
2326
3017
|
connection: "Connection",
|
|
2327
3018
|
bridge: "Bridge",
|
|
@@ -2340,6 +3031,7 @@ const en = {
|
|
|
2340
3031
|
},
|
|
2341
3032
|
actions: {
|
|
2342
3033
|
moreActions: "More actions",
|
|
3034
|
+
refresh: "Refresh",
|
|
2343
3035
|
check: "Check connection",
|
|
2344
3036
|
checking: "Checking",
|
|
2345
3037
|
stock: "Sync stock",
|
|
@@ -2371,7 +3063,9 @@ const en = {
|
|
|
2371
3063
|
attention: "Need attention",
|
|
2372
3064
|
zk: "ZK documents",
|
|
2373
3065
|
wz: "WZ documents",
|
|
2374
|
-
sales: "FS and PA"
|
|
3066
|
+
sales: "FS and PA",
|
|
3067
|
+
hintAttention: "Send again below",
|
|
3068
|
+
hintWaiting: "Sent after payment"
|
|
2375
3069
|
},
|
|
2376
3070
|
store: {
|
|
2377
3071
|
openOrder: "Open order",
|
|
@@ -2399,11 +3093,12 @@ const en = {
|
|
|
2399
3093
|
never: "never",
|
|
2400
3094
|
none: "none",
|
|
2401
3095
|
eventsReadAt: "Documents read",
|
|
2402
|
-
|
|
3096
|
+
points: { queue: "Queue every minute", documents: "Documents every 2 min", stock: "Stock every 10 min", products: "Products every hour" }
|
|
2403
3097
|
},
|
|
2404
3098
|
bridge: {
|
|
2405
3099
|
title: "Bridge",
|
|
2406
3100
|
subtitle: "What the last check of the bridge said. Click Check connection for a fresh one.",
|
|
3101
|
+
points: { last: "From the last check", fresh: "Check connection reads again" },
|
|
2407
3102
|
versions: "Versions",
|
|
2408
3103
|
versionsValue: "bridge {{bridge}}, contract {{contract}}, plugin {{plugin}}",
|
|
2409
3104
|
sdk: "nexo SDK and database",
|
|
@@ -2482,6 +3177,7 @@ const en = {
|
|
|
2482
3177
|
writers: {
|
|
2483
3178
|
title: "Writers",
|
|
2484
3179
|
subtitle: "Every write added in 0.2.0 needs its option in medusa-config.ts and a person arming it here. An option set to false wins.",
|
|
3180
|
+
points: { option: "Option in medusa-config.ts", person: "Armed here by a person", falseWins: "Option false wins" },
|
|
2485
3181
|
demoNote: "Demo: armed writers only simulate. Nothing in this store changes.",
|
|
2486
3182
|
names: {
|
|
2487
3183
|
prices: "Prices from Subiekt",
|
|
@@ -2528,6 +3224,7 @@ const en = {
|
|
|
2528
3224
|
products: {
|
|
2529
3225
|
title: "Products from Subiekt",
|
|
2530
3226
|
subtitle: "Prices from Subiekt next to the store products they update, and Subiekt products the store does not sell yet. Everything is a plan first: nothing changes until someone switches its writer on in Settings.",
|
|
3227
|
+
points: { plan: "A plan first", match: "EAN first, then SKU", writer: "Changes after arming" },
|
|
2531
3228
|
matching: "Subiekt products are matched to store variants by EAN first, then by the SKU against the Subiekt symbol. A code used twice is a conflict and is never guessed.",
|
|
2532
3229
|
matchedKey: "Matched by {{by}}: {{code}}",
|
|
2533
3230
|
settings: "Prices from {{level}} ({{type}}) to {{target}}, in {{currency}}.",
|
|
@@ -2563,10 +3260,11 @@ const en = {
|
|
|
2563
3260
|
columns: { product: "Product in Subiekt", change: "Change", store: "Product in the store", matched: "Matched by", status: "Status", details: "Details" },
|
|
2564
3261
|
matchedBy: { ean: "EAN", sku: "SKU" },
|
|
2565
3262
|
newProduct: "new, {{price}}",
|
|
2566
|
-
empty: "Nothing in this plan
|
|
3263
|
+
empty: "Nothing in this plan",
|
|
2567
3264
|
search: "Symbol, SKU or EAN",
|
|
2568
3265
|
quarantine: "Quarantined after repeated failures",
|
|
2569
3266
|
quarantineHint: "The writer skips these until you release them. Fix the cause first (the last error says what failed).",
|
|
3267
|
+
quarantinePoints: { skipped: "Skipped until released", fix: "Fix the cause first" },
|
|
2570
3268
|
samples: { conflicts: "Conflicts, never guessed", unmatchedVariants: "Variants without a match (SKU)", noPrice: "Without a price in this level" },
|
|
2571
3269
|
blocked: {
|
|
2572
3270
|
currency_mismatch: "The price level is in another currency than priceCurrency: nothing was planned.",
|
|
@@ -2576,11 +3274,11 @@ const en = {
|
|
|
2576
3274
|
tasks: {
|
|
2577
3275
|
title: "Queue",
|
|
2578
3276
|
subtitle: "Orders on their way to Subiekt: every ZK, WZ, invoice or receipt the store asked for, and how it went. A send that failed waits here for you, with a Send again button.",
|
|
2579
|
-
|
|
3277
|
+
points: { order: "One row per call", retries: "Retries by itself", failed: "Failed waits for you" },
|
|
3278
|
+
emptyBy: { attention: "Nothing needs attention", open: "Nothing on its way", done: "Nothing sent yet", all: "Queue empty" },
|
|
2580
3279
|
filters: { attention: "Need attention", open: "Open", done: "Done", all: "All" },
|
|
2581
3280
|
search: "Order number",
|
|
2582
|
-
|
|
2583
|
-
columns: { order: "Order in the store", operation: "Operation", status: "Status", attempts: "Attempts", document: "Document in Subiekt", details: "Details", actions: "" },
|
|
3281
|
+
columns: { order: "Order in the store", products: "Products", operation: "Operation", status: "Status", attempts: "Attempts", document: "Document in Subiekt", details: "Details", actions: "" },
|
|
2584
3282
|
kinds: { "order.create": "Create ZK", "order.cancel": "Cancel ZK", "order.fulfill": "Issue WZ", "order.document": "Issue sales document" },
|
|
2585
3283
|
documentKinds: { fs: "Issue FS", pa: "Issue PA" },
|
|
2586
3284
|
statuses: {
|
|
@@ -2603,17 +3301,20 @@ const en = {
|
|
|
2603
3301
|
documents: {
|
|
2604
3302
|
title: "Documents",
|
|
2605
3303
|
subtitle: "What Subiekt issued for your orders: ZK, WZ, invoices and receipts, each next to its order in the store.",
|
|
3304
|
+
points: { tag: "Order tag in the notes", warehouse: "WZ from the warehouse", ksef: "KSeF number on FS" },
|
|
3305
|
+
search: "Document or order number",
|
|
2606
3306
|
filters: { all: "All", ZK: "ZK", WZ: "WZ", FS: "FS", PA: "PA" },
|
|
2607
|
-
empty: "No documents yet
|
|
2608
|
-
columns: { number: "Number", order: "Order in the store", issued: "Issued", source: "Source", status: "Status", ksef: "KSeF number" },
|
|
2609
|
-
sources: { bridge: "Medusa", subiekt: "Warehouse", demo: "Demo" },
|
|
3307
|
+
empty: "No documents yet",
|
|
3308
|
+
columns: { number: "Number", order: "Order in the store", products: "Products", issued: "Issued", source: "Source", status: "Status", ksef: "KSeF number" },
|
|
3309
|
+
sources: { bridge: "Medusa", subiekt: "Warehouse", demo: "Demo", linked: "Linked by hand" },
|
|
2610
3310
|
statuses: { open: "Open", canceled: "Canceled", completed: "Completed" },
|
|
2611
3311
|
ksefWaiting: "waiting for KSeF"
|
|
2612
3312
|
},
|
|
2613
3313
|
stock: {
|
|
2614
3314
|
title: "Stock",
|
|
2615
3315
|
subtitle: "Subiekt to Medusa, by EAN first, then SKU against the product symbol.",
|
|
2616
|
-
|
|
3316
|
+
points: { direction: "Subiekt to Medusa", match: "EAN first, then SKU" },
|
|
3317
|
+
never: "No stock sync yet",
|
|
2617
3318
|
dryRun: "Dry run",
|
|
2618
3319
|
counters: {
|
|
2619
3320
|
subiektProducts: "Products in Subiekt",
|
|
@@ -2634,9 +3335,10 @@ const en = {
|
|
|
2634
3335
|
},
|
|
2635
3336
|
runs: {
|
|
2636
3337
|
title: "History",
|
|
2637
|
-
empty: "No runs yet
|
|
3338
|
+
empty: "No runs yet",
|
|
3339
|
+
points: { newest: "Newest first", jobs: "Background jobs and clicks" },
|
|
2638
3340
|
columns: { kind: "Job", trigger: "Trigger", status: "Result", message: "Summary", started: "Started", duration: "Time" },
|
|
2639
|
-
kinds: { stock: "Stock", events: "Documents", tasks: "Queue", health: "Connection", products: "Products" },
|
|
3341
|
+
kinds: { stock: "Stock", events: "Documents", tasks: "Queue", health: "Connection", products: "Products", catchup: "Safety net" },
|
|
2640
3342
|
triggers: { schedule: "Schedule", manual: "Manual", webhook: "Webhook", event: "Event", auto: "Automatic" },
|
|
2641
3343
|
statuses: { success: "OK", partial: "Partial", error: "Error", skipped: "Skipped" },
|
|
2642
3344
|
summary: {
|
|
@@ -2648,15 +3350,27 @@ const en = {
|
|
|
2648
3350
|
eventsNone: "Nothing new.",
|
|
2649
3351
|
health: "Bridge and Subiekt answer.",
|
|
2650
3352
|
productsPlan: "Plan: {{prices}} price change(s), {{creates}} new product(s). No writer armed.",
|
|
2651
|
-
productsApplied: "{{prices}} price change(s), {{creates}} new product(s) planned, {{applied}} applied, {{failed}} failed."
|
|
3353
|
+
productsApplied: "{{prices}} price change(s), {{creates}} new product(s) planned, {{applied}} applied, {{failed}} failed.",
|
|
3354
|
+
catchup: "{{queued}} order(s) without a ZK task queued, {{released}} released after the payment.",
|
|
3355
|
+
catchupErrors: "{{queued}} order(s) without a ZK task queued, {{released}} released after the payment, {{errors}} error(s)."
|
|
2652
3356
|
}
|
|
2653
3357
|
},
|
|
2654
3358
|
widget: {
|
|
2655
3359
|
title: "Subiekt nexo",
|
|
2656
3360
|
demo: "Demo",
|
|
2657
3361
|
more: "Panel",
|
|
2658
|
-
none: "
|
|
2659
|
-
waiting: "
|
|
3362
|
+
none: "Not sent to Subiekt",
|
|
3363
|
+
waiting: "ZK after the payment capture",
|
|
3364
|
+
state: { notSent: "Not sent", waiting: "Waiting for payment", sending: "Sending", attention: "Needs attention", inSubiekt: "In Subiekt" },
|
|
3365
|
+
run: {
|
|
3366
|
+
queue: "Waiting in the Medusa queue",
|
|
3367
|
+
queueShort: "Queue",
|
|
3368
|
+
bridge: "The bridge issues the document",
|
|
3369
|
+
bridgeShort: "Bridge",
|
|
3370
|
+
document: "The number comes back",
|
|
3371
|
+
documentShort: "Number",
|
|
3372
|
+
done: "In Subiekt"
|
|
3373
|
+
},
|
|
2660
3374
|
send: "Send to Subiekt now",
|
|
2661
3375
|
sent: "Queued. The ZK appears here in a few seconds.",
|
|
2662
3376
|
ksef: "KSeF {{number}}",
|
|
@@ -2665,7 +3379,29 @@ const en = {
|
|
|
2665
3379
|
issuePa: "Issue receipt (PA)",
|
|
2666
3380
|
issued: "Queued. The document appears here in a few seconds.",
|
|
2667
3381
|
autoOff: "Automatic sales documents are off: arm the writer on the Subiekt page.",
|
|
2668
|
-
autoOn: "The sales document is issued automatically after the {{after}}."
|
|
3382
|
+
autoOn: "The sales document is issued automatically after the {{after}}.",
|
|
3383
|
+
kinds: { ZK: "Order from customer (ZK)", WZ: "Goods issue (WZ)", FS: "Invoice (FS)", PA: "Receipt (PA)" },
|
|
3384
|
+
warehouse: "warehouse {{warehouse}}",
|
|
3385
|
+
related: "From {{numbers}}",
|
|
3386
|
+
zkCompleted: "Realized in Subiekt: the goods were released.",
|
|
3387
|
+
check: {
|
|
3388
|
+
button: "Check in Subiekt",
|
|
3389
|
+
again: "Check again",
|
|
3390
|
+
hint: "No ZK here? Check in Subiekt: if it is already there, link it to the order.",
|
|
3391
|
+
title: "In Subiekt now",
|
|
3392
|
+
at: "checked {{time}}",
|
|
3393
|
+
nothing: "Subiekt has no document for this order.",
|
|
3394
|
+
inSubiekt: "In Subiekt: {{status}}",
|
|
3395
|
+
notReported: "Subiekt does not report it (deleted there, or another database)",
|
|
3396
|
+
canceledThere: "Canceled in Subiekt.",
|
|
3397
|
+
states: { missing: "Not in Medusa", status_differs: "Medusa shows {{status}}", same: "Recorded", only_local: "Only in Medusa" },
|
|
3398
|
+
link: "Link",
|
|
3399
|
+
update: "Update status",
|
|
3400
|
+
linkHint: "Records it in Medusa. Nothing changes in Subiekt, no second document.",
|
|
3401
|
+
updateHint: "Records the status Subiekt shows. Nothing changes in Subiekt.",
|
|
3402
|
+
linked: "{{number}} linked to the order.",
|
|
3403
|
+
updated: "{{number}} updated."
|
|
3404
|
+
}
|
|
2669
3405
|
},
|
|
2670
3406
|
toast: {
|
|
2671
3407
|
started: "Started. Results appear here in a moment.",
|
|
@@ -2676,18 +3412,6 @@ const en = {
|
|
|
2676
3412
|
released: "Released. The next run tries it again.",
|
|
2677
3413
|
error: "Something went wrong: {{error}}"
|
|
2678
3414
|
},
|
|
2679
|
-
references: {
|
|
2680
|
-
title: "Running in stores built by Koda Plus",
|
|
2681
|
-
subtitle: "Live stores implemented by Koda Plus that run on this integration every day.",
|
|
2682
|
-
open: "Open the store",
|
|
2683
|
-
badgeOne: "Running in 1 store",
|
|
2684
|
-
badgeMany: "Running in {{count}} stores",
|
|
2685
|
-
badgeSoonOne: "Coming to 1 store",
|
|
2686
|
-
badgeSoonMany: "Coming to {{count}} stores",
|
|
2687
|
-
soon: "Soon",
|
|
2688
|
-
soonMore: "+{{count}} soon",
|
|
2689
|
-
review: "Read the review"
|
|
2690
|
-
},
|
|
2691
3415
|
community: communityEn,
|
|
2692
3416
|
guide: {
|
|
2693
3417
|
intro: {
|
|
@@ -2950,10 +3674,18 @@ const pl$1 = {
|
|
|
2950
3674
|
title: "Subiekt nexo",
|
|
2951
3675
|
by: "by Koda Plus",
|
|
2952
3676
|
subtitle: "Zamówienia trafiają do Subiekta nexo PRO jako dokumenty ZK, WZ wystawione w magazynie wraca do zamówienia, dokumenty sprzedaży dostają numer KSeF, a stany i ceny płyną z Subiekta do Medusy.",
|
|
3677
|
+
points: {
|
|
3678
|
+
orders: "Zamówienie jako ZK",
|
|
3679
|
+
wz: "WZ wraca z magazynu",
|
|
3680
|
+
sales: "Faktury z numerem KSeF",
|
|
3681
|
+
stock: "Stany z Subiekta",
|
|
3682
|
+
prices: "Ceny najpierw jako plan",
|
|
3683
|
+
safe: "Zapis dopiero po włączeniu"
|
|
3684
|
+
},
|
|
2953
3685
|
view: { panel: "Panel", guide: "Przewodnik wdrożenia" },
|
|
2954
3686
|
settings: {
|
|
2955
3687
|
title: "Ustawienia",
|
|
2956
|
-
subtitle: "Techniczna strona integracji
|
|
3688
|
+
subtitle: "Techniczna strona integracji",
|
|
2957
3689
|
tab: {
|
|
2958
3690
|
connection: "Połączenie",
|
|
2959
3691
|
bridge: "Most",
|
|
@@ -2972,6 +3704,7 @@ const pl$1 = {
|
|
|
2972
3704
|
},
|
|
2973
3705
|
actions: {
|
|
2974
3706
|
moreActions: "Więcej akcji",
|
|
3707
|
+
refresh: "Odśwież",
|
|
2975
3708
|
check: "Sprawdź połączenie",
|
|
2976
3709
|
checking: "Sprawdzam",
|
|
2977
3710
|
stock: "Synchronizuj stany",
|
|
@@ -3003,7 +3736,9 @@ const pl$1 = {
|
|
|
3003
3736
|
attention: "Wymagają uwagi",
|
|
3004
3737
|
zk: "Dokumenty ZK",
|
|
3005
3738
|
wz: "Dokumenty WZ",
|
|
3006
|
-
sales: "FS i PA"
|
|
3739
|
+
sales: "FS i PA",
|
|
3740
|
+
hintAttention: "Wyślij ponownie niżej",
|
|
3741
|
+
hintWaiting: "Wysyłka po płatności"
|
|
3007
3742
|
},
|
|
3008
3743
|
store: {
|
|
3009
3744
|
openOrder: "Otwórz zamówienie",
|
|
@@ -3031,11 +3766,12 @@ const pl$1 = {
|
|
|
3031
3766
|
never: "nigdy",
|
|
3032
3767
|
none: "brak",
|
|
3033
3768
|
eventsReadAt: "Dokumenty pobrane",
|
|
3034
|
-
|
|
3769
|
+
points: { queue: "Kolejka co minutę", documents: "Dokumenty co 2 min", stock: "Stany co 10 min", products: "Produkty co godzinę" }
|
|
3035
3770
|
},
|
|
3036
3771
|
bridge: {
|
|
3037
3772
|
title: "Most",
|
|
3038
3773
|
subtitle: "Co powiedziało ostatnie sprawdzenie mostu. Świeży odczyt daje przycisk Sprawdź połączenie.",
|
|
3774
|
+
points: { last: "Z ostatniego sprawdzenia", fresh: "Sprawdź połączenie czyta od nowa" },
|
|
3039
3775
|
versions: "Wersje",
|
|
3040
3776
|
versionsValue: "most {{bridge}}, kontrakt {{contract}}, wtyczka {{plugin}}",
|
|
3041
3777
|
sdk: "nexo SDK i baza",
|
|
@@ -3114,6 +3850,7 @@ const pl$1 = {
|
|
|
3114
3850
|
writers: {
|
|
3115
3851
|
title: "Przełączniki zapisu",
|
|
3116
3852
|
subtitle: "Każdy zapis dodany w 0.2.0 wymaga swojej opcji w medusa-config.ts i osoby, która włączy go tutaj. Opcja ustawiona na false wygrywa.",
|
|
3853
|
+
points: { option: "Opcja w medusa-config.ts", person: "Włącza tu człowiek", falseWins: "Opcja false wygrywa" },
|
|
3117
3854
|
demoNote: "Demo: włączone zapisy tylko symulują. W tym sklepie nic się nie zmienia.",
|
|
3118
3855
|
names: {
|
|
3119
3856
|
prices: "Ceny z Subiekta",
|
|
@@ -3160,6 +3897,7 @@ const pl$1 = {
|
|
|
3160
3897
|
products: {
|
|
3161
3898
|
title: "Produkty z Subiekta",
|
|
3162
3899
|
subtitle: "Ceny z Subiekta obok produktów w sklepie, które aktualizują, oraz towary z Subiekta, których sklep jeszcze nie sprzedaje. Najpierw wszystko jest planem: nic się nie zmienia, dopóki ktoś nie włączy zapisu w Ustawieniach.",
|
|
3900
|
+
points: { plan: "Najpierw plan", match: "Najpierw EAN, potem SKU", writer: "Zmiany po włączeniu zapisu" },
|
|
3163
3901
|
matching: "Towary z Subiekta są dopasowywane do wariantów w sklepie najpierw po EAN, potem po SKU porównanym z symbolem w Subiekcie. Kod użyty dwa razy to konflikt i nigdy nie jest zgadywany.",
|
|
3164
3902
|
matchedKey: "Dopasowane po {{by}}: {{code}}",
|
|
3165
3903
|
settings: "Ceny z {{level}} ({{type}}) do: {{target}}, w walucie {{currency}}.",
|
|
@@ -3195,10 +3933,11 @@ const pl$1 = {
|
|
|
3195
3933
|
columns: { product: "Towar w Subiekcie", change: "Zmiana", store: "Produkt w sklepie", matched: "Dopasowanie", status: "Status", details: "Szczegóły" },
|
|
3196
3934
|
matchedBy: { ean: "EAN", sku: "SKU" },
|
|
3197
3935
|
newProduct: "nowy, {{price}}",
|
|
3198
|
-
empty: "Nic w tym planie
|
|
3936
|
+
empty: "Nic w tym planie",
|
|
3199
3937
|
search: "Symbol, SKU albo EAN",
|
|
3200
3938
|
quarantine: "W kwarantannie po kolejnych błędach",
|
|
3201
3939
|
quarantineHint: "Zapis pomija te pozycje, dopóki ich nie zwolnisz. Najpierw usuń przyczynę (ostatni błąd mówi, co poszło nie tak).",
|
|
3940
|
+
quarantinePoints: { skipped: "Pomijane do zwolnienia", fix: "Najpierw usuń przyczynę" },
|
|
3202
3941
|
samples: { conflicts: "Konflikty, nigdy nie zgadujemy", unmatchedVariants: "Warianty bez dopasowania (SKU)", noPrice: "Bez ceny w tym poziomie" },
|
|
3203
3942
|
blocked: {
|
|
3204
3943
|
currency_mismatch: "Poziom cen jest w innej walucie niż priceCurrency: nic nie zaplanowano.",
|
|
@@ -3208,11 +3947,11 @@ const pl$1 = {
|
|
|
3208
3947
|
tasks: {
|
|
3209
3948
|
title: "Kolejka",
|
|
3210
3949
|
subtitle: "Zamówienia w drodze do Subiekta: każde ZK, WZ, faktura albo paragon, o które poprosił sklep, i jak poszło. Wysyłka, która się nie udała, czeka tu na Ciebie z przyciskiem Wyślij ponownie.",
|
|
3211
|
-
|
|
3950
|
+
points: { order: "Wiersz na każde wywołanie", retries: "Ponawia sama", failed: "Nieudane czeka na Ciebie" },
|
|
3951
|
+
emptyBy: { attention: "Nic nie wymaga uwagi", open: "Nic nie jest w drodze", done: "Jeszcze nic nie wysłano", all: "Kolejka pusta" },
|
|
3212
3952
|
filters: { attention: "Wymagają uwagi", open: "Otwarte", done: "Zakończone", all: "Wszystkie" },
|
|
3213
3953
|
search: "Numer zamówienia",
|
|
3214
|
-
|
|
3215
|
-
columns: { order: "Zamówienie w sklepie", operation: "Operacja", status: "Status", attempts: "Próby", document: "Dokument w Subiekcie", details: "Szczegóły", actions: "" },
|
|
3954
|
+
columns: { order: "Zamówienie w sklepie", products: "Produkty", operation: "Operacja", status: "Status", attempts: "Próby", document: "Dokument w Subiekcie", details: "Szczegóły", actions: "" },
|
|
3216
3955
|
kinds: { "order.create": "Utwórz ZK", "order.cancel": "Anuluj ZK", "order.fulfill": "Wystaw WZ", "order.document": "Wystaw dokument sprzedaży" },
|
|
3217
3956
|
documentKinds: { fs: "Wystaw FS", pa: "Wystaw PA" },
|
|
3218
3957
|
statuses: {
|
|
@@ -3235,17 +3974,20 @@ const pl$1 = {
|
|
|
3235
3974
|
documents: {
|
|
3236
3975
|
title: "Dokumenty",
|
|
3237
3976
|
subtitle: "Co Subiekt wystawił do Twoich zamówień: ZK, WZ, faktury i paragony, każdy dokument obok swojego zamówienia w sklepie.",
|
|
3977
|
+
points: { tag: "Znacznik zamówienia w uwagach", warehouse: "WZ z magazynu", ksef: "Numer KSeF na FS" },
|
|
3978
|
+
search: "Numer dokumentu albo zamówienia",
|
|
3238
3979
|
filters: { all: "Wszystkie", ZK: "ZK", WZ: "WZ", FS: "FS", PA: "PA" },
|
|
3239
|
-
empty: "Jeszcze
|
|
3240
|
-
columns: { number: "Numer", order: "Zamówienie w sklepie", issued: "Wystawiono", source: "Źródło", status: "Status", ksef: "Numer KSeF" },
|
|
3241
|
-
sources: { bridge: "Medusa", subiekt: "Magazyn", demo: "Demo" },
|
|
3980
|
+
empty: "Jeszcze bez dokumentów",
|
|
3981
|
+
columns: { number: "Numer", order: "Zamówienie w sklepie", products: "Produkty", issued: "Wystawiono", source: "Źródło", status: "Status", ksef: "Numer KSeF" },
|
|
3982
|
+
sources: { bridge: "Medusa", subiekt: "Magazyn", demo: "Demo", linked: "Połączone ręcznie" },
|
|
3242
3983
|
statuses: { open: "Otwarty", canceled: "Anulowany", completed: "Zrealizowany" },
|
|
3243
3984
|
ksefWaiting: "czeka na KSeF"
|
|
3244
3985
|
},
|
|
3245
3986
|
stock: {
|
|
3246
3987
|
title: "Stany",
|
|
3247
3988
|
subtitle: "Z Subiekta do Medusy, najpierw po EAN, potem po SKU porównanym z symbolem towaru.",
|
|
3248
|
-
|
|
3989
|
+
points: { direction: "Z Subiekta do Medusy", match: "Najpierw EAN, potem SKU" },
|
|
3990
|
+
never: "Stany jeszcze nie synchronizowane",
|
|
3249
3991
|
dryRun: "Próba na sucho",
|
|
3250
3992
|
counters: {
|
|
3251
3993
|
subiektProducts: "Towary w Subiekcie",
|
|
@@ -3266,9 +4008,10 @@ const pl$1 = {
|
|
|
3266
4008
|
},
|
|
3267
4009
|
runs: {
|
|
3268
4010
|
title: "Historia",
|
|
3269
|
-
empty: "Jeszcze
|
|
4011
|
+
empty: "Jeszcze bez uruchomień",
|
|
4012
|
+
points: { newest: "Najnowsze na górze", jobs: "Zadania w tle i kliknięcia" },
|
|
3270
4013
|
columns: { kind: "Zadanie", trigger: "Wyzwalacz", status: "Wynik", message: "Podsumowanie", started: "Start", duration: "Czas" },
|
|
3271
|
-
kinds: { stock: "Stany", events: "Dokumenty", tasks: "Kolejka", health: "Połączenie", products: "Produkty" },
|
|
4014
|
+
kinds: { stock: "Stany", events: "Dokumenty", tasks: "Kolejka", health: "Połączenie", products: "Produkty", catchup: "Siatka bezpieczeństwa" },
|
|
3272
4015
|
triggers: { schedule: "Harmonogram", manual: "Ręcznie", webhook: "Webhook", event: "Zdarzenie", auto: "Automatycznie" },
|
|
3273
4016
|
statuses: { success: "OK", partial: "Częściowo", error: "Błąd", skipped: "Pominięto" },
|
|
3274
4017
|
summary: {
|
|
@@ -3280,15 +4023,27 @@ const pl$1 = {
|
|
|
3280
4023
|
eventsNone: "Nic nowego.",
|
|
3281
4024
|
health: "Most i Subiekt odpowiadają.",
|
|
3282
4025
|
productsPlan: "Plan: zmiany cen {{prices}}, nowe produkty {{creates}}. Żaden zapis nie jest włączony.",
|
|
3283
|
-
productsApplied: "Zaplanowane zmiany cen: {{prices}}, nowe produkty: {{creates}}, naniesione: {{applied}}, nieudane: {{failed}}."
|
|
4026
|
+
productsApplied: "Zaplanowane zmiany cen: {{prices}}, nowe produkty: {{creates}}, naniesione: {{applied}}, nieudane: {{failed}}.",
|
|
4027
|
+
catchup: "Zamówienia bez zadania ZK dodane do kolejki: {{queued}}, zwolnione po płatności: {{released}}.",
|
|
4028
|
+
catchupErrors: "Zamówienia bez zadania ZK dodane do kolejki: {{queued}}, zwolnione po płatności: {{released}}, błędy: {{errors}}."
|
|
3284
4029
|
}
|
|
3285
4030
|
},
|
|
3286
4031
|
widget: {
|
|
3287
4032
|
title: "Subiekt nexo",
|
|
3288
4033
|
demo: "Demo",
|
|
3289
4034
|
more: "Panel",
|
|
3290
|
-
none: "
|
|
3291
|
-
waiting: "ZK
|
|
4035
|
+
none: "Nie wysłano do Subiekta",
|
|
4036
|
+
waiting: "ZK po zaksięgowaniu płatności",
|
|
4037
|
+
state: { notSent: "Nie wysłano", waiting: "Czeka na płatność", sending: "Wysyłka", attention: "Wymaga uwagi", inSubiekt: "W Subiekcie" },
|
|
4038
|
+
run: {
|
|
4039
|
+
queue: "Czeka w kolejce Medusy",
|
|
4040
|
+
queueShort: "Kolejka",
|
|
4041
|
+
bridge: "Most wystawia dokument",
|
|
4042
|
+
bridgeShort: "Most",
|
|
4043
|
+
document: "Numer wraca do Medusy",
|
|
4044
|
+
documentShort: "Numer",
|
|
4045
|
+
done: "W Subiekcie"
|
|
4046
|
+
},
|
|
3292
4047
|
send: "Wyślij do Subiekta teraz",
|
|
3293
4048
|
sent: "W kolejce. ZK pojawi się tu za kilka sekund.",
|
|
3294
4049
|
ksef: "KSeF {{number}}",
|
|
@@ -3297,7 +4052,29 @@ const pl$1 = {
|
|
|
3297
4052
|
issuePa: "Wystaw paragon (PA)",
|
|
3298
4053
|
issued: "W kolejce. Dokument pojawi się tu za kilka sekund.",
|
|
3299
4054
|
autoOff: "Automatyczne dokumenty sprzedaży są wyłączone: włącz zapis na stronie Subiekta.",
|
|
3300
|
-
autoOn: "Dokument sprzedaży powstanie automatycznie po {{after}}."
|
|
4055
|
+
autoOn: "Dokument sprzedaży powstanie automatycznie po {{after}}.",
|
|
4056
|
+
kinds: { ZK: "Zamówienie od klienta (ZK)", WZ: "Wydanie zewnętrzne (WZ)", FS: "Faktura (FS)", PA: "Paragon (PA)" },
|
|
4057
|
+
warehouse: "magazyn {{warehouse}}",
|
|
4058
|
+
related: "Na podstawie {{numbers}}",
|
|
4059
|
+
zkCompleted: "Zrealizowane w Subiekcie: towar wydano.",
|
|
4060
|
+
check: {
|
|
4061
|
+
button: "Sprawdź w Subiekcie",
|
|
4062
|
+
again: "Sprawdź ponownie",
|
|
4063
|
+
hint: "Nie ma tu ZK? Sprawdź w Subiekcie: jeśli już tam jest, połącz je z zamówieniem.",
|
|
4064
|
+
title: "W Subiekcie teraz",
|
|
4065
|
+
at: "sprawdzono {{time}}",
|
|
4066
|
+
nothing: "Subiekt nie ma żadnego dokumentu do tego zamówienia.",
|
|
4067
|
+
inSubiekt: "W Subiekcie: {{status}}",
|
|
4068
|
+
notReported: "Subiekt go nie zgłasza (usunięty tam albo inna baza)",
|
|
4069
|
+
canceledThere: "Anulowany w Subiekcie.",
|
|
4070
|
+
states: { missing: "Brak w Medusie", status_differs: "Medusa pokazuje: {{status}}", same: "Zapisany", only_local: "Tylko w Medusie" },
|
|
4071
|
+
link: "Połącz",
|
|
4072
|
+
update: "Zaktualizuj status",
|
|
4073
|
+
linkHint: "Zapisuje go w Medusie. W Subiekcie nic się nie zmienia, drugi dokument nie powstanie.",
|
|
4074
|
+
updateHint: "Zapisuje status, który pokazuje Subiekt. W Subiekcie nic się nie zmienia.",
|
|
4075
|
+
linked: "{{number}} połączony z zamówieniem.",
|
|
4076
|
+
updated: "{{number}} zaktualizowany."
|
|
4077
|
+
}
|
|
3301
4078
|
},
|
|
3302
4079
|
toast: {
|
|
3303
4080
|
started: "Uruchomione. Wynik pojawi się tu za chwilę.",
|
|
@@ -3308,18 +4085,6 @@ const pl$1 = {
|
|
|
3308
4085
|
released: "Zwolnione. Następny przebieg spróbuje ponownie.",
|
|
3309
4086
|
error: "Coś poszło nie tak: {{error}}"
|
|
3310
4087
|
},
|
|
3311
|
-
references: {
|
|
3312
|
-
title: "Działa w sklepach wdrożonych przez Koda Plus",
|
|
3313
|
-
subtitle: "Prawdziwe sklepy z wdrożeniem Koda Plus, które pracują na tej integracji na co dzień.",
|
|
3314
|
-
open: "Otwórz sklep",
|
|
3315
|
-
badgeOne: "Działa w 1 sklepie",
|
|
3316
|
-
badgeMany: "Działa w {{count}} sklepach",
|
|
3317
|
-
badgeSoonOne: "Wkrótce w 1 sklepie",
|
|
3318
|
-
badgeSoonMany: "Wkrótce w {{count}} sklepach",
|
|
3319
|
-
soon: "Wkrótce",
|
|
3320
|
-
soonMore: "+{{count}} wkrótce",
|
|
3321
|
-
review: "Zobacz opinię"
|
|
3322
|
-
},
|
|
3323
4088
|
community: communityPl,
|
|
3324
4089
|
guide: {
|
|
3325
4090
|
intro: {
|