dawlad-paperclip-direction 0.3.2 → 0.3.3
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/manifest.js +1 -1
- package/dist/ui/index.js +105 -24
- package/package.json +1 -1
package/dist/manifest.js
CHANGED
|
@@ -11,7 +11,7 @@ var route = (routeKey, method, path) => ({
|
|
|
11
11
|
var manifest = {
|
|
12
12
|
id: "dawlad.direction",
|
|
13
13
|
apiVersion: 1,
|
|
14
|
-
version: "0.3.
|
|
14
|
+
version: "0.3.3",
|
|
15
15
|
displayName: "Direction",
|
|
16
16
|
description: "Horizon, campaigns, milestones and one queue of decisions: where Dawlad is heading and what's in the way.",
|
|
17
17
|
author: "Aly Solamon",
|
package/dist/ui/index.js
CHANGED
|
@@ -184,6 +184,11 @@ html:has([data-dx-page="decisions"]) ol[data-slot="breadcrumb-list"]:has(a[href$
|
|
|
184
184
|
.dx-props-g { display: grid; grid-template-columns: 96px minmax(0, 1fr); row-gap: 12px; column-gap: 12px; font-size: 13.5px; align-items: center; padding-bottom: 10px; border-bottom: 1px solid var(--dx-line); }
|
|
185
185
|
.dx-props-g .k { color: var(--dx-muted); }
|
|
186
186
|
.dx-props-g .v { min-width: 0; overflow-wrap: anywhere; }
|
|
187
|
+
.dx-pv { border: 1px solid transparent; background: transparent; color: var(--dx-fg); font: inherit; font-size: 13.5px; padding: 3px 6px; margin-left: -7px; border-radius: 6px; max-width: 100%; cursor: pointer; color-scheme: inherit; }
|
|
188
|
+
.dx-pv:hover, .dx-pv:focus { border-color: var(--dx-line); background: var(--dx-soft); outline: none; }
|
|
189
|
+
.dx-pv option { background: var(--dx-card); color: var(--dx-fg); }
|
|
190
|
+
.dx-pv.num { width: 72px; cursor: text; }
|
|
191
|
+
.dx-busy { opacity: .55; pointer-events: none; }
|
|
187
192
|
.dx-plist { display: grid; gap: 2px; }
|
|
188
193
|
.dx-plist .r { display: flex; align-items: center; gap: 10px; width: 100%; text-align: left; border: 0; background: transparent; color: var(--dx-fg); padding: 7px 6px; border-radius: 6px; cursor: pointer; font-size: 13.5px; }
|
|
189
194
|
.dx-plist .r:hover, .dx-plist .r:focus-visible { background: var(--dx-soft2); outline: none; }
|
|
@@ -2353,7 +2358,7 @@ function CampaignPage({ companyId, goalId, tab, m, query }) {
|
|
|
2353
2358
|
tab === "connected" && /* @__PURE__ */ jsx7(ConnectedTab, { d: data, extra }),
|
|
2354
2359
|
tab === "activity" && /* @__PURE__ */ jsx7(ActivityTab, { d: data })
|
|
2355
2360
|
] }),
|
|
2356
|
-
pane ? /* @__PURE__ */ jsx7(CampaignPane, { d: data, extra, onClose: () => setPane(false) }) : /* @__PURE__ */ jsxs7("aside", { className: "dx-pane-rail", children: [
|
|
2361
|
+
pane ? /* @__PURE__ */ jsx7(CampaignPane, { d: data, extra, m, companyId, refresh, onClose: () => setPane(false) }) : /* @__PURE__ */ jsxs7("aside", { className: "dx-pane-rail", children: [
|
|
2357
2362
|
/* @__PURE__ */ jsx7("button", { className: "dx-icon", "aria-label": "Show the properties panel", title: "Properties and everything linked", onClick: () => setPane(true), children: Ico.doc }),
|
|
2358
2363
|
/* @__PURE__ */ jsx7("span", { className: "dx-pane-rail-t", onClick: () => setPane(true), children: "Properties" })
|
|
2359
2364
|
] })
|
|
@@ -2784,7 +2789,7 @@ function useHostConnected(companyId, d) {
|
|
|
2784
2789
|
}, [key]);
|
|
2785
2790
|
return out;
|
|
2786
2791
|
}
|
|
2787
|
-
function CampaignPane({ d, extra, onClose }) {
|
|
2792
|
+
function CampaignPane({ d, extra, m, companyId, refresh, onClose }) {
|
|
2788
2793
|
const go = useGo("direction");
|
|
2789
2794
|
const groups = [
|
|
2790
2795
|
{
|
|
@@ -2894,44 +2899,120 @@ function CampaignPane({ d, extra, onClose }) {
|
|
|
2894
2899
|
/* @__PURE__ */ jsx7("span", { style: { flex: 1 } }),
|
|
2895
2900
|
/* @__PURE__ */ jsx7("button", { className: "dx-icon", "aria-label": "Hide the panel", title: "Hide the panel", onClick: onClose, children: Ico.x })
|
|
2896
2901
|
] }),
|
|
2897
|
-
/* @__PURE__ */ jsx7("div", { className: "dx-pane-body", children: active === "props" ? /* @__PURE__ */ jsx7(CampaignProps, { d, groups, onOpen: pick }) : cur ? /* @__PURE__ */ jsx7(ConnList, { g: cur, onItem: openItem }) : /* @__PURE__ */ jsxs7("div", { className: "dx-pane-empty", children: [
|
|
2902
|
+
/* @__PURE__ */ jsx7("div", { className: "dx-pane-body", children: active === "props" ? /* @__PURE__ */ jsx7(CampaignProps, { d, m, companyId, refresh, groups, onOpen: pick }) : cur ? /* @__PURE__ */ jsx7(ConnList, { g: cur, onItem: openItem }) : /* @__PURE__ */ jsxs7("div", { className: "dx-pane-empty", children: [
|
|
2898
2903
|
/* @__PURE__ */ jsx7("b", { children: "Nothing is open." }),
|
|
2899
2904
|
/* @__PURE__ */ jsx7("span", { className: "dx-muted dx-small", children: "Use + to open the properties or anything linked to this campaign." })
|
|
2900
2905
|
] }) })
|
|
2901
2906
|
] });
|
|
2902
2907
|
}
|
|
2903
|
-
function
|
|
2908
|
+
function useAgents(companyId) {
|
|
2909
|
+
const [list, setList] = useState6([]);
|
|
2910
|
+
useEffect3(() => {
|
|
2911
|
+
let live = true;
|
|
2912
|
+
fetch(`/api/companies/${companyId}/agents`, { credentials: "same-origin" }).then((r) => r.ok ? r.json() : []).then((a) => {
|
|
2913
|
+
if (live) setList((Array.isArray(a) ? a : []).filter((x) => x.status !== "terminated").map((x) => ({ id: x.id, name: x.name, title: x.title ?? null })));
|
|
2914
|
+
}).catch(() => {
|
|
2915
|
+
});
|
|
2916
|
+
return () => {
|
|
2917
|
+
live = false;
|
|
2918
|
+
};
|
|
2919
|
+
}, [companyId]);
|
|
2920
|
+
return list;
|
|
2921
|
+
}
|
|
2922
|
+
function CampaignProps({ d, m, companyId, refresh, groups, onOpen }) {
|
|
2904
2923
|
const c = d.campaign;
|
|
2905
|
-
const
|
|
2924
|
+
const set = usePluginAction("set-campaign");
|
|
2925
|
+
const agents = useAgents(companyId);
|
|
2926
|
+
const [busy, setBusy] = useState6(null);
|
|
2927
|
+
const [err, setErr] = useState6(null);
|
|
2928
|
+
const [mins, setMins] = useState6(c.alyMinutes != null ? String(c.alyMinutes) : "");
|
|
2929
|
+
useEffect3(() => setMins(c.alyMinutes != null ? String(c.alyMinutes) : ""), [c.alyMinutes]);
|
|
2930
|
+
const save = async (field, patch) => {
|
|
2931
|
+
setBusy(field);
|
|
2932
|
+
setErr(null);
|
|
2933
|
+
try {
|
|
2934
|
+
await set({ companyId, goalId: c.goalId, ...patch });
|
|
2935
|
+
refresh();
|
|
2936
|
+
} catch (e) {
|
|
2937
|
+
setErr(e.message);
|
|
2938
|
+
} finally {
|
|
2939
|
+
setBusy(null);
|
|
2940
|
+
}
|
|
2941
|
+
};
|
|
2942
|
+
const row = (k, v, field) => /* @__PURE__ */ jsxs7(Fragment4, { children: [
|
|
2906
2943
|
/* @__PURE__ */ jsx7("span", { className: "k", children: k }),
|
|
2907
|
-
/* @__PURE__ */ jsx7("span", { className:
|
|
2944
|
+
/* @__PURE__ */ jsx7("span", { className: `v${busy === field ? " dx-busy" : ""}`, children: v })
|
|
2908
2945
|
] });
|
|
2946
|
+
const lead = c.owner.kind === "agent" ? c.owner.id ?? "" : "";
|
|
2909
2947
|
return /* @__PURE__ */ jsxs7("div", { className: "dx-props", children: [
|
|
2910
2948
|
/* @__PURE__ */ jsx7("div", { className: "dx-props-h", children: "Direction" }),
|
|
2911
2949
|
/* @__PURE__ */ jsxs7("div", { className: "dx-props-g", children: [
|
|
2912
|
-
row("Lead", /* @__PURE__ */ jsxs7("
|
|
2913
|
-
/* @__PURE__ */ jsx7(
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
|
|
2922
|
-
|
|
2923
|
-
|
|
2924
|
-
/* @__PURE__ */ jsx7("
|
|
2925
|
-
|
|
2950
|
+
row("Lead", /* @__PURE__ */ jsxs7("select", { className: "dx-pv", "aria-label": "Lead", value: lead, onChange: (e) => save("lead", { leadAgentId: e.target.value || null }), children: [
|
|
2951
|
+
/* @__PURE__ */ jsx7("option", { value: "", children: "No lead" }),
|
|
2952
|
+
agents.map((a) => /* @__PURE__ */ jsxs7("option", { value: a.id, children: [
|
|
2953
|
+
a.name,
|
|
2954
|
+
a.title ? ` \xB7 ${a.title}` : ""
|
|
2955
|
+
] }, a.id))
|
|
2956
|
+
] }), "lead"),
|
|
2957
|
+
row("Team", /* @__PURE__ */ jsxs7("select", { className: "dx-pv", "aria-label": "Team", value: c.team?.goalId ?? "", onChange: (e) => e.target.value && save("team", { teamGoalId: e.target.value }), children: [
|
|
2958
|
+
!c.team && /* @__PURE__ */ jsx7("option", { value: "", children: "No team" }),
|
|
2959
|
+
m.teams.map((t) => /* @__PURE__ */ jsx7("option", { value: t.goalId, children: t.name }, t.goalId))
|
|
2960
|
+
] }), "team"),
|
|
2961
|
+
row("Serves", /* @__PURE__ */ jsxs7("select", { className: "dx-pv", "aria-label": "Serves", value: c.partId ?? "", onChange: (e) => save("part", { partId: e.target.value || null }), children: [
|
|
2962
|
+
/* @__PURE__ */ jsx7("option", { value: "", children: "Not placed" }),
|
|
2963
|
+
m.horizon.parts.map((p) => /* @__PURE__ */ jsx7("option", { value: p.id, children: p.name }, p.id))
|
|
2964
|
+
] }), "part"),
|
|
2965
|
+
row("Order", /* @__PURE__ */ jsxs7("span", { className: "dx-row", style: { gap: 4 }, children: [
|
|
2966
|
+
/* @__PURE__ */ jsxs7("select", { className: "dx-pv", "aria-label": "Order", value: c.rankLabel ?? "", onChange: (e) => save("rank", { rankLabel: e.target.value || null }), children: [
|
|
2967
|
+
/* @__PURE__ */ jsx7("option", { value: "", children: "Not ranked" }),
|
|
2968
|
+
/* @__PURE__ */ jsx7("option", { value: "Now", children: "Now" }),
|
|
2969
|
+
/* @__PURE__ */ jsx7("option", { value: "Next", children: "Next" }),
|
|
2970
|
+
/* @__PURE__ */ jsx7("option", { value: "Later", children: "Later" })
|
|
2971
|
+
] }),
|
|
2972
|
+
/* @__PURE__ */ jsxs7("select", { className: "dx-pv", "aria-label": "Focus or parked", value: c.state, onChange: (e) => save("rank", { state: e.target.value }), children: [
|
|
2973
|
+
/* @__PURE__ */ jsx7("option", { value: "focus", children: "focus" }),
|
|
2974
|
+
/* @__PURE__ */ jsx7("option", { value: "parked", children: "parked" })
|
|
2975
|
+
] })
|
|
2976
|
+
] }), "rank"),
|
|
2926
2977
|
row("Health", /* @__PURE__ */ jsx7(HealthPill, { h: c.health }))
|
|
2927
2978
|
] }),
|
|
2928
2979
|
/* @__PURE__ */ jsx7("div", { className: "dx-props-h", children: "Dates" }),
|
|
2929
2980
|
/* @__PURE__ */ jsxs7("div", { className: "dx-props-g", children: [
|
|
2930
|
-
row("Start",
|
|
2931
|
-
row("Finish",
|
|
2981
|
+
row("Start", /* @__PURE__ */ jsx7("input", { className: "dx-pv", type: "date", "aria-label": "Start", value: c.plannedStart ?? "", onChange: (e) => save("start", { plannedStart: e.target.value || null }) }), "start"),
|
|
2982
|
+
row("Finish", /* @__PURE__ */ jsxs7("span", { className: "dx-row", style: { gap: 6, flexWrap: "wrap" }, children: [
|
|
2983
|
+
/* @__PURE__ */ jsx7("input", { className: "dx-pv", type: "date", "aria-label": "Planned finish", value: c.plannedFinish ?? "", onChange: (e) => save("finish", { plannedFinish: e.target.value || null }) }),
|
|
2984
|
+
c.forecastFinish && c.forecastFinish !== c.plannedFinish && /* @__PURE__ */ jsxs7("span", { className: "dx-muted dx-xs", children: [
|
|
2985
|
+
"forecast ",
|
|
2986
|
+
fmt(c.forecastFinish)
|
|
2987
|
+
] })
|
|
2988
|
+
] }), "finish"),
|
|
2932
2989
|
row("Plan was", /* @__PURE__ */ jsx7("span", { className: "dx-muted", children: fmt(c.planFinish ?? c.plannedFinish) })),
|
|
2933
|
-
row("Review",
|
|
2934
|
-
row("Your time",
|
|
2990
|
+
row("Review", /* @__PURE__ */ jsx7("input", { className: "dx-pv", type: "date", "aria-label": "Review date", value: c.reviewDate ?? "", onChange: (e) => save("review", { reviewDate: e.target.value || null }) }), "review"),
|
|
2991
|
+
row("Your time", /* @__PURE__ */ jsxs7("span", { className: "dx-row", style: { gap: 6 }, children: [
|
|
2992
|
+
/* @__PURE__ */ jsx7(
|
|
2993
|
+
"input",
|
|
2994
|
+
{
|
|
2995
|
+
className: "dx-pv num",
|
|
2996
|
+
type: "number",
|
|
2997
|
+
min: 0,
|
|
2998
|
+
step: 5,
|
|
2999
|
+
"aria-label": "Your minutes a week",
|
|
3000
|
+
placeholder: "not set",
|
|
3001
|
+
value: mins,
|
|
3002
|
+
onChange: (e) => setMins(e.target.value),
|
|
3003
|
+
onBlur: () => {
|
|
3004
|
+
const v = mins.trim() === "" ? null : Number(mins);
|
|
3005
|
+
if (v !== c.alyMinutes) save("mins", { alyMinutes: v });
|
|
3006
|
+
},
|
|
3007
|
+
onKeyDown: (e) => e.key === "Enter" && e.target.blur()
|
|
3008
|
+
}
|
|
3009
|
+
),
|
|
3010
|
+
/* @__PURE__ */ jsx7("span", { className: "dx-muted dx-small", children: "min a week" })
|
|
3011
|
+
] }), "mins")
|
|
3012
|
+
] }),
|
|
3013
|
+
err && /* @__PURE__ */ jsxs7("div", { className: "dx-err dx-small", children: [
|
|
3014
|
+
"Couldn't save: ",
|
|
3015
|
+
err
|
|
2935
3016
|
] }),
|
|
2936
3017
|
/* @__PURE__ */ jsx7("div", { className: "dx-props-h", children: "Linked" }),
|
|
2937
3018
|
/* @__PURE__ */ jsx7("div", { className: "dx-plist", children: groups.map((g) => /* @__PURE__ */ jsxs7("button", { className: "r", onClick: () => onOpen(g.kind), children: [
|
package/package.json
CHANGED