epiq 1.2.2 → 1.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/dist/gui/main.js +671 -218
- package/dist/index.js +53 -52
- package/dist/mcp.js +44 -43
- package/package.json +1 -1
package/dist/gui/main.js
CHANGED
|
@@ -1328,7 +1328,7 @@ var require_react_dom_development = __commonJS({
|
|
|
1328
1328
|
return dispatcher;
|
|
1329
1329
|
}
|
|
1330
1330
|
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error());
|
|
1331
|
-
var
|
|
1331
|
+
var React17 = require_react(), Internals = {
|
|
1332
1332
|
d: {
|
|
1333
1333
|
f: noop,
|
|
1334
1334
|
r: function() {
|
|
@@ -1346,7 +1346,7 @@ var require_react_dom_development = __commonJS({
|
|
|
1346
1346
|
},
|
|
1347
1347
|
p: 0,
|
|
1348
1348
|
findDOMNode: null
|
|
1349
|
-
}, REACT_PORTAL_TYPE = Symbol.for("react.portal"), ReactSharedInternals =
|
|
1349
|
+
}, REACT_PORTAL_TYPE = Symbol.for("react.portal"), ReactSharedInternals = React17.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;
|
|
1350
1350
|
"function" === typeof Map && null != Map.prototype && "function" === typeof Map.prototype.forEach && "function" === typeof Set && null != Set.prototype && "function" === typeof Set.prototype.clear && "function" === typeof Set.prototype.forEach || console.error(
|
|
1351
1351
|
"React depends on Map and Set built-in types. Make sure that you load a polyfill in older browsers. https://reactjs.org/link/react-polyfills"
|
|
1352
1352
|
);
|
|
@@ -2881,7 +2881,7 @@ var require_react_dom_client_development = __commonJS({
|
|
|
2881
2881
|
"number" === type && getActiveElement(node.ownerDocument) === node || node.defaultValue === "" + value || (node.defaultValue = "" + value);
|
|
2882
2882
|
}
|
|
2883
2883
|
function validateOptionProps(element, props) {
|
|
2884
|
-
null == props.value && ("object" === typeof props.children && null !== props.children ?
|
|
2884
|
+
null == props.value && ("object" === typeof props.children && null !== props.children ? React17.Children.forEach(props.children, function(child) {
|
|
2885
2885
|
null == child || "string" === typeof child || "number" === typeof child || "bigint" === typeof child || didWarnInvalidChild || (didWarnInvalidChild = true, console.error(
|
|
2886
2886
|
"Cannot infer the option value of complex children. Pass a `value` prop or use a plain string as children to <option>."
|
|
2887
2887
|
));
|
|
@@ -18513,14 +18513,14 @@ var require_react_dom_client_development = __commonJS({
|
|
|
18513
18513
|
));
|
|
18514
18514
|
}
|
|
18515
18515
|
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error());
|
|
18516
|
-
var Scheduler = require_scheduler(),
|
|
18516
|
+
var Scheduler = require_scheduler(), React17 = require_react(), ReactDOM = require_react_dom(), assign = Object.assign, REACT_LEGACY_ELEMENT_TYPE = Symbol.for("react.element"), REACT_ELEMENT_TYPE = Symbol.for("react.transitional.element"), REACT_PORTAL_TYPE = Symbol.for("react.portal"), REACT_FRAGMENT_TYPE = Symbol.for("react.fragment"), REACT_STRICT_MODE_TYPE = Symbol.for("react.strict_mode"), REACT_PROFILER_TYPE = Symbol.for("react.profiler"), REACT_CONSUMER_TYPE = Symbol.for("react.consumer"), REACT_CONTEXT_TYPE = Symbol.for("react.context"), REACT_FORWARD_REF_TYPE = Symbol.for("react.forward_ref"), REACT_SUSPENSE_TYPE = Symbol.for("react.suspense"), REACT_SUSPENSE_LIST_TYPE = Symbol.for("react.suspense_list"), REACT_MEMO_TYPE = Symbol.for("react.memo"), REACT_LAZY_TYPE = Symbol.for("react.lazy");
|
|
18517
18517
|
Symbol.for("react.scope");
|
|
18518
18518
|
var REACT_ACTIVITY_TYPE = Symbol.for("react.activity");
|
|
18519
18519
|
Symbol.for("react.legacy_hidden");
|
|
18520
18520
|
Symbol.for("react.tracing_marker");
|
|
18521
18521
|
var REACT_MEMO_CACHE_SENTINEL = Symbol.for("react.memo_cache_sentinel");
|
|
18522
18522
|
Symbol.for("react.view_transition");
|
|
18523
|
-
var MAYBE_ITERATOR_SYMBOL = Symbol.iterator, REACT_CLIENT_REFERENCE = Symbol.for("react.client.reference"), isArrayImpl = Array.isArray, ReactSharedInternals =
|
|
18523
|
+
var MAYBE_ITERATOR_SYMBOL = Symbol.iterator, REACT_CLIENT_REFERENCE = Symbol.for("react.client.reference"), isArrayImpl = Array.isArray, ReactSharedInternals = React17.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, ReactDOMSharedInternals = ReactDOM.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, NotPending = Object.freeze({
|
|
18524
18524
|
pending: false,
|
|
18525
18525
|
data: null,
|
|
18526
18526
|
method: null,
|
|
@@ -21308,7 +21308,7 @@ var require_react_dom_client_development = __commonJS({
|
|
|
21308
21308
|
}
|
|
21309
21309
|
};
|
|
21310
21310
|
(function() {
|
|
21311
|
-
var isomorphicReactPackageVersion =
|
|
21311
|
+
var isomorphicReactPackageVersion = React17.version;
|
|
21312
21312
|
if ("19.2.6" !== isomorphicReactPackageVersion)
|
|
21313
21313
|
throw Error(
|
|
21314
21314
|
'Incompatible React versions: The "react" and "react-dom" packages must have the exact same version. Instead got:\n - react: ' + (isomorphicReactPackageVersion + "\n - react-dom: 19.2.6\nLearn more: https://react.dev/warnings/version-mismatch")
|
|
@@ -21662,18 +21662,18 @@ var require_react_jsx_runtime_development = __commonJS({
|
|
|
21662
21662
|
function isValidElement2(object) {
|
|
21663
21663
|
return "object" === typeof object && null !== object && object.$$typeof === REACT_ELEMENT_TYPE;
|
|
21664
21664
|
}
|
|
21665
|
-
var
|
|
21665
|
+
var React17 = require_react(), REACT_ELEMENT_TYPE = Symbol.for("react.transitional.element"), REACT_PORTAL_TYPE = Symbol.for("react.portal"), REACT_FRAGMENT_TYPE = Symbol.for("react.fragment"), REACT_STRICT_MODE_TYPE = Symbol.for("react.strict_mode"), REACT_PROFILER_TYPE = Symbol.for("react.profiler"), REACT_CONSUMER_TYPE = Symbol.for("react.consumer"), REACT_CONTEXT_TYPE = Symbol.for("react.context"), REACT_FORWARD_REF_TYPE = Symbol.for("react.forward_ref"), REACT_SUSPENSE_TYPE = Symbol.for("react.suspense"), REACT_SUSPENSE_LIST_TYPE = Symbol.for("react.suspense_list"), REACT_MEMO_TYPE = Symbol.for("react.memo"), REACT_LAZY_TYPE = Symbol.for("react.lazy"), REACT_ACTIVITY_TYPE = Symbol.for("react.activity"), REACT_CLIENT_REFERENCE = Symbol.for("react.client.reference"), ReactSharedInternals = React17.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, hasOwnProperty = Object.prototype.hasOwnProperty, isArrayImpl = Array.isArray, createTask = console.createTask ? console.createTask : function() {
|
|
21666
21666
|
return null;
|
|
21667
21667
|
};
|
|
21668
|
-
|
|
21668
|
+
React17 = {
|
|
21669
21669
|
react_stack_bottom_frame: function(callStackForError) {
|
|
21670
21670
|
return callStackForError();
|
|
21671
21671
|
}
|
|
21672
21672
|
};
|
|
21673
21673
|
var specialPropKeyWarningShown;
|
|
21674
21674
|
var didWarnAboutElementRef = {};
|
|
21675
|
-
var unknownOwnerDebugStack =
|
|
21676
|
-
|
|
21675
|
+
var unknownOwnerDebugStack = React17.react_stack_bottom_frame.bind(
|
|
21676
|
+
React17,
|
|
21677
21677
|
UnknownOwner
|
|
21678
21678
|
)();
|
|
21679
21679
|
var unknownOwnerDebugTask = createTask(getTaskName(UnknownOwner));
|
|
@@ -24492,7 +24492,7 @@ function useViewTransitionState(to, { relative } = {}) {
|
|
|
24492
24492
|
}
|
|
24493
24493
|
|
|
24494
24494
|
// source/gui/client/App.tsx
|
|
24495
|
-
var
|
|
24495
|
+
var import_react9 = __toESM(require_react(), 1);
|
|
24496
24496
|
|
|
24497
24497
|
// source/gui/client/components/Button.tsx
|
|
24498
24498
|
var import_react = __toESM(require_react(), 1);
|
|
@@ -24911,12 +24911,13 @@ var User = ({
|
|
|
24911
24911
|
);
|
|
24912
24912
|
|
|
24913
24913
|
// source/version.ts
|
|
24914
|
-
var EPIQ_VERSION = "1.
|
|
24914
|
+
var EPIQ_VERSION = "1.3.0";
|
|
24915
24915
|
|
|
24916
24916
|
// source/gui/client/components/Header.tsx
|
|
24917
24917
|
var import_jsx_runtime6 = __toESM(require_jsx_runtime(), 1);
|
|
24918
24918
|
var Header = ({ state, connected, syncStatus }) => {
|
|
24919
24919
|
const syncColor = syncStatus.status === "synced" ? GUI_THEME.green : syncStatus.status === "failed" ? GUI_THEME.red : GUI_THEME.accent;
|
|
24920
|
+
const syncLabel = syncStatus.status === "failed" ? "-" : syncStatus.msg.toLowerCase();
|
|
24920
24921
|
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
24921
24922
|
Panel,
|
|
24922
24923
|
{
|
|
@@ -24986,12 +24987,17 @@ var Header = ({ state, connected, syncStatus }) => {
|
|
|
24986
24987
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
24987
24988
|
"span",
|
|
24988
24989
|
{
|
|
24990
|
+
title: syncStatus.status === "failed" ? syncStatus.msg : void 0,
|
|
24989
24991
|
style: {
|
|
24990
24992
|
color: GUI_THEME.dim,
|
|
24991
24993
|
minWidth: 72,
|
|
24994
|
+
maxWidth: 220,
|
|
24995
|
+
overflow: "hidden",
|
|
24996
|
+
textOverflow: "ellipsis",
|
|
24997
|
+
whiteSpace: "nowrap",
|
|
24992
24998
|
textAlign: "right"
|
|
24993
24999
|
},
|
|
24994
|
-
children: connected ?
|
|
25000
|
+
children: connected ? syncLabel : "-"
|
|
24995
25001
|
}
|
|
24996
25002
|
),
|
|
24997
25003
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
@@ -25042,7 +25048,7 @@ var Header = ({ state, connected, syncStatus }) => {
|
|
|
25042
25048
|
};
|
|
25043
25049
|
|
|
25044
25050
|
// source/gui/client/components/IssueDetails.tsx
|
|
25045
|
-
var
|
|
25051
|
+
var import_react7 = __toESM(require_react(), 1);
|
|
25046
25052
|
|
|
25047
25053
|
// source/gui/client/components/Aside.tsx
|
|
25048
25054
|
var import_jsx_runtime7 = __toESM(require_jsx_runtime(), 1);
|
|
@@ -25062,9 +25068,60 @@ var Aside = ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
|
25062
25068
|
}
|
|
25063
25069
|
);
|
|
25064
25070
|
|
|
25065
|
-
// source/gui/client/components/
|
|
25071
|
+
// source/gui/client/components/CopyRef.tsx
|
|
25072
|
+
var import_react4 = __toESM(require_react(), 1);
|
|
25066
25073
|
var import_jsx_runtime8 = __toESM(require_jsx_runtime(), 1);
|
|
25067
|
-
var
|
|
25074
|
+
var copyToClipboard = async (value) => {
|
|
25075
|
+
try {
|
|
25076
|
+
await navigator.clipboard.writeText(value);
|
|
25077
|
+
return true;
|
|
25078
|
+
} catch {
|
|
25079
|
+
return false;
|
|
25080
|
+
}
|
|
25081
|
+
};
|
|
25082
|
+
var CopyRef = ({ refValue }) => {
|
|
25083
|
+
const [copied, setCopied] = (0, import_react4.useState)(false);
|
|
25084
|
+
const resetTimer = (0, import_react4.useRef)(
|
|
25085
|
+
void 0
|
|
25086
|
+
);
|
|
25087
|
+
(0, import_react4.useEffect)(() => () => clearTimeout(resetTimer.current), []);
|
|
25088
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
25089
|
+
"button",
|
|
25090
|
+
{
|
|
25091
|
+
type: "button",
|
|
25092
|
+
title: `Copy ${refValue}`,
|
|
25093
|
+
onClick: async (event) => {
|
|
25094
|
+
event.stopPropagation();
|
|
25095
|
+
if (await copyToClipboard(refValue)) {
|
|
25096
|
+
setCopied(true);
|
|
25097
|
+
clearTimeout(resetTimer.current);
|
|
25098
|
+
resetTimer.current = setTimeout(() => setCopied(false), 1200);
|
|
25099
|
+
}
|
|
25100
|
+
},
|
|
25101
|
+
style: {
|
|
25102
|
+
fontFamily: "monospace",
|
|
25103
|
+
fontSize: "inherit",
|
|
25104
|
+
color: copied ? GUI_THEME.green : GUI_THEME.dim,
|
|
25105
|
+
background: "transparent",
|
|
25106
|
+
border: "none",
|
|
25107
|
+
padding: 0,
|
|
25108
|
+
cursor: "pointer",
|
|
25109
|
+
transition: "color 120ms ease"
|
|
25110
|
+
},
|
|
25111
|
+
onMouseEnter: (event) => {
|
|
25112
|
+
if (!copied) event.currentTarget.style.color = GUI_THEME.accent;
|
|
25113
|
+
},
|
|
25114
|
+
onMouseLeave: (event) => {
|
|
25115
|
+
event.currentTarget.style.color = copied ? GUI_THEME.green : GUI_THEME.dim;
|
|
25116
|
+
},
|
|
25117
|
+
children: copied ? "copied!" : refValue
|
|
25118
|
+
}
|
|
25119
|
+
);
|
|
25120
|
+
};
|
|
25121
|
+
|
|
25122
|
+
// source/gui/client/components/FormHeader.tsx
|
|
25123
|
+
var import_jsx_runtime9 = __toESM(require_jsx_runtime(), 1);
|
|
25124
|
+
var FormHeader = ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
25068
25125
|
"div",
|
|
25069
25126
|
{
|
|
25070
25127
|
style: {
|
|
@@ -25079,8 +25136,8 @@ var FormHeader = ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
|
25079
25136
|
);
|
|
25080
25137
|
|
|
25081
25138
|
// source/gui/client/components/FormPrimitives.tsx
|
|
25082
|
-
var
|
|
25083
|
-
var Input = (props) => /* @__PURE__ */ (0,
|
|
25139
|
+
var import_jsx_runtime10 = __toESM(require_jsx_runtime(), 1);
|
|
25140
|
+
var Input = (props) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
25084
25141
|
"input",
|
|
25085
25142
|
{
|
|
25086
25143
|
...props,
|
|
@@ -25098,7 +25155,7 @@ var Input = (props) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
|
25098
25155
|
}
|
|
25099
25156
|
}
|
|
25100
25157
|
);
|
|
25101
|
-
var Textarea = (props) => /* @__PURE__ */ (0,
|
|
25158
|
+
var Textarea = (props) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
25102
25159
|
"textarea",
|
|
25103
25160
|
{
|
|
25104
25161
|
maxLength: props.maxLength ?? 1500,
|
|
@@ -25120,19 +25177,309 @@ var Textarea = (props) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
|
25120
25177
|
}
|
|
25121
25178
|
}
|
|
25122
25179
|
);
|
|
25123
|
-
var ActionRow = ({ children }) => /* @__PURE__ */ (0,
|
|
25180
|
+
var ActionRow = ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
25124
25181
|
"div",
|
|
25125
25182
|
{
|
|
25126
25183
|
style: { display: "flex", justifyContent: "flex-end", gap: 8, marginTop: 8 },
|
|
25127
25184
|
children
|
|
25128
25185
|
}
|
|
25129
25186
|
);
|
|
25130
|
-
var AddRow = ({ children }) => /* @__PURE__ */ (0,
|
|
25131
|
-
var ChipRow = ({ children }) => /* @__PURE__ */ (0,
|
|
25132
|
-
var Empty = ({ children }) => /* @__PURE__ */ (0,
|
|
25187
|
+
var AddRow = ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { style: { display: "flex", gap: 8, marginTop: 10 }, children });
|
|
25188
|
+
var ChipRow = ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { style: { display: "flex", gap: 8, flexWrap: "wrap", marginTop: 10 }, children });
|
|
25189
|
+
var Empty = ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { style: { display: "inline-block", marginTop: 8, color: GUI_THEME.dim }, children });
|
|
25190
|
+
|
|
25191
|
+
// source/gui/client/components/IssueAttachments.tsx
|
|
25192
|
+
var import_react5 = __toESM(require_react(), 1);
|
|
25193
|
+
|
|
25194
|
+
// source/gui/client/components/Section.tsx
|
|
25195
|
+
var import_jsx_runtime11 = __toESM(require_jsx_runtime(), 1);
|
|
25196
|
+
var Section = ({
|
|
25197
|
+
title,
|
|
25198
|
+
action,
|
|
25199
|
+
children,
|
|
25200
|
+
first = false
|
|
25201
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
25202
|
+
"section",
|
|
25203
|
+
{
|
|
25204
|
+
style: {
|
|
25205
|
+
padding: first ? "0px 0 14px 0" : "14px 0",
|
|
25206
|
+
borderTop: first ? "none" : `1px solid ${GUI_THEME.line}`
|
|
25207
|
+
},
|
|
25208
|
+
children: [
|
|
25209
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
25210
|
+
"div",
|
|
25211
|
+
{
|
|
25212
|
+
style: {
|
|
25213
|
+
display: "flex",
|
|
25214
|
+
justifyContent: "space-between",
|
|
25215
|
+
alignItems: "center",
|
|
25216
|
+
gap: 12
|
|
25217
|
+
},
|
|
25218
|
+
children: [
|
|
25219
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
25220
|
+
"span",
|
|
25221
|
+
{
|
|
25222
|
+
style: {
|
|
25223
|
+
color: GUI_THEME.secondary,
|
|
25224
|
+
fontSize: 10,
|
|
25225
|
+
textTransform: "uppercase",
|
|
25226
|
+
letterSpacing: "0.08em"
|
|
25227
|
+
},
|
|
25228
|
+
children: title
|
|
25229
|
+
}
|
|
25230
|
+
),
|
|
25231
|
+
action
|
|
25232
|
+
]
|
|
25233
|
+
}
|
|
25234
|
+
),
|
|
25235
|
+
children
|
|
25236
|
+
]
|
|
25237
|
+
}
|
|
25238
|
+
);
|
|
25239
|
+
|
|
25240
|
+
// source/gui/client/components/IssueAttachments.tsx
|
|
25241
|
+
var import_jsx_runtime12 = __toESM(require_jsx_runtime(), 1);
|
|
25242
|
+
var IssueAttachments = ({
|
|
25243
|
+
issueId,
|
|
25244
|
+
readonly,
|
|
25245
|
+
attachments,
|
|
25246
|
+
uploadStatus,
|
|
25247
|
+
onUploadFiles,
|
|
25248
|
+
onDeleteAttachment
|
|
25249
|
+
}) => {
|
|
25250
|
+
const [dragging, setDragging] = (0, import_react5.useState)(false);
|
|
25251
|
+
const [lightbox, setLightbox] = (0, import_react5.useState)(null);
|
|
25252
|
+
const [broken, setBroken] = (0, import_react5.useState)({});
|
|
25253
|
+
(0, import_react5.useEffect)(() => {
|
|
25254
|
+
setLightbox(null);
|
|
25255
|
+
setDragging(false);
|
|
25256
|
+
setBroken({});
|
|
25257
|
+
}, [issueId]);
|
|
25258
|
+
(0, import_react5.useEffect)(() => {
|
|
25259
|
+
if (!lightbox) return;
|
|
25260
|
+
const onKeyDown = (event) => {
|
|
25261
|
+
if (event.key === "Escape") setLightbox(null);
|
|
25262
|
+
};
|
|
25263
|
+
window.addEventListener("keydown", onKeyDown);
|
|
25264
|
+
return () => window.removeEventListener("keydown", onKeyDown);
|
|
25265
|
+
}, [lightbox]);
|
|
25266
|
+
const canUpload = !readonly && Boolean(onUploadFiles);
|
|
25267
|
+
const handleDrop = (event) => {
|
|
25268
|
+
event.preventDefault();
|
|
25269
|
+
setDragging(false);
|
|
25270
|
+
if (!canUpload) return;
|
|
25271
|
+
const files = Array.from(event.dataTransfer.files).filter(
|
|
25272
|
+
(file) => file.type.startsWith("image/")
|
|
25273
|
+
);
|
|
25274
|
+
if (files.length > 0) onUploadFiles?.(issueId, files);
|
|
25275
|
+
};
|
|
25276
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
25277
|
+
Section,
|
|
25278
|
+
{
|
|
25279
|
+
title: `Attachments${attachments.length ? ` (${attachments.length})` : ""}`,
|
|
25280
|
+
children: [
|
|
25281
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
25282
|
+
"div",
|
|
25283
|
+
{
|
|
25284
|
+
onDragOver: (event) => {
|
|
25285
|
+
if (!canUpload) return;
|
|
25286
|
+
event.preventDefault();
|
|
25287
|
+
setDragging(true);
|
|
25288
|
+
},
|
|
25289
|
+
onDragLeave: () => setDragging(false),
|
|
25290
|
+
onDrop: handleDrop,
|
|
25291
|
+
style: {
|
|
25292
|
+
marginTop: 8,
|
|
25293
|
+
padding: dragging ? 10 : 0,
|
|
25294
|
+
border: dragging ? `1px dashed ${GUI_THEME.accent}` : "1px dashed transparent",
|
|
25295
|
+
borderRadius: 4,
|
|
25296
|
+
transition: "padding 0.12s ease, border-color 0.12s ease"
|
|
25297
|
+
},
|
|
25298
|
+
children: [
|
|
25299
|
+
attachments.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Empty, { children: canUpload ? "No attachments \u2014 drop an image here" : "No attachments" }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
25300
|
+
"div",
|
|
25301
|
+
{
|
|
25302
|
+
style: {
|
|
25303
|
+
display: "flex",
|
|
25304
|
+
flexWrap: "wrap",
|
|
25305
|
+
gap: 8
|
|
25306
|
+
},
|
|
25307
|
+
children: attachments.map((attachment) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
25308
|
+
"div",
|
|
25309
|
+
{
|
|
25310
|
+
style: { position: "relative", width: 72, height: 72 },
|
|
25311
|
+
children: [
|
|
25312
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
25313
|
+
"button",
|
|
25314
|
+
{
|
|
25315
|
+
type: "button",
|
|
25316
|
+
disabled: broken[attachment.id],
|
|
25317
|
+
onClick: () => setLightbox(attachment),
|
|
25318
|
+
title: `${attachment.name} (${Math.max(
|
|
25319
|
+
1,
|
|
25320
|
+
Math.round(attachment.bytes / 1024)
|
|
25321
|
+
)} KB)`,
|
|
25322
|
+
style: {
|
|
25323
|
+
padding: 0,
|
|
25324
|
+
border: `1px solid ${GUI_THEME.line}`,
|
|
25325
|
+
borderRadius: 4,
|
|
25326
|
+
background: GUI_THEME.panel2,
|
|
25327
|
+
cursor: broken[attachment.id] ? "default" : "zoom-in",
|
|
25328
|
+
overflow: "hidden",
|
|
25329
|
+
width: "100%",
|
|
25330
|
+
height: "100%"
|
|
25331
|
+
},
|
|
25332
|
+
children: broken[attachment.id] ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
25333
|
+
"span",
|
|
25334
|
+
{
|
|
25335
|
+
title: "Attachment unavailable (missing, corrupt, or over the size cap)",
|
|
25336
|
+
style: {
|
|
25337
|
+
display: "flex",
|
|
25338
|
+
alignItems: "center",
|
|
25339
|
+
justifyContent: "center",
|
|
25340
|
+
width: "100%",
|
|
25341
|
+
height: "100%",
|
|
25342
|
+
color: GUI_THEME.dim2,
|
|
25343
|
+
fontSize: 9,
|
|
25344
|
+
padding: 4,
|
|
25345
|
+
textAlign: "center"
|
|
25346
|
+
},
|
|
25347
|
+
children: "unavailable"
|
|
25348
|
+
}
|
|
25349
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
25350
|
+
"img",
|
|
25351
|
+
{
|
|
25352
|
+
src: `/media/${attachment.fileName}`,
|
|
25353
|
+
alt: attachment.name,
|
|
25354
|
+
loading: "lazy",
|
|
25355
|
+
onError: () => setBroken((prev) => ({ ...prev, [attachment.id]: true })),
|
|
25356
|
+
style: {
|
|
25357
|
+
width: "100%",
|
|
25358
|
+
height: "100%",
|
|
25359
|
+
objectFit: "cover",
|
|
25360
|
+
display: "block"
|
|
25361
|
+
}
|
|
25362
|
+
}
|
|
25363
|
+
)
|
|
25364
|
+
}
|
|
25365
|
+
),
|
|
25366
|
+
attachment.canDelete && !readonly && onDeleteAttachment && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
25367
|
+
"button",
|
|
25368
|
+
{
|
|
25369
|
+
type: "button",
|
|
25370
|
+
title: "Delete attachment",
|
|
25371
|
+
onClick: () => onDeleteAttachment(issueId, attachment.id),
|
|
25372
|
+
style: {
|
|
25373
|
+
position: "absolute",
|
|
25374
|
+
top: 2,
|
|
25375
|
+
right: 2,
|
|
25376
|
+
width: 16,
|
|
25377
|
+
height: 16,
|
|
25378
|
+
lineHeight: "14px",
|
|
25379
|
+
padding: 0,
|
|
25380
|
+
border: `1px solid ${GUI_THEME.line}`,
|
|
25381
|
+
borderRadius: 3,
|
|
25382
|
+
background: "rgba(4, 5, 8, 0.75)",
|
|
25383
|
+
color: GUI_THEME.secondary,
|
|
25384
|
+
fontSize: 10,
|
|
25385
|
+
cursor: "pointer"
|
|
25386
|
+
},
|
|
25387
|
+
children: "\xD7"
|
|
25388
|
+
}
|
|
25389
|
+
)
|
|
25390
|
+
]
|
|
25391
|
+
},
|
|
25392
|
+
attachment.id
|
|
25393
|
+
))
|
|
25394
|
+
}
|
|
25395
|
+
),
|
|
25396
|
+
canUpload && attachments.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
25397
|
+
"div",
|
|
25398
|
+
{
|
|
25399
|
+
style: {
|
|
25400
|
+
marginTop: 8,
|
|
25401
|
+
color: GUI_THEME.dim2,
|
|
25402
|
+
fontSize: 10
|
|
25403
|
+
},
|
|
25404
|
+
children: "drop an image to attach"
|
|
25405
|
+
}
|
|
25406
|
+
),
|
|
25407
|
+
uploadStatus.state === "uploading" && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
25408
|
+
"div",
|
|
25409
|
+
{
|
|
25410
|
+
style: {
|
|
25411
|
+
marginTop: 8,
|
|
25412
|
+
color: GUI_THEME.secondary,
|
|
25413
|
+
fontSize: 11
|
|
25414
|
+
},
|
|
25415
|
+
children: [
|
|
25416
|
+
"uploading ",
|
|
25417
|
+
uploadStatus.name,
|
|
25418
|
+
"\u2026"
|
|
25419
|
+
]
|
|
25420
|
+
}
|
|
25421
|
+
),
|
|
25422
|
+
uploadStatus.state === "error" && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
25423
|
+
"div",
|
|
25424
|
+
{
|
|
25425
|
+
style: {
|
|
25426
|
+
marginTop: 8,
|
|
25427
|
+
color: GUI_THEME.red,
|
|
25428
|
+
fontSize: 11
|
|
25429
|
+
},
|
|
25430
|
+
children: uploadStatus.message
|
|
25431
|
+
}
|
|
25432
|
+
)
|
|
25433
|
+
]
|
|
25434
|
+
}
|
|
25435
|
+
),
|
|
25436
|
+
lightbox && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
25437
|
+
"div",
|
|
25438
|
+
{
|
|
25439
|
+
onClick: () => setLightbox(null),
|
|
25440
|
+
style: {
|
|
25441
|
+
position: "fixed",
|
|
25442
|
+
inset: 0,
|
|
25443
|
+
zIndex: 100,
|
|
25444
|
+
display: "flex",
|
|
25445
|
+
alignItems: "center",
|
|
25446
|
+
justifyContent: "center",
|
|
25447
|
+
flexDirection: "column",
|
|
25448
|
+
gap: 10,
|
|
25449
|
+
background: "rgba(4, 5, 8, 0.88)",
|
|
25450
|
+
cursor: "zoom-out"
|
|
25451
|
+
},
|
|
25452
|
+
children: [
|
|
25453
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
25454
|
+
"img",
|
|
25455
|
+
{
|
|
25456
|
+
src: `/media/${lightbox.fileName}`,
|
|
25457
|
+
alt: lightbox.name,
|
|
25458
|
+
style: {
|
|
25459
|
+
maxWidth: "90vw",
|
|
25460
|
+
maxHeight: "85vh",
|
|
25461
|
+
borderRadius: 6,
|
|
25462
|
+
border: `1px solid ${GUI_THEME.line}`
|
|
25463
|
+
}
|
|
25464
|
+
}
|
|
25465
|
+
),
|
|
25466
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { style: { color: GUI_THEME.secondary, fontSize: 11 }, children: [
|
|
25467
|
+
lightbox.name,
|
|
25468
|
+
" \xB7 ",
|
|
25469
|
+
Math.max(1, Math.round(lightbox.bytes / 1024)),
|
|
25470
|
+
" ",
|
|
25471
|
+
"KB \xB7 esc to close"
|
|
25472
|
+
] })
|
|
25473
|
+
]
|
|
25474
|
+
}
|
|
25475
|
+
)
|
|
25476
|
+
]
|
|
25477
|
+
}
|
|
25478
|
+
);
|
|
25479
|
+
};
|
|
25133
25480
|
|
|
25134
25481
|
// source/gui/client/components/IssueComments.tsx
|
|
25135
|
-
var
|
|
25482
|
+
var import_react6 = __toESM(require_react(), 1);
|
|
25136
25483
|
|
|
25137
25484
|
// source/gui/client/lib/gui-format.helper.ts
|
|
25138
25485
|
var timeAgo = (timestampMs) => {
|
|
@@ -25154,7 +25501,7 @@ var timeAgo = (timestampMs) => {
|
|
|
25154
25501
|
};
|
|
25155
25502
|
|
|
25156
25503
|
// source/gui/client/components/IssueComments.tsx
|
|
25157
|
-
var
|
|
25504
|
+
var import_jsx_runtime13 = __toESM(require_jsx_runtime(), 1);
|
|
25158
25505
|
var IssueComments = ({
|
|
25159
25506
|
whoAmI,
|
|
25160
25507
|
issueId,
|
|
@@ -25163,15 +25510,15 @@ var IssueComments = ({
|
|
|
25163
25510
|
onAddComment,
|
|
25164
25511
|
onDeleteComment
|
|
25165
25512
|
}) => {
|
|
25166
|
-
const [body, setBody] = (0,
|
|
25513
|
+
const [body, setBody] = (0, import_react6.useState)("");
|
|
25167
25514
|
const addComment = () => {
|
|
25168
25515
|
const nextBody = body.trim();
|
|
25169
25516
|
if (!nextBody) return;
|
|
25170
25517
|
onAddComment?.(issueId, nextBody);
|
|
25171
25518
|
setBody("");
|
|
25172
25519
|
};
|
|
25173
|
-
return /* @__PURE__ */ (0,
|
|
25174
|
-
comments.length === 0 ? /* @__PURE__ */ (0,
|
|
25520
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { children: [
|
|
25521
|
+
comments.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Empty, { children: "No comments" }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: { display: "flex", flexDirection: "column", gap: 12 }, children: comments.map((comment) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
25175
25522
|
"div",
|
|
25176
25523
|
{
|
|
25177
25524
|
style: {
|
|
@@ -25181,7 +25528,7 @@ var IssueComments = ({
|
|
|
25181
25528
|
background: GUI_THEME.tertiary
|
|
25182
25529
|
},
|
|
25183
25530
|
children: [
|
|
25184
|
-
/* @__PURE__ */ (0,
|
|
25531
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
25185
25532
|
"div",
|
|
25186
25533
|
{
|
|
25187
25534
|
style: {
|
|
@@ -25191,15 +25538,15 @@ var IssueComments = ({
|
|
|
25191
25538
|
marginBottom: 8
|
|
25192
25539
|
},
|
|
25193
25540
|
children: [
|
|
25194
|
-
/* @__PURE__ */ (0,
|
|
25541
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: { color: GUI_THEME.secondary, fontSize: 10 }, children: [
|
|
25195
25542
|
comment.author.name ?? "unknown",
|
|
25196
|
-
comment.createdAt && /* @__PURE__ */ (0,
|
|
25543
|
+
comment.createdAt && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { style: { color: GUI_THEME.dim2 }, children: [
|
|
25197
25544
|
" ",
|
|
25198
25545
|
"\xB7 ",
|
|
25199
25546
|
timeAgo(comment.createdAt)
|
|
25200
25547
|
] })
|
|
25201
25548
|
] }),
|
|
25202
|
-
comment.author.id === whoAmI.id && onDeleteComment && /* @__PURE__ */ (0,
|
|
25549
|
+
comment.author.id === whoAmI.id && onDeleteComment && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
25203
25550
|
Button,
|
|
25204
25551
|
{
|
|
25205
25552
|
variant: "ghost",
|
|
@@ -25214,7 +25561,7 @@ var IssueComments = ({
|
|
|
25214
25561
|
]
|
|
25215
25562
|
}
|
|
25216
25563
|
),
|
|
25217
|
-
/* @__PURE__ */ (0,
|
|
25564
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
25218
25565
|
"div",
|
|
25219
25566
|
{
|
|
25220
25567
|
style: {
|
|
@@ -25229,8 +25576,8 @@ var IssueComments = ({
|
|
|
25229
25576
|
},
|
|
25230
25577
|
comment.id
|
|
25231
25578
|
)) }),
|
|
25232
|
-
!readonly && /* @__PURE__ */ (0,
|
|
25233
|
-
/* @__PURE__ */ (0,
|
|
25579
|
+
!readonly && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: { marginTop: 18 }, children: [
|
|
25580
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
25234
25581
|
Textarea,
|
|
25235
25582
|
{
|
|
25236
25583
|
maxLength: 120,
|
|
@@ -25245,64 +25592,18 @@ var IssueComments = ({
|
|
|
25245
25592
|
style: { minHeight: 45 }
|
|
25246
25593
|
}
|
|
25247
25594
|
),
|
|
25248
|
-
/* @__PURE__ */ (0,
|
|
25595
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ActionRow, { children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Button, { onClick: addComment, children: "comment" }) })
|
|
25249
25596
|
] })
|
|
25250
25597
|
] });
|
|
25251
25598
|
};
|
|
25252
25599
|
|
|
25253
|
-
// source/gui/client/components/Section.tsx
|
|
25254
|
-
var import_jsx_runtime11 = __toESM(require_jsx_runtime(), 1);
|
|
25255
|
-
var Section = ({
|
|
25256
|
-
title,
|
|
25257
|
-
action,
|
|
25258
|
-
children,
|
|
25259
|
-
first = false
|
|
25260
|
-
}) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
25261
|
-
"section",
|
|
25262
|
-
{
|
|
25263
|
-
style: {
|
|
25264
|
-
padding: first ? "0px 0 14px 0" : "14px 0",
|
|
25265
|
-
borderTop: first ? "none" : `1px solid ${GUI_THEME.line}`
|
|
25266
|
-
},
|
|
25267
|
-
children: [
|
|
25268
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
25269
|
-
"div",
|
|
25270
|
-
{
|
|
25271
|
-
style: {
|
|
25272
|
-
display: "flex",
|
|
25273
|
-
justifyContent: "space-between",
|
|
25274
|
-
alignItems: "center",
|
|
25275
|
-
gap: 12
|
|
25276
|
-
},
|
|
25277
|
-
children: [
|
|
25278
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
25279
|
-
"span",
|
|
25280
|
-
{
|
|
25281
|
-
style: {
|
|
25282
|
-
color: GUI_THEME.secondary,
|
|
25283
|
-
fontSize: 10,
|
|
25284
|
-
textTransform: "uppercase",
|
|
25285
|
-
letterSpacing: "0.08em"
|
|
25286
|
-
},
|
|
25287
|
-
children: title
|
|
25288
|
-
}
|
|
25289
|
-
),
|
|
25290
|
-
action
|
|
25291
|
-
]
|
|
25292
|
-
}
|
|
25293
|
-
),
|
|
25294
|
-
children
|
|
25295
|
-
]
|
|
25296
|
-
}
|
|
25297
|
-
);
|
|
25298
|
-
|
|
25299
25600
|
// source/gui/client/components/Tabs.tsx
|
|
25300
|
-
var
|
|
25601
|
+
var import_jsx_runtime14 = __toESM(require_jsx_runtime(), 1);
|
|
25301
25602
|
var Tabs = ({
|
|
25302
25603
|
activeTab,
|
|
25303
25604
|
tabs,
|
|
25304
25605
|
onChange
|
|
25305
|
-
}) => /* @__PURE__ */ (0,
|
|
25606
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
25306
25607
|
"div",
|
|
25307
25608
|
{
|
|
25308
25609
|
style: {
|
|
@@ -25313,7 +25614,7 @@ var Tabs = ({
|
|
|
25313
25614
|
},
|
|
25314
25615
|
children: tabs.map((tab) => {
|
|
25315
25616
|
const active = tab.id === activeTab;
|
|
25316
|
-
return /* @__PURE__ */ (0,
|
|
25617
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
25317
25618
|
"button",
|
|
25318
25619
|
{
|
|
25319
25620
|
type: "button",
|
|
@@ -25331,7 +25632,7 @@ var Tabs = ({
|
|
|
25331
25632
|
},
|
|
25332
25633
|
children: [
|
|
25333
25634
|
tab.label,
|
|
25334
|
-
typeof tab.count === "number" && /* @__PURE__ */ (0,
|
|
25635
|
+
typeof tab.count === "number" && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
25335
25636
|
"span",
|
|
25336
25637
|
{
|
|
25337
25638
|
style: { color: tab.count ? GUI_THEME.secondary : GUI_THEME.dim },
|
|
@@ -25352,7 +25653,7 @@ var Tabs = ({
|
|
|
25352
25653
|
);
|
|
25353
25654
|
|
|
25354
25655
|
// source/gui/client/components/IssueDetails.tsx
|
|
25355
|
-
var
|
|
25656
|
+
var import_jsx_runtime15 = __toESM(require_jsx_runtime(), 1);
|
|
25356
25657
|
var IssueDetails = ({
|
|
25357
25658
|
whoAmI,
|
|
25358
25659
|
comments,
|
|
@@ -25370,18 +25671,22 @@ var IssueDetails = ({
|
|
|
25370
25671
|
onReopenIssue,
|
|
25371
25672
|
onAddComment,
|
|
25372
25673
|
onDeleteComment,
|
|
25674
|
+
attachments,
|
|
25675
|
+
attachmentUploadStatus,
|
|
25676
|
+
onUploadAttachments,
|
|
25677
|
+
onDeleteAttachment,
|
|
25373
25678
|
knownTags: tags,
|
|
25374
25679
|
knownAssignees: assignees
|
|
25375
25680
|
}) => {
|
|
25376
|
-
const [title, setTitle] = (0,
|
|
25377
|
-
const [description, setDescription] = (0,
|
|
25378
|
-
const [tagName, setTagName] = (0,
|
|
25379
|
-
const [assigneeName, setAssigneeName] = (0,
|
|
25380
|
-
const [editingTitle, setEditingTitle] = (0,
|
|
25381
|
-
const [editingDescription, setEditingDescription] = (0,
|
|
25382
|
-
const [addingTag, setAddingTag] = (0,
|
|
25383
|
-
const [addingAssignee, setAddingAssignee] = (0,
|
|
25384
|
-
(0,
|
|
25681
|
+
const [title, setTitle] = (0, import_react7.useState)("");
|
|
25682
|
+
const [description, setDescription] = (0, import_react7.useState)("");
|
|
25683
|
+
const [tagName, setTagName] = (0, import_react7.useState)("");
|
|
25684
|
+
const [assigneeName, setAssigneeName] = (0, import_react7.useState)("");
|
|
25685
|
+
const [editingTitle, setEditingTitle] = (0, import_react7.useState)(false);
|
|
25686
|
+
const [editingDescription, setEditingDescription] = (0, import_react7.useState)(false);
|
|
25687
|
+
const [addingTag, setAddingTag] = (0, import_react7.useState)(false);
|
|
25688
|
+
const [addingAssignee, setAddingAssignee] = (0, import_react7.useState)(false);
|
|
25689
|
+
(0, import_react7.useEffect)(() => {
|
|
25385
25690
|
setTitle(issue?.title ?? "");
|
|
25386
25691
|
setDescription(issue?.description ?? "");
|
|
25387
25692
|
setTagName("");
|
|
@@ -25441,9 +25746,9 @@ var IssueDetails = ({
|
|
|
25441
25746
|
const availableAssignees = assignees.filter(
|
|
25442
25747
|
(assignee) => !issue?.assignees.some((issueAssignee) => issueAssignee.id === assignee.id)
|
|
25443
25748
|
);
|
|
25444
|
-
return /* @__PURE__ */ (0,
|
|
25445
|
-
/* @__PURE__ */ (0,
|
|
25446
|
-
/* @__PURE__ */ (0,
|
|
25749
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Aside, { children: issue ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
|
|
25750
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(FormHeader, { children: [
|
|
25751
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
25447
25752
|
"span",
|
|
25448
25753
|
{
|
|
25449
25754
|
style: {
|
|
@@ -25452,19 +25757,19 @@ var IssueDetails = ({
|
|
|
25452
25757
|
textTransform: "uppercase",
|
|
25453
25758
|
letterSpacing: "0.08em"
|
|
25454
25759
|
},
|
|
25455
|
-
children: issue.ref && /* @__PURE__ */ (0,
|
|
25760
|
+
children: issue.ref && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(CopyRef, { refValue: issue.ref })
|
|
25456
25761
|
}
|
|
25457
25762
|
),
|
|
25458
|
-
/* @__PURE__ */ (0,
|
|
25763
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Button, { variant: "ghost", onClick: onClose, children: "\xD7" })
|
|
25459
25764
|
] }),
|
|
25460
|
-
/* @__PURE__ */ (0,
|
|
25461
|
-
activeTab === "overview" && /* @__PURE__ */ (0,
|
|
25462
|
-
/* @__PURE__ */ (0,
|
|
25765
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Tabs, { tabs, activeTab, onChange: onChangeTab }),
|
|
25766
|
+
activeTab === "overview" && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
|
|
25767
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
25463
25768
|
Section,
|
|
25464
25769
|
{
|
|
25465
25770
|
first: true,
|
|
25466
25771
|
title: "Title",
|
|
25467
|
-
action: !issue.readonly && !editingTitle && /* @__PURE__ */ (0,
|
|
25772
|
+
action: !issue.readonly && !editingTitle && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
25468
25773
|
Button,
|
|
25469
25774
|
{
|
|
25470
25775
|
variant: "ghost",
|
|
@@ -25472,8 +25777,8 @@ var IssueDetails = ({
|
|
|
25472
25777
|
children: "edit"
|
|
25473
25778
|
}
|
|
25474
25779
|
),
|
|
25475
|
-
children: editingTitle ? /* @__PURE__ */ (0,
|
|
25476
|
-
/* @__PURE__ */ (0,
|
|
25780
|
+
children: editingTitle ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
|
|
25781
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
25477
25782
|
Input,
|
|
25478
25783
|
{
|
|
25479
25784
|
value: title,
|
|
@@ -25485,11 +25790,11 @@ var IssueDetails = ({
|
|
|
25485
25790
|
}
|
|
25486
25791
|
}
|
|
25487
25792
|
),
|
|
25488
|
-
/* @__PURE__ */ (0,
|
|
25489
|
-
/* @__PURE__ */ (0,
|
|
25490
|
-
/* @__PURE__ */ (0,
|
|
25793
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(ActionRow, { children: [
|
|
25794
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Button, { onClick: saveTitle, children: "save" }),
|
|
25795
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Button, { variant: "ghost", onClick: cancelTitle, children: "cancel" })
|
|
25491
25796
|
] })
|
|
25492
|
-
] }) : /* @__PURE__ */ (0,
|
|
25797
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
25493
25798
|
"div",
|
|
25494
25799
|
{
|
|
25495
25800
|
style: {
|
|
@@ -25504,11 +25809,11 @@ var IssueDetails = ({
|
|
|
25504
25809
|
)
|
|
25505
25810
|
}
|
|
25506
25811
|
),
|
|
25507
|
-
/* @__PURE__ */ (0,
|
|
25812
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
25508
25813
|
Section,
|
|
25509
25814
|
{
|
|
25510
25815
|
title: "Description",
|
|
25511
|
-
action: !issue.readonly && !editingDescription && /* @__PURE__ */ (0,
|
|
25816
|
+
action: !issue.readonly && !editingDescription && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
25512
25817
|
Button,
|
|
25513
25818
|
{
|
|
25514
25819
|
variant: "ghost",
|
|
@@ -25516,8 +25821,8 @@ var IssueDetails = ({
|
|
|
25516
25821
|
children: "edit"
|
|
25517
25822
|
}
|
|
25518
25823
|
),
|
|
25519
|
-
children: editingDescription ? /* @__PURE__ */ (0,
|
|
25520
|
-
/* @__PURE__ */ (0,
|
|
25824
|
+
children: editingDescription ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
|
|
25825
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
25521
25826
|
Textarea,
|
|
25522
25827
|
{
|
|
25523
25828
|
value: description,
|
|
@@ -25532,31 +25837,34 @@ var IssueDetails = ({
|
|
|
25532
25837
|
}
|
|
25533
25838
|
}
|
|
25534
25839
|
),
|
|
25535
|
-
/* @__PURE__ */ (0,
|
|
25536
|
-
/* @__PURE__ */ (0,
|
|
25537
|
-
/* @__PURE__ */ (0,
|
|
25840
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(ActionRow, { children: [
|
|
25841
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Button, { onClick: saveDescription, children: "save" }),
|
|
25842
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Button, { variant: "ghost", onClick: cancelDescription, children: "cancel" })
|
|
25538
25843
|
] })
|
|
25539
|
-
] }) : issue.description ? /* @__PURE__ */ (0,
|
|
25844
|
+
] }) : issue.description ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
25540
25845
|
"p",
|
|
25541
25846
|
{
|
|
25542
25847
|
style: {
|
|
25543
25848
|
lineHeight: 1.55,
|
|
25544
25849
|
whiteSpace: "pre-wrap",
|
|
25545
25850
|
margin: "8px 0 0",
|
|
25851
|
+
padding: "12px 16px",
|
|
25852
|
+
background: "rgba(0, 0, 0, 0.22)",
|
|
25853
|
+
borderRadius: 8,
|
|
25546
25854
|
color: GUI_THEME.primary
|
|
25547
25855
|
},
|
|
25548
25856
|
children: issue.description
|
|
25549
25857
|
}
|
|
25550
|
-
) : /* @__PURE__ */ (0,
|
|
25858
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Empty, { children: "No description" })
|
|
25551
25859
|
}
|
|
25552
25860
|
),
|
|
25553
|
-
/* @__PURE__ */ (0,
|
|
25861
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
25554
25862
|
Section,
|
|
25555
25863
|
{
|
|
25556
25864
|
title: "Tags",
|
|
25557
|
-
action: !issue.readonly && !addingTag && /* @__PURE__ */ (0,
|
|
25865
|
+
action: !issue.readonly && !addingTag && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Button, { variant: "ghost", onClick: () => setAddingTag(true), children: "+" }) || addingTag && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Button, { variant: "ghost", onClick: () => setAddingTag(false), children: "-" }),
|
|
25558
25866
|
children: [
|
|
25559
|
-
/* @__PURE__ */ (0,
|
|
25867
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ChipRow, { children: issue.tags.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Empty, { children: "No tags" }) : issue.tags.map((tag) => /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
25560
25868
|
Button,
|
|
25561
25869
|
{
|
|
25562
25870
|
variant: "chip",
|
|
@@ -25572,7 +25880,7 @@ var IssueDetails = ({
|
|
|
25572
25880
|
},
|
|
25573
25881
|
tag.id
|
|
25574
25882
|
)) }),
|
|
25575
|
-
addingTag && /* @__PURE__ */ (0,
|
|
25883
|
+
addingTag && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ChipRow, { children: availableTags.map((tag) => /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
25576
25884
|
Button,
|
|
25577
25885
|
{
|
|
25578
25886
|
variant: "chip",
|
|
@@ -25587,8 +25895,8 @@ var IssueDetails = ({
|
|
|
25587
25895
|
},
|
|
25588
25896
|
tag.id
|
|
25589
25897
|
)) }),
|
|
25590
|
-
addingTag && /* @__PURE__ */ (0,
|
|
25591
|
-
/* @__PURE__ */ (0,
|
|
25898
|
+
addingTag && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(AddRow, { children: [
|
|
25899
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
25592
25900
|
Input,
|
|
25593
25901
|
{
|
|
25594
25902
|
value: tagName,
|
|
@@ -25604,23 +25912,23 @@ var IssueDetails = ({
|
|
|
25604
25912
|
}
|
|
25605
25913
|
}
|
|
25606
25914
|
),
|
|
25607
|
-
/* @__PURE__ */ (0,
|
|
25915
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Button, { onClick: addTag, children: "add" })
|
|
25608
25916
|
] })
|
|
25609
25917
|
]
|
|
25610
25918
|
}
|
|
25611
25919
|
),
|
|
25612
|
-
/* @__PURE__ */ (0,
|
|
25920
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
25613
25921
|
Section,
|
|
25614
25922
|
{
|
|
25615
25923
|
title: "Assignees",
|
|
25616
|
-
action: !issue.readonly && !addingAssignee && /* @__PURE__ */ (0,
|
|
25924
|
+
action: !issue.readonly && !addingAssignee && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
25617
25925
|
Button,
|
|
25618
25926
|
{
|
|
25619
25927
|
variant: "ghost",
|
|
25620
25928
|
onClick: () => setAddingAssignee(true),
|
|
25621
25929
|
children: "+"
|
|
25622
25930
|
}
|
|
25623
|
-
) || addingAssignee && /* @__PURE__ */ (0,
|
|
25931
|
+
) || addingAssignee && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
25624
25932
|
Button,
|
|
25625
25933
|
{
|
|
25626
25934
|
variant: "ghost",
|
|
@@ -25629,7 +25937,7 @@ var IssueDetails = ({
|
|
|
25629
25937
|
}
|
|
25630
25938
|
),
|
|
25631
25939
|
children: [
|
|
25632
|
-
/* @__PURE__ */ (0,
|
|
25940
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ChipRow, { children: issue.assignees.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Empty, { children: "No assignees" }) : issue.assignees.map((assignee) => /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
25633
25941
|
Button,
|
|
25634
25942
|
{
|
|
25635
25943
|
variant: "chip",
|
|
@@ -25646,7 +25954,7 @@ var IssueDetails = ({
|
|
|
25646
25954
|
},
|
|
25647
25955
|
assignee.id
|
|
25648
25956
|
)) }),
|
|
25649
|
-
addingAssignee && /* @__PURE__ */ (0,
|
|
25957
|
+
addingAssignee && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ChipRow, { children: availableAssignees.map((assignee) => /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
25650
25958
|
Button,
|
|
25651
25959
|
{
|
|
25652
25960
|
variant: "chip",
|
|
@@ -25661,8 +25969,8 @@ var IssueDetails = ({
|
|
|
25661
25969
|
},
|
|
25662
25970
|
assignee.id
|
|
25663
25971
|
)) }),
|
|
25664
|
-
addingAssignee && /* @__PURE__ */ (0,
|
|
25665
|
-
/* @__PURE__ */ (0,
|
|
25972
|
+
addingAssignee && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(AddRow, { children: [
|
|
25973
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
25666
25974
|
Input,
|
|
25667
25975
|
{
|
|
25668
25976
|
value: assigneeName,
|
|
@@ -25678,21 +25986,32 @@ var IssueDetails = ({
|
|
|
25678
25986
|
}
|
|
25679
25987
|
}
|
|
25680
25988
|
),
|
|
25681
|
-
/* @__PURE__ */ (0,
|
|
25989
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Button, { onClick: addAssignee, children: "add" })
|
|
25682
25990
|
] })
|
|
25683
25991
|
]
|
|
25684
25992
|
}
|
|
25685
25993
|
),
|
|
25686
|
-
/* @__PURE__ */ (0,
|
|
25994
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
25995
|
+
IssueAttachments,
|
|
25996
|
+
{
|
|
25997
|
+
issueId: issue.id,
|
|
25998
|
+
readonly: Boolean(issue.readonly),
|
|
25999
|
+
attachments,
|
|
26000
|
+
uploadStatus: attachmentUploadStatus,
|
|
26001
|
+
onUploadFiles: onUploadAttachments,
|
|
26002
|
+
onDeleteAttachment
|
|
26003
|
+
}
|
|
26004
|
+
),
|
|
26005
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
25687
26006
|
Section,
|
|
25688
26007
|
{
|
|
25689
26008
|
title: "Actions",
|
|
25690
|
-
action: issue.isClosed ? /* @__PURE__ */ (0,
|
|
26009
|
+
action: issue.isClosed ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Button, { onClick: () => onReopenIssue(issue.id), children: "reopen issue" }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Button, { onClick: () => onCloseIssue(issue.id), children: "close issue" }),
|
|
25691
26010
|
children: ""
|
|
25692
26011
|
}
|
|
25693
26012
|
)
|
|
25694
26013
|
] }),
|
|
25695
|
-
activeTab === "comments" && /* @__PURE__ */ (0,
|
|
26014
|
+
activeTab === "comments" && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
25696
26015
|
IssueComments,
|
|
25697
26016
|
{
|
|
25698
26017
|
whoAmI,
|
|
@@ -25703,15 +26022,15 @@ var IssueDetails = ({
|
|
|
25703
26022
|
onDeleteComment
|
|
25704
26023
|
}
|
|
25705
26024
|
)
|
|
25706
|
-
] }) : /* @__PURE__ */ (0,
|
|
26025
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Empty, { children: "Select an issue" }) });
|
|
25707
26026
|
};
|
|
25708
26027
|
|
|
25709
26028
|
// source/gui/client/components/SwimlaneColumn.tsx
|
|
25710
|
-
var
|
|
26029
|
+
var import_react8 = __toESM(require_react(), 1);
|
|
25711
26030
|
|
|
25712
26031
|
// source/gui/client/components/IconComment.tsx
|
|
25713
|
-
var
|
|
25714
|
-
var IconComment = ({ size = 16 }) => /* @__PURE__ */ (0,
|
|
26032
|
+
var import_jsx_runtime16 = __toESM(require_jsx_runtime(), 1);
|
|
26033
|
+
var IconComment = ({ size = 16 }) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
25715
26034
|
"svg",
|
|
25716
26035
|
{
|
|
25717
26036
|
width: size,
|
|
@@ -25719,7 +26038,7 @@ var IconComment = ({ size = 16 }) => /* @__PURE__ */ (0, import_jsx_runtime14.js
|
|
|
25719
26038
|
viewBox: "0 0 16 16",
|
|
25720
26039
|
fill: "none",
|
|
25721
26040
|
"aria-hidden": "true",
|
|
25722
|
-
children: /* @__PURE__ */ (0,
|
|
26041
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
25723
26042
|
"path",
|
|
25724
26043
|
{
|
|
25725
26044
|
d: "M3.9 2.6h5.2a2.4 2.4 0 0 1 2.4 2.4v2.5a2.4 2.4 0 0 1-2.4 2.4H6.6l-1.8 2.1.2-2.1H3.9a2.4 2.4 0 0 1-2.4-2.4V5a2.4 2.4 0 0 1 2.4-2.4Z",
|
|
@@ -25734,7 +26053,7 @@ var IconComment = ({ size = 16 }) => /* @__PURE__ */ (0, import_jsx_runtime14.js
|
|
|
25734
26053
|
);
|
|
25735
26054
|
|
|
25736
26055
|
// source/gui/client/components/TicketCard.tsx
|
|
25737
|
-
var
|
|
26056
|
+
var import_jsx_runtime17 = __toESM(require_jsx_runtime(), 1);
|
|
25738
26057
|
var TicketCard = ({
|
|
25739
26058
|
ticket,
|
|
25740
26059
|
index,
|
|
@@ -25747,7 +26066,7 @@ var TicketCard = ({
|
|
|
25747
26066
|
onDropIssueAt
|
|
25748
26067
|
}) => {
|
|
25749
26068
|
const getVisualTargetIndex = (isAfterMiddle) => index + (isAfterMiddle ? 1 : 0);
|
|
25750
|
-
return /* @__PURE__ */ (0,
|
|
26069
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
25751
26070
|
"div",
|
|
25752
26071
|
{
|
|
25753
26072
|
draggable: !ticket.readonly,
|
|
@@ -25788,7 +26107,7 @@ var TicketCard = ({
|
|
|
25788
26107
|
border: `1px solid ${isSelected ? GUI_THEME.accent : "transparent"}`
|
|
25789
26108
|
},
|
|
25790
26109
|
children: [
|
|
25791
|
-
/* @__PURE__ */ (0,
|
|
26110
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
25792
26111
|
"div",
|
|
25793
26112
|
{
|
|
25794
26113
|
style: {
|
|
@@ -25801,7 +26120,7 @@ var TicketCard = ({
|
|
|
25801
26120
|
children: isSelected ? "\u276F" : index + 1
|
|
25802
26121
|
}
|
|
25803
26122
|
),
|
|
25804
|
-
/* @__PURE__ */ (0,
|
|
26123
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
25805
26124
|
"div",
|
|
25806
26125
|
{
|
|
25807
26126
|
style: {
|
|
@@ -25812,7 +26131,7 @@ var TicketCard = ({
|
|
|
25812
26131
|
gap: 12
|
|
25813
26132
|
},
|
|
25814
26133
|
children: [
|
|
25815
|
-
/* @__PURE__ */ (0,
|
|
26134
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
25816
26135
|
"div",
|
|
25817
26136
|
{
|
|
25818
26137
|
style: {
|
|
@@ -25823,7 +26142,7 @@ var TicketCard = ({
|
|
|
25823
26142
|
flex: 1
|
|
25824
26143
|
},
|
|
25825
26144
|
children: [
|
|
25826
|
-
/* @__PURE__ */ (0,
|
|
26145
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
25827
26146
|
"div",
|
|
25828
26147
|
{
|
|
25829
26148
|
style: {
|
|
@@ -25833,23 +26152,10 @@ var TicketCard = ({
|
|
|
25833
26152
|
fontWeight: 500,
|
|
25834
26153
|
fontSize: 12
|
|
25835
26154
|
},
|
|
25836
|
-
children: ticket.ref && /* @__PURE__ */ (0,
|
|
25837
|
-
"span",
|
|
25838
|
-
{
|
|
25839
|
-
style: {
|
|
25840
|
-
fontFamily: "monospace",
|
|
25841
|
-
marginRight: 6,
|
|
25842
|
-
color: GUI_THEME.dim
|
|
25843
|
-
},
|
|
25844
|
-
children: [
|
|
25845
|
-
"#",
|
|
25846
|
-
ticket.ref
|
|
25847
|
-
]
|
|
25848
|
-
}
|
|
25849
|
-
)
|
|
26155
|
+
children: ticket.ref && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { style: { marginRight: 6 }, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(CopyRef, { refValue: ticket.ref }) })
|
|
25850
26156
|
}
|
|
25851
26157
|
),
|
|
25852
|
-
/* @__PURE__ */ (0,
|
|
26158
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
25853
26159
|
"div",
|
|
25854
26160
|
{
|
|
25855
26161
|
style: {
|
|
@@ -25862,7 +26168,7 @@ var TicketCard = ({
|
|
|
25862
26168
|
children: ticket.title
|
|
25863
26169
|
}
|
|
25864
26170
|
),
|
|
25865
|
-
/* @__PURE__ */ (0,
|
|
26171
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
25866
26172
|
"div",
|
|
25867
26173
|
{
|
|
25868
26174
|
style: {
|
|
@@ -25871,7 +26177,7 @@ var TicketCard = ({
|
|
|
25871
26177
|
gap: 6,
|
|
25872
26178
|
alignItems: "center"
|
|
25873
26179
|
},
|
|
25874
|
-
children: ticket.tags.map((tag) => /* @__PURE__ */ (0,
|
|
26180
|
+
children: ticket.tags.map((tag) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
25875
26181
|
"span",
|
|
25876
26182
|
{
|
|
25877
26183
|
style: {
|
|
@@ -25891,7 +26197,7 @@ var TicketCard = ({
|
|
|
25891
26197
|
]
|
|
25892
26198
|
}
|
|
25893
26199
|
),
|
|
25894
|
-
/* @__PURE__ */ (0,
|
|
26200
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
25895
26201
|
"div",
|
|
25896
26202
|
{
|
|
25897
26203
|
style: {
|
|
@@ -25901,7 +26207,7 @@ var TicketCard = ({
|
|
|
25901
26207
|
flexShrink: 0,
|
|
25902
26208
|
paddingTop: 2
|
|
25903
26209
|
},
|
|
25904
|
-
children: commentCount > 0 && /* @__PURE__ */ (0,
|
|
26210
|
+
children: commentCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
25905
26211
|
"button",
|
|
25906
26212
|
{
|
|
25907
26213
|
type: "button",
|
|
@@ -25939,14 +26245,14 @@ var TicketCard = ({
|
|
|
25939
26245
|
event.currentTarget.style.transform = "translateY(0)";
|
|
25940
26246
|
},
|
|
25941
26247
|
children: [
|
|
25942
|
-
/* @__PURE__ */ (0,
|
|
25943
|
-
/* @__PURE__ */ (0,
|
|
26248
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(IconComment, {}),
|
|
26249
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { children: commentCount })
|
|
25944
26250
|
]
|
|
25945
26251
|
}
|
|
25946
26252
|
)
|
|
25947
26253
|
}
|
|
25948
26254
|
),
|
|
25949
|
-
ticket.assignees.length > 0 && /* @__PURE__ */ (0,
|
|
26255
|
+
ticket.assignees.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
25950
26256
|
"div",
|
|
25951
26257
|
{
|
|
25952
26258
|
style: {
|
|
@@ -25956,7 +26262,7 @@ var TicketCard = ({
|
|
|
25956
26262
|
paddingTop: 2,
|
|
25957
26263
|
marginTop: "-4px"
|
|
25958
26264
|
},
|
|
25959
|
-
children: ticket.assignees.map((assignee, idx) => /* @__PURE__ */ (0,
|
|
26265
|
+
children: ticket.assignees.map((assignee, idx) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(User, { user: assignee, index: idx, isFocus: isSelected }))
|
|
25960
26266
|
}
|
|
25961
26267
|
)
|
|
25962
26268
|
]
|
|
@@ -25968,7 +26274,7 @@ var TicketCard = ({
|
|
|
25968
26274
|
};
|
|
25969
26275
|
|
|
25970
26276
|
// source/gui/client/components/SwimlaneColumn.tsx
|
|
25971
|
-
var
|
|
26277
|
+
var import_jsx_runtime18 = __toESM(require_jsx_runtime(), 1);
|
|
25972
26278
|
var SwimlaneColumn = ({
|
|
25973
26279
|
swimlane,
|
|
25974
26280
|
selected,
|
|
@@ -25984,7 +26290,7 @@ var SwimlaneColumn = ({
|
|
|
25984
26290
|
onDragOverIssue,
|
|
25985
26291
|
onDragLeave
|
|
25986
26292
|
}) => {
|
|
25987
|
-
return /* @__PURE__ */ (0,
|
|
26293
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
25988
26294
|
Panel,
|
|
25989
26295
|
{
|
|
25990
26296
|
as: "section",
|
|
@@ -26024,7 +26330,7 @@ var SwimlaneColumn = ({
|
|
|
26024
26330
|
onDragLeave();
|
|
26025
26331
|
},
|
|
26026
26332
|
children: [
|
|
26027
|
-
/* @__PURE__ */ (0,
|
|
26333
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
26028
26334
|
"header",
|
|
26029
26335
|
{
|
|
26030
26336
|
style: {
|
|
@@ -26035,7 +26341,7 @@ var SwimlaneColumn = ({
|
|
|
26035
26341
|
alignItems: "center"
|
|
26036
26342
|
},
|
|
26037
26343
|
children: [
|
|
26038
|
-
/* @__PURE__ */ (0,
|
|
26344
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
26039
26345
|
"div",
|
|
26040
26346
|
{
|
|
26041
26347
|
style: {
|
|
@@ -26044,30 +26350,30 @@ var SwimlaneColumn = ({
|
|
|
26044
26350
|
gap: 8
|
|
26045
26351
|
},
|
|
26046
26352
|
children: [
|
|
26047
|
-
/* @__PURE__ */ (0,
|
|
26353
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
26048
26354
|
"span",
|
|
26049
26355
|
{
|
|
26050
26356
|
style: { color: selected ? GUI_THEME.accent : GUI_THEME.secondary },
|
|
26051
26357
|
children: selected ? "\u276F" : " "
|
|
26052
26358
|
}
|
|
26053
26359
|
),
|
|
26054
|
-
/* @__PURE__ */ (0,
|
|
26360
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
26055
26361
|
"strong",
|
|
26056
26362
|
{
|
|
26057
26363
|
style: { color: selected ? GUI_THEME.accent : GUI_THEME.primary },
|
|
26058
26364
|
children: swimlane.title
|
|
26059
26365
|
}
|
|
26060
26366
|
),
|
|
26061
|
-
/* @__PURE__ */ (0,
|
|
26367
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("span", { style: { color: GUI_THEME.dim }, children: [
|
|
26062
26368
|
"(",
|
|
26063
26369
|
swimlane.issues.length,
|
|
26064
26370
|
")"
|
|
26065
26371
|
] }),
|
|
26066
|
-
swimlane.readonly && /* @__PURE__ */ (0,
|
|
26372
|
+
swimlane.readonly && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { children: "\u{1F512}" })
|
|
26067
26373
|
]
|
|
26068
26374
|
}
|
|
26069
26375
|
),
|
|
26070
|
-
/* @__PURE__ */ (0,
|
|
26376
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
26071
26377
|
Button,
|
|
26072
26378
|
{
|
|
26073
26379
|
variant: "ghost",
|
|
@@ -26080,9 +26386,9 @@ var SwimlaneColumn = ({
|
|
|
26080
26386
|
]
|
|
26081
26387
|
}
|
|
26082
26388
|
),
|
|
26083
|
-
/* @__PURE__ */ (0,
|
|
26084
|
-
dropIndex === 0 && /* @__PURE__ */ (0,
|
|
26085
|
-
/* @__PURE__ */ (0,
|
|
26389
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: { overflow: "auto", paddingTop: 4, flex: 1 }, children: swimlane.issues.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [
|
|
26390
|
+
dropIndex === 0 && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(DropIndicator, {}),
|
|
26391
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
26086
26392
|
"div",
|
|
26087
26393
|
{
|
|
26088
26394
|
style: {
|
|
@@ -26094,10 +26400,10 @@ var SwimlaneColumn = ({
|
|
|
26094
26400
|
children: "Drop issue here"
|
|
26095
26401
|
}
|
|
26096
26402
|
)
|
|
26097
|
-
] }) : /* @__PURE__ */ (0,
|
|
26098
|
-
swimlane.issues.map((ticket, index) => /* @__PURE__ */ (0,
|
|
26099
|
-
dropIndex === index && /* @__PURE__ */ (0,
|
|
26100
|
-
/* @__PURE__ */ (0,
|
|
26403
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [
|
|
26404
|
+
swimlane.issues.map((ticket, index) => /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_react8.default.Fragment, { children: [
|
|
26405
|
+
dropIndex === index && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(DropIndicator, {}),
|
|
26406
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
26101
26407
|
TicketCard,
|
|
26102
26408
|
{
|
|
26103
26409
|
ticket,
|
|
@@ -26115,7 +26421,7 @@ var SwimlaneColumn = ({
|
|
|
26115
26421
|
}
|
|
26116
26422
|
)
|
|
26117
26423
|
] }, ticket.id)),
|
|
26118
|
-
dropIndex === swimlane.issues.length && /* @__PURE__ */ (0,
|
|
26424
|
+
dropIndex === swimlane.issues.length && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(DropIndicator, {})
|
|
26119
26425
|
] }) })
|
|
26120
26426
|
]
|
|
26121
26427
|
}
|
|
@@ -26253,9 +26559,73 @@ var updateIssueInGuiState = (state, issueId, updateIssue) => ({
|
|
|
26253
26559
|
}))
|
|
26254
26560
|
});
|
|
26255
26561
|
|
|
26562
|
+
// source/gui/client/lib/compress-image.ts
|
|
26563
|
+
var MAX_LONG_EDGE = 1600;
|
|
26564
|
+
var DEFAULT_MAX_KB = 500;
|
|
26565
|
+
var QUALITY_STEPS = [0.8, 0.7, 0.6, 0.5, 0.4];
|
|
26566
|
+
var toBlob = (canvas, type, quality) => new Promise((resolve) => canvas.toBlob(resolve, type, quality));
|
|
26567
|
+
var replaceExtension = (name, ext) => {
|
|
26568
|
+
const base = name.replace(/\.[a-z0-9]+$/i, "");
|
|
26569
|
+
return `${base || "image"}.${ext}`;
|
|
26570
|
+
};
|
|
26571
|
+
var compressImage = async (file, maxKb = DEFAULT_MAX_KB) => {
|
|
26572
|
+
const maxBytes = maxKb * 1024;
|
|
26573
|
+
if (file.type === "image/gif") {
|
|
26574
|
+
if (file.size <= maxBytes) {
|
|
26575
|
+
return { blob: file, name: file.name };
|
|
26576
|
+
}
|
|
26577
|
+
return {
|
|
26578
|
+
error: `GIFs are attached as-is and this one exceeds ${maxKb} KB`
|
|
26579
|
+
};
|
|
26580
|
+
}
|
|
26581
|
+
let bitmap;
|
|
26582
|
+
try {
|
|
26583
|
+
bitmap = await createImageBitmap(file);
|
|
26584
|
+
} catch {
|
|
26585
|
+
return { error: "Not a supported image" };
|
|
26586
|
+
}
|
|
26587
|
+
const scale = Math.min(
|
|
26588
|
+
1,
|
|
26589
|
+
MAX_LONG_EDGE / Math.max(bitmap.width, bitmap.height)
|
|
26590
|
+
);
|
|
26591
|
+
const canvas = document.createElement("canvas");
|
|
26592
|
+
canvas.width = Math.max(1, Math.round(bitmap.width * scale));
|
|
26593
|
+
canvas.height = Math.max(1, Math.round(bitmap.height * scale));
|
|
26594
|
+
const context = canvas.getContext("2d");
|
|
26595
|
+
if (!context) {
|
|
26596
|
+
bitmap.close();
|
|
26597
|
+
return { error: "Unable to process image" };
|
|
26598
|
+
}
|
|
26599
|
+
context.drawImage(bitmap, 0, 0, canvas.width, canvas.height);
|
|
26600
|
+
bitmap.close();
|
|
26601
|
+
for (const quality of QUALITY_STEPS) {
|
|
26602
|
+
const blob = await toBlob(canvas, "image/webp", quality);
|
|
26603
|
+
if (blob && blob.size <= maxBytes) {
|
|
26604
|
+
return { blob, name: replaceExtension(file.name, "webp") };
|
|
26605
|
+
}
|
|
26606
|
+
}
|
|
26607
|
+
return {
|
|
26608
|
+
error: `Unable to compress image under ${maxKb} KB`
|
|
26609
|
+
};
|
|
26610
|
+
};
|
|
26611
|
+
var blobToBase64 = (blob) => new Promise((resolve, reject) => {
|
|
26612
|
+
const reader = new FileReader();
|
|
26613
|
+
reader.onload = () => {
|
|
26614
|
+
const dataUrl = String(reader.result ?? "");
|
|
26615
|
+
const base64 = dataUrl.split(",")[1];
|
|
26616
|
+
if (!base64) {
|
|
26617
|
+
reject(new Error("Unable to encode image"));
|
|
26618
|
+
return;
|
|
26619
|
+
}
|
|
26620
|
+
resolve(base64);
|
|
26621
|
+
};
|
|
26622
|
+
reader.onerror = () => reject(new Error("Unable to read image"));
|
|
26623
|
+
reader.readAsDataURL(blob);
|
|
26624
|
+
});
|
|
26625
|
+
|
|
26256
26626
|
// source/gui/client/App.tsx
|
|
26257
|
-
var
|
|
26258
|
-
var DropIndicator = () => /* @__PURE__ */ (0,
|
|
26627
|
+
var import_jsx_runtime19 = __toESM(require_jsx_runtime(), 1);
|
|
26628
|
+
var DropIndicator = () => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
26259
26629
|
"div",
|
|
26260
26630
|
{
|
|
26261
26631
|
style: {
|
|
@@ -26270,34 +26640,51 @@ var DropIndicator = () => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
|
26270
26640
|
var App = () => {
|
|
26271
26641
|
const { boardId, issueId } = useParams();
|
|
26272
26642
|
const [searchParams, setSearchParams] = useSearchParams();
|
|
26273
|
-
const [connected, setConnected] = (0,
|
|
26274
|
-
const [syncStatus, setSyncStatus] = (0,
|
|
26643
|
+
const [connected, setConnected] = (0, import_react9.useState)(false);
|
|
26644
|
+
const [syncStatus, setSyncStatus] = (0, import_react9.useState)({
|
|
26275
26645
|
status: "synced",
|
|
26276
26646
|
msg: "idle"
|
|
26277
26647
|
});
|
|
26278
|
-
const [state, setState] = (0,
|
|
26279
|
-
const [dragOverSwimlaneId, setDragOverSwimlaneId] = (0,
|
|
26648
|
+
const [state, setState] = (0, import_react9.useState)(null);
|
|
26649
|
+
const [dragOverSwimlaneId, setDragOverSwimlaneId] = (0, import_react9.useState)(
|
|
26280
26650
|
null
|
|
26281
26651
|
);
|
|
26282
|
-
const [dropTarget, setDropTarget] = (0,
|
|
26283
|
-
const [boardMenuOpen, setBoardMenuOpen] = (0,
|
|
26284
|
-
const [createIssueModal, setCreateIssueModal] = (0,
|
|
26285
|
-
const boardMenuRef = (0,
|
|
26286
|
-
const socketRef = (0,
|
|
26652
|
+
const [dropTarget, setDropTarget] = (0, import_react9.useState)(null);
|
|
26653
|
+
const [boardMenuOpen, setBoardMenuOpen] = (0, import_react9.useState)(false);
|
|
26654
|
+
const [createIssueModal, setCreateIssueModal] = (0, import_react9.useState)(null);
|
|
26655
|
+
const boardMenuRef = (0, import_react9.useRef)(null);
|
|
26656
|
+
const socketRef = (0, import_react9.useRef)(null);
|
|
26287
26657
|
const selectedTab = searchParams.get("tab") === "comments" ? "comments" : "overview";
|
|
26288
26658
|
const navigate = useNavigate();
|
|
26289
26659
|
const selectedBoard = (state && boardId ? findBoard(state, boardId) : null) ?? state?.boards[0] ?? null;
|
|
26290
26660
|
const boardSlug = selectedBoard?.ref ?? boardId;
|
|
26291
26661
|
const selectedIssue = state && issueId ? findIssue(state, issueId) : null;
|
|
26662
|
+
(0, import_react9.useEffect)(() => {
|
|
26663
|
+
const onPaste = (event) => {
|
|
26664
|
+
if (!selectedIssue || selectedIssue.readonly) return;
|
|
26665
|
+
const target = event.target;
|
|
26666
|
+
if (target && (target.tagName === "INPUT" || target.tagName === "TEXTAREA" || target.isContentEditable)) {
|
|
26667
|
+
return;
|
|
26668
|
+
}
|
|
26669
|
+
const files = Array.from(event.clipboardData?.items ?? []).filter((item) => item.kind === "file" && item.type.startsWith("image/")).map((item) => item.getAsFile()).filter((file) => Boolean(file));
|
|
26670
|
+
if (files.length === 0) return;
|
|
26671
|
+
event.preventDefault();
|
|
26672
|
+
void uploadIssueAttachments(selectedIssue.id, files);
|
|
26673
|
+
};
|
|
26674
|
+
window.addEventListener("paste", onPaste);
|
|
26675
|
+
return () => window.removeEventListener("paste", onPaste);
|
|
26676
|
+
});
|
|
26292
26677
|
const closeIssueDetails = () => {
|
|
26293
26678
|
if (!boardSlug) return;
|
|
26294
26679
|
void navigate(`/board/${boardSlug}`);
|
|
26295
26680
|
};
|
|
26296
26681
|
const commentsByIssueId = state?.commentsByIssueId ?? {};
|
|
26682
|
+
const attachmentsByIssueId = state?.attachmentsByIssueId ?? {};
|
|
26683
|
+
const [attachmentUploadStatus, setAttachmentUploadStatus] = (0, import_react9.useState)({ state: "idle" });
|
|
26297
26684
|
const requestState = () => {
|
|
26298
26685
|
socketRef.current?.send(JSON.stringify({ type: "state:get" }));
|
|
26299
26686
|
};
|
|
26300
|
-
(0,
|
|
26687
|
+
(0, import_react9.useEffect)(() => {
|
|
26301
26688
|
const socket = new WebSocket(
|
|
26302
26689
|
`ws://${window.location.host}/ws${boardId ? `?boardId=${boardId}` : ""}`
|
|
26303
26690
|
);
|
|
@@ -26341,12 +26728,12 @@ var App = () => {
|
|
|
26341
26728
|
socket.close();
|
|
26342
26729
|
};
|
|
26343
26730
|
}, [boardId, navigate]);
|
|
26344
|
-
(0,
|
|
26731
|
+
(0, import_react9.useEffect)(() => {
|
|
26345
26732
|
if (!boardId && state?.boards[0]) {
|
|
26346
26733
|
void navigate(`/board/${state.boards[0].ref}`, { replace: true });
|
|
26347
26734
|
}
|
|
26348
26735
|
}, [boardId, state, navigate]);
|
|
26349
|
-
(0,
|
|
26736
|
+
(0, import_react9.useEffect)(() => {
|
|
26350
26737
|
const close = (event) => {
|
|
26351
26738
|
if (boardMenuRef.current && !boardMenuRef.current.contains(event.target)) {
|
|
26352
26739
|
setBoardMenuOpen(false);
|
|
@@ -26531,6 +26918,68 @@ var App = () => {
|
|
|
26531
26918
|
});
|
|
26532
26919
|
send("issue:comment:add", { issueId: issueId2, body });
|
|
26533
26920
|
};
|
|
26921
|
+
const uploadIssueAttachments = async (issueId2, files) => {
|
|
26922
|
+
for (const file of files) {
|
|
26923
|
+
setAttachmentUploadStatus({ state: "uploading", name: file.name });
|
|
26924
|
+
const compressed = await compressImage(file, state?.attachmentMaxKb);
|
|
26925
|
+
if ("error" in compressed) {
|
|
26926
|
+
setAttachmentUploadStatus({ state: "error", message: compressed.error });
|
|
26927
|
+
return;
|
|
26928
|
+
}
|
|
26929
|
+
try {
|
|
26930
|
+
const dataBase64 = await blobToBase64(compressed.blob);
|
|
26931
|
+
const response = await fetch("/api/attachments", {
|
|
26932
|
+
method: "POST",
|
|
26933
|
+
headers: { "content-type": "application/json" },
|
|
26934
|
+
body: JSON.stringify({
|
|
26935
|
+
issueId: issueId2,
|
|
26936
|
+
name: compressed.name,
|
|
26937
|
+
dataBase64
|
|
26938
|
+
})
|
|
26939
|
+
});
|
|
26940
|
+
const payload = await response.json();
|
|
26941
|
+
if (!response.ok) {
|
|
26942
|
+
setAttachmentUploadStatus({
|
|
26943
|
+
state: "error",
|
|
26944
|
+
message: payload?.message ?? "Upload failed"
|
|
26945
|
+
});
|
|
26946
|
+
return;
|
|
26947
|
+
}
|
|
26948
|
+
const nextState = getResultValue(payload);
|
|
26949
|
+
if (nextState) setState(nextState);
|
|
26950
|
+
} catch (error) {
|
|
26951
|
+
setAttachmentUploadStatus({
|
|
26952
|
+
state: "error",
|
|
26953
|
+
message: error instanceof Error ? error.message : "Upload failed"
|
|
26954
|
+
});
|
|
26955
|
+
return;
|
|
26956
|
+
}
|
|
26957
|
+
}
|
|
26958
|
+
setAttachmentUploadStatus({ state: "idle" });
|
|
26959
|
+
};
|
|
26960
|
+
const deleteIssueAttachment = async (_issueId, attachmentId) => {
|
|
26961
|
+
try {
|
|
26962
|
+
const response = await fetch(
|
|
26963
|
+
`/api/attachments/${encodeURIComponent(attachmentId)}`,
|
|
26964
|
+
{ method: "DELETE" }
|
|
26965
|
+
);
|
|
26966
|
+
const payload = await response.json();
|
|
26967
|
+
if (!response.ok) {
|
|
26968
|
+
setAttachmentUploadStatus({
|
|
26969
|
+
state: "error",
|
|
26970
|
+
message: payload?.message ?? "Unable to delete attachment"
|
|
26971
|
+
});
|
|
26972
|
+
return;
|
|
26973
|
+
}
|
|
26974
|
+
const nextState = getResultValue(payload);
|
|
26975
|
+
if (nextState) setState(nextState);
|
|
26976
|
+
} catch (error) {
|
|
26977
|
+
setAttachmentUploadStatus({
|
|
26978
|
+
state: "error",
|
|
26979
|
+
message: error instanceof Error ? error.message : "Unable to delete attachment"
|
|
26980
|
+
});
|
|
26981
|
+
}
|
|
26982
|
+
};
|
|
26534
26983
|
const deleteIssueComment = (_issueId, commentId) => {
|
|
26535
26984
|
setState((prev) => {
|
|
26536
26985
|
if (!prev) return prev;
|
|
@@ -26548,7 +26997,7 @@ var App = () => {
|
|
|
26548
26997
|
});
|
|
26549
26998
|
send("issue:comment:delete", { commentId });
|
|
26550
26999
|
};
|
|
26551
|
-
return /* @__PURE__ */ (0,
|
|
27000
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
26552
27001
|
"div",
|
|
26553
27002
|
{
|
|
26554
27003
|
style: {
|
|
@@ -26560,8 +27009,8 @@ var App = () => {
|
|
|
26560
27009
|
flexDirection: "column"
|
|
26561
27010
|
},
|
|
26562
27011
|
children: [
|
|
26563
|
-
/* @__PURE__ */ (0,
|
|
26564
|
-
/* @__PURE__ */ (0,
|
|
27012
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Header, { state, connected, syncStatus }),
|
|
27013
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
26565
27014
|
"div",
|
|
26566
27015
|
{
|
|
26567
27016
|
style: {
|
|
@@ -26570,8 +27019,8 @@ var App = () => {
|
|
|
26570
27019
|
overflow: "hidden"
|
|
26571
27020
|
},
|
|
26572
27021
|
children: [
|
|
26573
|
-
/* @__PURE__ */ (0,
|
|
26574
|
-
/* @__PURE__ */ (0,
|
|
27022
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("main", { style: { padding: "0 30px 30px 30px", overflow: "auto", flex: 1 }, children: [
|
|
27023
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { style: { padding: "20px 10px" }, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
26575
27024
|
Dropdown,
|
|
26576
27025
|
{
|
|
26577
27026
|
label: "Board:",
|
|
@@ -26587,7 +27036,7 @@ var App = () => {
|
|
|
26587
27036
|
onSelect: selectBoard
|
|
26588
27037
|
}
|
|
26589
27038
|
) }),
|
|
26590
|
-
/* @__PURE__ */ (0,
|
|
27039
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { style: { display: "flex", gap: 8 }, children: selectedBoard?.swimlanes.map((swimlane) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
26591
27040
|
SwimlaneColumn,
|
|
26592
27041
|
{
|
|
26593
27042
|
swimlane,
|
|
@@ -26607,7 +27056,7 @@ var App = () => {
|
|
|
26607
27056
|
swimlane.id
|
|
26608
27057
|
)) })
|
|
26609
27058
|
] }),
|
|
26610
|
-
selectedIssue && state?.user && /* @__PURE__ */ (0,
|
|
27059
|
+
selectedIssue && state?.user && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
26611
27060
|
IssueDetails,
|
|
26612
27061
|
{
|
|
26613
27062
|
whoAmI: state.user,
|
|
@@ -26624,6 +27073,10 @@ var App = () => {
|
|
|
26624
27073
|
onRemoveAssignee: removeIssueAssignee,
|
|
26625
27074
|
onAddComment: addIssueComment,
|
|
26626
27075
|
onDeleteComment: deleteIssueComment,
|
|
27076
|
+
attachments: attachmentsByIssueId[selectedIssue.id] ?? [],
|
|
27077
|
+
attachmentUploadStatus,
|
|
27078
|
+
onUploadAttachments: uploadIssueAttachments,
|
|
27079
|
+
onDeleteAttachment: deleteIssueAttachment,
|
|
26627
27080
|
onReopenIssue: reopenIssue,
|
|
26628
27081
|
onCloseIssue: closeIssue,
|
|
26629
27082
|
knownTags: state.tags ?? [],
|
|
@@ -26633,7 +27086,7 @@ var App = () => {
|
|
|
26633
27086
|
]
|
|
26634
27087
|
}
|
|
26635
27088
|
),
|
|
26636
|
-
createIssueModal && /* @__PURE__ */ (0,
|
|
27089
|
+
createIssueModal && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
26637
27090
|
CreateIssueModal,
|
|
26638
27091
|
{
|
|
26639
27092
|
title: createIssueModal.title,
|
|
@@ -26648,14 +27101,14 @@ var App = () => {
|
|
|
26648
27101
|
};
|
|
26649
27102
|
|
|
26650
27103
|
// source/gui/client/main.tsx
|
|
26651
|
-
var
|
|
27104
|
+
var import_jsx_runtime20 = __toESM(require_jsx_runtime(), 1);
|
|
26652
27105
|
(0, import_client.createRoot)(document.getElementById("root")).render(
|
|
26653
|
-
/* @__PURE__ */ (0,
|
|
26654
|
-
/* @__PURE__ */ (0,
|
|
26655
|
-
/* @__PURE__ */ (0,
|
|
26656
|
-
/* @__PURE__ */ (0,
|
|
26657
|
-
/* @__PURE__ */ (0,
|
|
26658
|
-
/* @__PURE__ */ (0,
|
|
27106
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(BrowserRouter, { children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(Routes, { children: [
|
|
27107
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Route, { path: "/", element: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(App, {}) }),
|
|
27108
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Route, { path: "/board/:boardId", element: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(App, {}) }),
|
|
27109
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Route, { path: "/board/:boardId/issue/:issueId", element: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(App, {}) }),
|
|
27110
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Route, { path: "/board/:boardId/:issueId", element: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(App, {}) }),
|
|
27111
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Route, { path: "*", element: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Navigate, { to: "/", replace: true }) })
|
|
26659
27112
|
] }) })
|
|
26660
27113
|
);
|
|
26661
27114
|
/*! Bundled license information:
|