medusa-plugin-order-notes 0.1.2
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/medusa-config.js +23 -0
- package/.medusa/server/src/admin/index.js +166 -0
- package/.medusa/server/src/admin/index.mjs +165 -0
- package/.medusa/server/src/api/admin/order-notes/[id]/route.js +12 -0
- package/.medusa/server/src/api/admin/order-notes/route.js +33 -0
- package/.medusa/server/src/api/middlewares.js +23 -0
- package/.medusa/server/src/api/validators.js +18 -0
- package/.medusa/server/src/links/order-note-order.js +15 -0
- package/.medusa/server/src/links/order-order-note.js +18 -0
- package/.medusa/server/src/modules/order-note/index.js +10 -0
- package/.medusa/server/src/modules/order-note/migrations/Migration20260409171812.js +15 -0
- package/.medusa/server/src/modules/order-note/models/order-note.js +13 -0
- package/.medusa/server/src/modules/order-note/service.js +23 -0
- package/LICENSE +21 -0
- package/README.md +64 -0
- package/package.json +78 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
4
|
+
(0, utils_1.loadEnv)(process.env.NODE_ENV || 'development', process.cwd());
|
|
5
|
+
module.exports = (0, utils_1.defineConfig)({
|
|
6
|
+
projectConfig: {
|
|
7
|
+
redisUrl: process.env.REDIS_URL,
|
|
8
|
+
databaseUrl: process.env.DATABASE_URL,
|
|
9
|
+
http: {
|
|
10
|
+
storeCors: process.env.STORE_CORS || 'http://localhost:5173',
|
|
11
|
+
adminCors: process.env.ADMIN_CORS || 'http://localhost:5173,http://localhost:9000',
|
|
12
|
+
authCors: process.env.AUTH_CORS || 'http://localhost:5173,http://localhost:9000',
|
|
13
|
+
jwtSecret: process.env.JWT_SECRET || 'supersecret',
|
|
14
|
+
cookieSecret: process.env.COOKIE_SECRET || 'supersecret'
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
modules: [
|
|
18
|
+
{
|
|
19
|
+
resolve: './src/modules/order-note'
|
|
20
|
+
}
|
|
21
|
+
]
|
|
22
|
+
});
|
|
23
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVkdXNhLWNvbmZpZy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL21lZHVzYS1jb25maWcudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSxxREFBaUU7QUFFakUsSUFBQSxlQUFPLEVBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxRQUFRLElBQUksYUFBYSxFQUFFLE9BQU8sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFBO0FBRTdELE1BQU0sQ0FBQyxPQUFPLEdBQUcsSUFBQSxvQkFBWSxFQUFDO0lBQzdCLGFBQWEsRUFBRTtRQUNkLFFBQVEsRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLFNBQVM7UUFDL0IsV0FBVyxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsWUFBWTtRQUNyQyxJQUFJLEVBQUU7WUFDTCxTQUFTLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxVQUFVLElBQUksdUJBQXVCO1lBQzVELFNBQVMsRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVUsSUFBSSw2Q0FBNkM7WUFDbEYsUUFBUSxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsU0FBUyxJQUFJLDZDQUE2QztZQUNoRixTQUFTLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxVQUFVLElBQUksYUFBYTtZQUNsRCxZQUFZLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxhQUFhLElBQUksYUFBYTtTQUN4RDtLQUNEO0lBQ0QsT0FBTyxFQUFFO1FBQ1I7WUFDQyxPQUFPLEVBQUUsMEJBQTBCO1NBQ25DO0tBQ0Q7Q0FDRCxDQUFDLENBQUEifQ==
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const jsxRuntime = require("react/jsx-runtime");
|
|
3
|
+
const react = require("react");
|
|
4
|
+
const adminSdk = require("@medusajs/admin-sdk");
|
|
5
|
+
const ui = require("@medusajs/ui");
|
|
6
|
+
const icons = require("@medusajs/icons");
|
|
7
|
+
const reactQuery = require("@tanstack/react-query");
|
|
8
|
+
const Medusa = require("@medusajs/js-sdk");
|
|
9
|
+
const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
|
|
10
|
+
const Medusa__default = /* @__PURE__ */ _interopDefault(Medusa);
|
|
11
|
+
const sdk = new Medusa__default.default({
|
|
12
|
+
baseUrl: "/",
|
|
13
|
+
debug: false,
|
|
14
|
+
auth: {
|
|
15
|
+
type: "session"
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
const useOrderNotes = (orderId) => {
|
|
19
|
+
return reactQuery.useQuery({
|
|
20
|
+
queryFn: () => sdk.client.fetch("/admin/order-notes", {
|
|
21
|
+
query: { order_id: orderId, limit: 50 }
|
|
22
|
+
}),
|
|
23
|
+
queryKey: ["order-notes", orderId],
|
|
24
|
+
enabled: !!orderId
|
|
25
|
+
});
|
|
26
|
+
};
|
|
27
|
+
const useCreateOrderNote = (orderId) => {
|
|
28
|
+
const queryClient = reactQuery.useQueryClient();
|
|
29
|
+
return reactQuery.useMutation({
|
|
30
|
+
mutationFn: (body) => sdk.client.fetch("/admin/order-notes", { method: "POST", body }),
|
|
31
|
+
onSuccess: () => {
|
|
32
|
+
queryClient.invalidateQueries({ queryKey: ["order-notes", orderId] });
|
|
33
|
+
queryClient.invalidateQueries({ queryKey: ["orders"] });
|
|
34
|
+
queryClient.invalidateQueries({ queryKey: ["order", orderId] });
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
};
|
|
38
|
+
const useDeleteOrderNote = (orderId) => {
|
|
39
|
+
const queryClient = reactQuery.useQueryClient();
|
|
40
|
+
return reactQuery.useMutation({
|
|
41
|
+
mutationFn: (id) => sdk.client.fetch(`/admin/order-notes/${id}`, { method: "DELETE" }),
|
|
42
|
+
onSuccess: () => {
|
|
43
|
+
queryClient.invalidateQueries({ queryKey: ["order-notes", orderId] });
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
};
|
|
47
|
+
adminSdk.defineWidgetConfig({
|
|
48
|
+
zone: "order.details.after"
|
|
49
|
+
});
|
|
50
|
+
const OrderNotesWidget = ({ data: order }) => {
|
|
51
|
+
const [showForm, setShowForm] = react.useState(false);
|
|
52
|
+
const [noteText, setNoteText] = react.useState("");
|
|
53
|
+
const [sendToCustomer, setSendToCustomer] = react.useState(false);
|
|
54
|
+
const { data: notesData, isLoading } = useOrderNotes(order.id);
|
|
55
|
+
const createMutation = useCreateOrderNote(order.id);
|
|
56
|
+
const deleteMutation = useDeleteOrderNote(order.id);
|
|
57
|
+
const notes = (notesData == null ? void 0 : notesData.order_notes) ?? [];
|
|
58
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "divide-y p-0", children: [
|
|
59
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between px-6 py-4", children: [
|
|
60
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", children: "Order Notes" }),
|
|
61
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
62
|
+
ui.Button,
|
|
63
|
+
{
|
|
64
|
+
size: "small",
|
|
65
|
+
variant: "secondary",
|
|
66
|
+
onClick: () => {
|
|
67
|
+
setShowForm((prev) => !prev);
|
|
68
|
+
setNoteText("");
|
|
69
|
+
setSendToCustomer(false);
|
|
70
|
+
},
|
|
71
|
+
children: showForm ? "Cancel" : "Add Note"
|
|
72
|
+
}
|
|
73
|
+
)
|
|
74
|
+
] }),
|
|
75
|
+
showForm && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 px-6 py-4", children: [
|
|
76
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
77
|
+
ui.Textarea,
|
|
78
|
+
{
|
|
79
|
+
placeholder: "Write a note...",
|
|
80
|
+
value: noteText,
|
|
81
|
+
onChange: (e) => setNoteText(e.target.value),
|
|
82
|
+
rows: 3
|
|
83
|
+
}
|
|
84
|
+
),
|
|
85
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
86
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
87
|
+
ui.Checkbox,
|
|
88
|
+
{
|
|
89
|
+
id: "send-to-customer",
|
|
90
|
+
checked: sendToCustomer,
|
|
91
|
+
onCheckedChange: (checked) => setSendToCustomer(checked === true)
|
|
92
|
+
}
|
|
93
|
+
),
|
|
94
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Label, { htmlFor: "send-to-customer", className: "cursor-pointer", children: "Send to customer" })
|
|
95
|
+
] }),
|
|
96
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-end", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
97
|
+
ui.Button,
|
|
98
|
+
{
|
|
99
|
+
size: "small",
|
|
100
|
+
disabled: !noteText.trim() || createMutation.isPending,
|
|
101
|
+
isLoading: createMutation.isPending,
|
|
102
|
+
onClick: () => createMutation.mutate(
|
|
103
|
+
{ order_id: order.id, note: noteText, sent: sendToCustomer },
|
|
104
|
+
{
|
|
105
|
+
onSuccess: () => {
|
|
106
|
+
setNoteText("");
|
|
107
|
+
setSendToCustomer(false);
|
|
108
|
+
setShowForm(false);
|
|
109
|
+
ui.toast.success(sendToCustomer ? "Note added and sent to customer" : "Note added");
|
|
110
|
+
},
|
|
111
|
+
onError: () => ui.toast.error("Failed to add note")
|
|
112
|
+
}
|
|
113
|
+
),
|
|
114
|
+
children: "Save"
|
|
115
|
+
}
|
|
116
|
+
) })
|
|
117
|
+
] }),
|
|
118
|
+
isLoading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-6 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Loading..." }) }) : notes.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-6 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "No notes for this order." }) }) : notes.map((note) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-4 px-6 py-4", children: [
|
|
119
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1 flex-1 min-w-0", children: [
|
|
120
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "whitespace-pre-wrap break-words", children: note.note }),
|
|
121
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 mt-1", children: [
|
|
122
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-fg-muted", children: new Date(note.created_at).toLocaleString() }),
|
|
123
|
+
note.sent && /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { size: "xsmall", color: "blue", children: "Sent to customer" })
|
|
124
|
+
] })
|
|
125
|
+
] }),
|
|
126
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
127
|
+
"button",
|
|
128
|
+
{
|
|
129
|
+
className: "text-ui-fg-muted hover:text-ui-fg-base flex-shrink-0 mt-0.5",
|
|
130
|
+
onClick: () => deleteMutation.mutate(note.id, {
|
|
131
|
+
onSuccess: () => ui.toast.success("Note deleted"),
|
|
132
|
+
onError: () => ui.toast.error("Failed to delete note")
|
|
133
|
+
}),
|
|
134
|
+
"aria-label": "Delete note",
|
|
135
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(icons.Trash, { className: "h-4 w-4" })
|
|
136
|
+
}
|
|
137
|
+
)
|
|
138
|
+
] }, note.id))
|
|
139
|
+
] });
|
|
140
|
+
};
|
|
141
|
+
const widgetModule = { widgets: [
|
|
142
|
+
{
|
|
143
|
+
Component: OrderNotesWidget,
|
|
144
|
+
zone: ["order.details.after"]
|
|
145
|
+
}
|
|
146
|
+
] };
|
|
147
|
+
const routeModule = {
|
|
148
|
+
routes: []
|
|
149
|
+
};
|
|
150
|
+
const menuItemModule = {
|
|
151
|
+
menuItems: []
|
|
152
|
+
};
|
|
153
|
+
const formModule = { customFields: {} };
|
|
154
|
+
const displayModule = {
|
|
155
|
+
displays: {}
|
|
156
|
+
};
|
|
157
|
+
const i18nModule = { resources: {} };
|
|
158
|
+
const plugin = {
|
|
159
|
+
widgetModule,
|
|
160
|
+
routeModule,
|
|
161
|
+
menuItemModule,
|
|
162
|
+
formModule,
|
|
163
|
+
displayModule,
|
|
164
|
+
i18nModule
|
|
165
|
+
};
|
|
166
|
+
module.exports = plugin;
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { jsxs, jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import { defineWidgetConfig } from "@medusajs/admin-sdk";
|
|
4
|
+
import { Container, Heading, Button, Textarea, Checkbox, Label, toast, Text, Badge } from "@medusajs/ui";
|
|
5
|
+
import { Trash } from "@medusajs/icons";
|
|
6
|
+
import { useQuery, useQueryClient, useMutation } from "@tanstack/react-query";
|
|
7
|
+
import Medusa from "@medusajs/js-sdk";
|
|
8
|
+
const sdk = new Medusa({
|
|
9
|
+
baseUrl: "/",
|
|
10
|
+
debug: false,
|
|
11
|
+
auth: {
|
|
12
|
+
type: "session"
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
const useOrderNotes = (orderId) => {
|
|
16
|
+
return useQuery({
|
|
17
|
+
queryFn: () => sdk.client.fetch("/admin/order-notes", {
|
|
18
|
+
query: { order_id: orderId, limit: 50 }
|
|
19
|
+
}),
|
|
20
|
+
queryKey: ["order-notes", orderId],
|
|
21
|
+
enabled: !!orderId
|
|
22
|
+
});
|
|
23
|
+
};
|
|
24
|
+
const useCreateOrderNote = (orderId) => {
|
|
25
|
+
const queryClient = useQueryClient();
|
|
26
|
+
return useMutation({
|
|
27
|
+
mutationFn: (body) => sdk.client.fetch("/admin/order-notes", { method: "POST", body }),
|
|
28
|
+
onSuccess: () => {
|
|
29
|
+
queryClient.invalidateQueries({ queryKey: ["order-notes", orderId] });
|
|
30
|
+
queryClient.invalidateQueries({ queryKey: ["orders"] });
|
|
31
|
+
queryClient.invalidateQueries({ queryKey: ["order", orderId] });
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
};
|
|
35
|
+
const useDeleteOrderNote = (orderId) => {
|
|
36
|
+
const queryClient = useQueryClient();
|
|
37
|
+
return useMutation({
|
|
38
|
+
mutationFn: (id) => sdk.client.fetch(`/admin/order-notes/${id}`, { method: "DELETE" }),
|
|
39
|
+
onSuccess: () => {
|
|
40
|
+
queryClient.invalidateQueries({ queryKey: ["order-notes", orderId] });
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
defineWidgetConfig({
|
|
45
|
+
zone: "order.details.after"
|
|
46
|
+
});
|
|
47
|
+
const OrderNotesWidget = ({ data: order }) => {
|
|
48
|
+
const [showForm, setShowForm] = useState(false);
|
|
49
|
+
const [noteText, setNoteText] = useState("");
|
|
50
|
+
const [sendToCustomer, setSendToCustomer] = useState(false);
|
|
51
|
+
const { data: notesData, isLoading } = useOrderNotes(order.id);
|
|
52
|
+
const createMutation = useCreateOrderNote(order.id);
|
|
53
|
+
const deleteMutation = useDeleteOrderNote(order.id);
|
|
54
|
+
const notes = (notesData == null ? void 0 : notesData.order_notes) ?? [];
|
|
55
|
+
return /* @__PURE__ */ jsxs(Container, { className: "divide-y p-0", children: [
|
|
56
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between px-6 py-4", children: [
|
|
57
|
+
/* @__PURE__ */ jsx(Heading, { level: "h2", children: "Order Notes" }),
|
|
58
|
+
/* @__PURE__ */ jsx(
|
|
59
|
+
Button,
|
|
60
|
+
{
|
|
61
|
+
size: "small",
|
|
62
|
+
variant: "secondary",
|
|
63
|
+
onClick: () => {
|
|
64
|
+
setShowForm((prev) => !prev);
|
|
65
|
+
setNoteText("");
|
|
66
|
+
setSendToCustomer(false);
|
|
67
|
+
},
|
|
68
|
+
children: showForm ? "Cancel" : "Add Note"
|
|
69
|
+
}
|
|
70
|
+
)
|
|
71
|
+
] }),
|
|
72
|
+
showForm && /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3 px-6 py-4", children: [
|
|
73
|
+
/* @__PURE__ */ jsx(
|
|
74
|
+
Textarea,
|
|
75
|
+
{
|
|
76
|
+
placeholder: "Write a note...",
|
|
77
|
+
value: noteText,
|
|
78
|
+
onChange: (e) => setNoteText(e.target.value),
|
|
79
|
+
rows: 3
|
|
80
|
+
}
|
|
81
|
+
),
|
|
82
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
83
|
+
/* @__PURE__ */ jsx(
|
|
84
|
+
Checkbox,
|
|
85
|
+
{
|
|
86
|
+
id: "send-to-customer",
|
|
87
|
+
checked: sendToCustomer,
|
|
88
|
+
onCheckedChange: (checked) => setSendToCustomer(checked === true)
|
|
89
|
+
}
|
|
90
|
+
),
|
|
91
|
+
/* @__PURE__ */ jsx(Label, { htmlFor: "send-to-customer", className: "cursor-pointer", children: "Send to customer" })
|
|
92
|
+
] }),
|
|
93
|
+
/* @__PURE__ */ jsx("div", { className: "flex justify-end", children: /* @__PURE__ */ jsx(
|
|
94
|
+
Button,
|
|
95
|
+
{
|
|
96
|
+
size: "small",
|
|
97
|
+
disabled: !noteText.trim() || createMutation.isPending,
|
|
98
|
+
isLoading: createMutation.isPending,
|
|
99
|
+
onClick: () => createMutation.mutate(
|
|
100
|
+
{ order_id: order.id, note: noteText, sent: sendToCustomer },
|
|
101
|
+
{
|
|
102
|
+
onSuccess: () => {
|
|
103
|
+
setNoteText("");
|
|
104
|
+
setSendToCustomer(false);
|
|
105
|
+
setShowForm(false);
|
|
106
|
+
toast.success(sendToCustomer ? "Note added and sent to customer" : "Note added");
|
|
107
|
+
},
|
|
108
|
+
onError: () => toast.error("Failed to add note")
|
|
109
|
+
}
|
|
110
|
+
),
|
|
111
|
+
children: "Save"
|
|
112
|
+
}
|
|
113
|
+
) })
|
|
114
|
+
] }),
|
|
115
|
+
isLoading ? /* @__PURE__ */ jsx("div", { className: "px-6 py-4", children: /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Loading..." }) }) : notes.length === 0 ? /* @__PURE__ */ jsx("div", { className: "px-6 py-4", children: /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "No notes for this order." }) }) : notes.map((note) => /* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-4 px-6 py-4", children: [
|
|
116
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1 flex-1 min-w-0", children: [
|
|
117
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "whitespace-pre-wrap break-words", children: note.note }),
|
|
118
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mt-1", children: [
|
|
119
|
+
/* @__PURE__ */ jsx(Text, { size: "xsmall", className: "text-ui-fg-muted", children: new Date(note.created_at).toLocaleString() }),
|
|
120
|
+
note.sent && /* @__PURE__ */ jsx(Badge, { size: "xsmall", color: "blue", children: "Sent to customer" })
|
|
121
|
+
] })
|
|
122
|
+
] }),
|
|
123
|
+
/* @__PURE__ */ jsx(
|
|
124
|
+
"button",
|
|
125
|
+
{
|
|
126
|
+
className: "text-ui-fg-muted hover:text-ui-fg-base flex-shrink-0 mt-0.5",
|
|
127
|
+
onClick: () => deleteMutation.mutate(note.id, {
|
|
128
|
+
onSuccess: () => toast.success("Note deleted"),
|
|
129
|
+
onError: () => toast.error("Failed to delete note")
|
|
130
|
+
}),
|
|
131
|
+
"aria-label": "Delete note",
|
|
132
|
+
children: /* @__PURE__ */ jsx(Trash, { className: "h-4 w-4" })
|
|
133
|
+
}
|
|
134
|
+
)
|
|
135
|
+
] }, note.id))
|
|
136
|
+
] });
|
|
137
|
+
};
|
|
138
|
+
const widgetModule = { widgets: [
|
|
139
|
+
{
|
|
140
|
+
Component: OrderNotesWidget,
|
|
141
|
+
zone: ["order.details.after"]
|
|
142
|
+
}
|
|
143
|
+
] };
|
|
144
|
+
const routeModule = {
|
|
145
|
+
routes: []
|
|
146
|
+
};
|
|
147
|
+
const menuItemModule = {
|
|
148
|
+
menuItems: []
|
|
149
|
+
};
|
|
150
|
+
const formModule = { customFields: {} };
|
|
151
|
+
const displayModule = {
|
|
152
|
+
displays: {}
|
|
153
|
+
};
|
|
154
|
+
const i18nModule = { resources: {} };
|
|
155
|
+
const plugin = {
|
|
156
|
+
widgetModule,
|
|
157
|
+
routeModule,
|
|
158
|
+
menuItemModule,
|
|
159
|
+
formModule,
|
|
160
|
+
displayModule,
|
|
161
|
+
i18nModule
|
|
162
|
+
};
|
|
163
|
+
export {
|
|
164
|
+
plugin as default
|
|
165
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DELETE = void 0;
|
|
4
|
+
const order_note_1 = require("../../../../modules/order-note");
|
|
5
|
+
const DELETE = async (req, res) => {
|
|
6
|
+
const { id } = req.params;
|
|
7
|
+
const orderNoteService = req.scope.resolve(order_note_1.ORDER_NOTE_MODULE);
|
|
8
|
+
await orderNoteService.deleteOrderNotes([id]);
|
|
9
|
+
res.json({ deleted: [id] });
|
|
10
|
+
};
|
|
11
|
+
exports.DELETE = DELETE;
|
|
12
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL29yZGVyLW5vdGVzL1tpZF0vcm91dGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQ0EsK0RBQWtFO0FBRzNELE1BQU0sTUFBTSxHQUFHLEtBQUssRUFBRSxHQUErQixFQUFFLEdBQW1CLEVBQUUsRUFBRTtJQUNwRixNQUFNLEVBQUUsRUFBRSxFQUFFLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQTtJQUN6QixNQUFNLGdCQUFnQixHQUFxQixHQUFHLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyw4QkFBaUIsQ0FBQyxDQUFBO0lBQy9FLE1BQU0sZ0JBQWdCLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFBO0lBQzdDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxPQUFPLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUE7QUFDNUIsQ0FBQyxDQUFBO0FBTFksUUFBQSxNQUFNLFVBS2xCIn0=
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.POST = exports.GET = void 0;
|
|
4
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
5
|
+
const order_note_1 = require("../../../modules/order-note");
|
|
6
|
+
const GET = async (req, res) => {
|
|
7
|
+
const { order_id } = req.validatedQuery;
|
|
8
|
+
const query = req.scope.resolve(utils_1.ContainerRegistrationKeys.QUERY);
|
|
9
|
+
const { data: order_notes, metadata } = await query.graph({
|
|
10
|
+
entity: 'order_note',
|
|
11
|
+
...req.queryConfig,
|
|
12
|
+
filters: {
|
|
13
|
+
...(order_id ? { order_id } : {})
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
res.json({
|
|
17
|
+
order_notes,
|
|
18
|
+
count: metadata?.count,
|
|
19
|
+
limit: metadata?.take,
|
|
20
|
+
offset: metadata?.skip
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
exports.GET = GET;
|
|
24
|
+
const POST = async (req, res) => {
|
|
25
|
+
const orderNoteService = req.scope.resolve(order_note_1.ORDER_NOTE_MODULE);
|
|
26
|
+
const order_note = await orderNoteService.createNote({
|
|
27
|
+
...req.validatedBody,
|
|
28
|
+
user_id: req.auth_context.actor_id
|
|
29
|
+
});
|
|
30
|
+
res.status(201).json({ order_note });
|
|
31
|
+
};
|
|
32
|
+
exports.POST = POST;
|
|
33
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL29yZGVyLW5vdGVzL3JvdXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUNBLHFEQUFxRTtBQUVyRSw0REFBK0Q7QUFHeEQsTUFBTSxHQUFHLEdBQUcsS0FBSyxFQUN2QixHQUF1RCxFQUN2RCxHQUFtQixFQUNsQixFQUFFO0lBQ0gsTUFBTSxFQUFFLFFBQVEsRUFBRSxHQUFHLEdBQUcsQ0FBQyxjQUFjLENBQUE7SUFDdkMsTUFBTSxLQUFLLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsaUNBQXlCLENBQUMsS0FBSyxDQUFDLENBQUE7SUFFaEUsTUFBTSxFQUFFLElBQUksRUFBRSxXQUFXLEVBQUUsUUFBUSxFQUFFLEdBQUcsTUFBTSxLQUFLLENBQUMsS0FBSyxDQUFDO1FBQ3pELE1BQU0sRUFBRSxZQUFZO1FBQ3BCLEdBQUcsR0FBRyxDQUFDLFdBQVc7UUFDbEIsT0FBTyxFQUFFO1lBQ1IsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsRUFBRSxRQUFRLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1NBQ2pDO0tBQ0QsQ0FBQyxDQUFBO0lBRUYsR0FBRyxDQUFDLElBQUksQ0FBQztRQUNSLFdBQVc7UUFDWCxLQUFLLEVBQUUsUUFBUSxFQUFFLEtBQUs7UUFDdEIsS0FBSyxFQUFFLFFBQVEsRUFBRSxJQUFJO1FBQ3JCLE1BQU0sRUFBRSxRQUFRLEVBQUUsSUFBSTtLQUN0QixDQUFDLENBQUE7QUFDSCxDQUFDLENBQUE7QUFyQlksUUFBQSxHQUFHLE9BcUJmO0FBRU0sTUFBTSxJQUFJLEdBQUcsS0FBSyxFQUN4QixHQUF5RCxFQUN6RCxHQUFtQixFQUNsQixFQUFFO0lBQ0gsTUFBTSxnQkFBZ0IsR0FBcUIsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsOEJBQWlCLENBQUMsQ0FBQTtJQUMvRSxNQUFNLFVBQVUsR0FBRyxNQUFNLGdCQUFnQixDQUFDLFVBQVUsQ0FBQztRQUNwRCxHQUFHLEdBQUcsQ0FBQyxhQUFhO1FBQ3BCLE9BQU8sRUFBRSxHQUFHLENBQUMsWUFBWSxDQUFDLFFBQVE7S0FDbEMsQ0FBQyxDQUFBO0lBQ0YsR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxVQUFVLEVBQUUsQ0FBQyxDQUFBO0FBQ3JDLENBQUMsQ0FBQTtBQVZZLFFBQUEsSUFBSSxRQVVoQiJ9
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const http_1 = require("@medusajs/framework/http");
|
|
4
|
+
const validators_1 = require("./validators");
|
|
5
|
+
exports.default = (0, http_1.defineMiddlewares)([
|
|
6
|
+
{
|
|
7
|
+
matcher: '/admin/order-notes',
|
|
8
|
+
method: ['GET'],
|
|
9
|
+
middlewares: [
|
|
10
|
+
(0, http_1.validateAndTransformQuery)(validators_1.AdminGetOrderNotes, {
|
|
11
|
+
defaults: ['id', 'order_id', 'user_id', 'note', 'sent', 'created_at', 'updated_at'],
|
|
12
|
+
isList: true,
|
|
13
|
+
defaultLimit: 20
|
|
14
|
+
})
|
|
15
|
+
]
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
matcher: '/admin/order-notes',
|
|
19
|
+
method: ['POST'],
|
|
20
|
+
middlewares: [(0, http_1.validateAndTransformBody)(validators_1.AdminCreateOrderNote)]
|
|
21
|
+
}
|
|
22
|
+
]);
|
|
23
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWlkZGxld2FyZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvYXBpL21pZGRsZXdhcmVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsbURBQWlIO0FBQ2pILDZDQUF1RTtBQUV2RSxrQkFBZSxJQUFBLHdCQUFpQixFQUFDO0lBQ2hDO1FBQ0MsT0FBTyxFQUFFLG9CQUFvQjtRQUM3QixNQUFNLEVBQUUsQ0FBQyxLQUFLLENBQUM7UUFDZixXQUFXLEVBQUU7WUFDWixJQUFBLGdDQUF5QixFQUFDLCtCQUFrQixFQUFFO2dCQUM3QyxRQUFRLEVBQUUsQ0FBQyxJQUFJLEVBQUUsVUFBVSxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBRSxZQUFZLENBQUM7Z0JBQ25GLE1BQU0sRUFBRSxJQUFJO2dCQUNaLFlBQVksRUFBRSxFQUFFO2FBQ2hCLENBQUM7U0FDRjtLQUNEO0lBQ0Q7UUFDQyxPQUFPLEVBQUUsb0JBQW9CO1FBQzdCLE1BQU0sRUFBRSxDQUFDLE1BQU0sQ0FBQztRQUNoQixXQUFXLEVBQUUsQ0FBQyxJQUFBLCtCQUF3QixFQUFDLGlDQUFvQixDQUFDLENBQUM7S0FDN0Q7Q0FDRCxDQUFDLENBQUEifQ==
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AdminCreateOrderNote = exports.AdminGetOrderNotes = void 0;
|
|
4
|
+
const zod_1 = require("@medusajs/framework/zod");
|
|
5
|
+
const validators_1 = require("@medusajs/medusa/api/utils/validators");
|
|
6
|
+
exports.AdminGetOrderNotes = (0, validators_1.createFindParams)({
|
|
7
|
+
limit: 20,
|
|
8
|
+
offset: 0
|
|
9
|
+
}).extend({
|
|
10
|
+
order_id: zod_1.z.string().optional()
|
|
11
|
+
});
|
|
12
|
+
exports.AdminCreateOrderNote = zod_1.z.object({
|
|
13
|
+
order_id: zod_1.z.string(),
|
|
14
|
+
note: zod_1.z.string(),
|
|
15
|
+
sent: zod_1.z.boolean().default(false),
|
|
16
|
+
metadata: zod_1.z.record(zod_1.z.unknown()).nullable().optional()
|
|
17
|
+
});
|
|
18
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdG9ycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9hcGkvdmFsaWRhdG9ycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxpREFBMkM7QUFDM0Msc0VBQXdFO0FBRTNELFFBQUEsa0JBQWtCLEdBQUcsSUFBQSw2QkFBZ0IsRUFBQztJQUNsRCxLQUFLLEVBQUUsRUFBRTtJQUNULE1BQU0sRUFBRSxDQUFDO0NBQ1QsQ0FBQyxDQUFDLE1BQU0sQ0FBQztJQUNULFFBQVEsRUFBRSxPQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxFQUFFO0NBQy9CLENBQUMsQ0FBQTtBQUdXLFFBQUEsb0JBQW9CLEdBQUcsT0FBQyxDQUFDLE1BQU0sQ0FBQztJQUM1QyxRQUFRLEVBQUUsT0FBQyxDQUFDLE1BQU0sRUFBRTtJQUNwQixJQUFJLEVBQUUsT0FBQyxDQUFDLE1BQU0sRUFBRTtJQUNoQixJQUFJLEVBQUUsT0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUM7SUFDaEMsUUFBUSxFQUFFLE9BQUMsQ0FBQyxNQUFNLENBQUMsT0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUMsUUFBUSxFQUFFO0NBQ3JELENBQUMsQ0FBQSJ9
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
7
|
+
const order_1 = __importDefault(require("@medusajs/medusa/order"));
|
|
8
|
+
const order_note_1 = __importDefault(require("../modules/order-note"));
|
|
9
|
+
exports.default = (0, utils_1.defineLink)({
|
|
10
|
+
linkable: order_note_1.default.linkable.orderNote,
|
|
11
|
+
field: 'order_id'
|
|
12
|
+
}, order_1.default.linkable.order, {
|
|
13
|
+
readOnly: true
|
|
14
|
+
});
|
|
15
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3JkZXItbm90ZS1vcmRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saW5rcy9vcmRlci1ub3RlLW9yZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEscURBQXNEO0FBQ3RELG1FQUFnRDtBQUNoRCx1RUFBbUQ7QUFFbkQsa0JBQWUsSUFBQSxrQkFBVSxFQUN4QjtJQUNDLFFBQVEsRUFBRSxvQkFBZSxDQUFDLFFBQVEsQ0FBQyxTQUFTO0lBQzVDLEtBQUssRUFBRSxVQUFVO0NBQ2pCLEVBQ0QsZUFBVyxDQUFDLFFBQVEsQ0FBQyxLQUFLLEVBQzFCO0lBQ0MsUUFBUSxFQUFFLElBQUk7Q0FDZCxDQUNELENBQUEifQ==
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
7
|
+
const order_1 = __importDefault(require("@medusajs/medusa/order"));
|
|
8
|
+
const order_note_1 = __importDefault(require("../modules/order-note"));
|
|
9
|
+
exports.default = (0, utils_1.defineLink)({
|
|
10
|
+
linkable: order_1.default.linkable.order,
|
|
11
|
+
field: 'id'
|
|
12
|
+
}, {
|
|
13
|
+
...order_note_1.default.linkable.orderNote.id,
|
|
14
|
+
primaryKey: 'order_id'
|
|
15
|
+
}, {
|
|
16
|
+
readOnly: true
|
|
17
|
+
});
|
|
18
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3JkZXItb3JkZXItbm90ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saW5rcy9vcmRlci1vcmRlci1ub3RlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEscURBQXNEO0FBQ3RELG1FQUFnRDtBQUNoRCx1RUFBbUQ7QUFFbkQsa0JBQWUsSUFBQSxrQkFBVSxFQUN4QjtJQUNDLFFBQVEsRUFBRSxlQUFXLENBQUMsUUFBUSxDQUFDLEtBQUs7SUFDcEMsS0FBSyxFQUFFLElBQUk7Q0FDWCxFQUNEO0lBQ0MsR0FBRyxvQkFBZSxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsRUFBRTtJQUN4QyxVQUFVLEVBQUUsVUFBVTtDQUN0QixFQUNEO0lBQ0MsUUFBUSxFQUFFLElBQUk7Q0FDZCxDQUNELENBQUEifQ==
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ORDER_NOTE_MODULE = void 0;
|
|
4
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
5
|
+
const service_1 = require("./service");
|
|
6
|
+
exports.ORDER_NOTE_MODULE = 'order_note';
|
|
7
|
+
exports.default = (0, utils_1.Module)(exports.ORDER_NOTE_MODULE, {
|
|
8
|
+
service: service_1.OrderNoteService
|
|
9
|
+
});
|
|
10
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvbW9kdWxlcy9vcmRlci1ub3RlL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHFEQUFrRDtBQUNsRCx1Q0FBNEM7QUFFL0IsUUFBQSxpQkFBaUIsR0FBRyxZQUFZLENBQUE7QUFFN0Msa0JBQWUsSUFBQSxjQUFNLEVBQUMseUJBQWlCLEVBQUU7SUFDeEMsT0FBTyxFQUFFLDBCQUFnQjtDQUN6QixDQUFDLENBQUEifQ==
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Migration20260409171812 = void 0;
|
|
4
|
+
const migrations_1 = require("@medusajs/framework/mikro-orm/migrations");
|
|
5
|
+
class Migration20260409171812 extends migrations_1.Migration {
|
|
6
|
+
async up() {
|
|
7
|
+
this.addSql(`create table if not exists "order_note" ("id" text not null, "order_id" text not null, "user_id" text not null, "note" text not null, "sent" boolean not null default false, "metadata" jsonb null, "created_at" timestamptz not null default now(), "updated_at" timestamptz not null default now(), "deleted_at" timestamptz null, constraint "order_note_pkey" primary key ("id"));`);
|
|
8
|
+
this.addSql(`CREATE INDEX IF NOT EXISTS "IDX_order_note_deleted_at" ON "order_note" ("deleted_at") WHERE deleted_at IS NULL;`);
|
|
9
|
+
}
|
|
10
|
+
async down() {
|
|
11
|
+
this.addSql(`drop table if exists "order_note" cascade;`);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
exports.Migration20260409171812 = Migration20260409171812;
|
|
15
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTWlncmF0aW9uMjAyNjA0MDkxNzE4MTIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvbW9kdWxlcy9vcmRlci1ub3RlL21pZ3JhdGlvbnMvTWlncmF0aW9uMjAyNjA0MDkxNzE4MTIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEseUVBQXFFO0FBRXJFLE1BQWEsdUJBQXdCLFNBQVEsc0JBQVM7SUFFM0MsS0FBSyxDQUFDLEVBQUU7UUFDZixJQUFJLENBQUMsTUFBTSxDQUFDLHdYQUF3WCxDQUFDLENBQUM7UUFDdFksSUFBSSxDQUFDLE1BQU0sQ0FBQyxpSEFBaUgsQ0FBQyxDQUFDO0lBQ2pJLENBQUM7SUFFUSxLQUFLLENBQUMsSUFBSTtRQUNqQixJQUFJLENBQUMsTUFBTSxDQUFDLDRDQUE0QyxDQUFDLENBQUM7SUFDNUQsQ0FBQztDQUVGO0FBWEQsMERBV0MifQ==
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.OrderNote = void 0;
|
|
4
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
5
|
+
exports.OrderNote = utils_1.model.define('order_note', {
|
|
6
|
+
id: utils_1.model.id().primaryKey(),
|
|
7
|
+
order_id: utils_1.model.text(),
|
|
8
|
+
user_id: utils_1.model.text(),
|
|
9
|
+
note: utils_1.model.text(),
|
|
10
|
+
sent: utils_1.model.boolean().default(false),
|
|
11
|
+
metadata: utils_1.model.json().nullable()
|
|
12
|
+
});
|
|
13
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3JkZXItbm90ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9tb2R1bGVzL29yZGVyLW5vdGUvbW9kZWxzL29yZGVyLW5vdGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEscURBQWlEO0FBRXBDLFFBQUEsU0FBUyxHQUFHLGFBQUssQ0FBQyxNQUFNLENBQUMsWUFBWSxFQUFFO0lBQ25ELEVBQUUsRUFBRSxhQUFLLENBQUMsRUFBRSxFQUFFLENBQUMsVUFBVSxFQUFFO0lBQzNCLFFBQVEsRUFBRSxhQUFLLENBQUMsSUFBSSxFQUFFO0lBQ3RCLE9BQU8sRUFBRSxhQUFLLENBQUMsSUFBSSxFQUFFO0lBQ3JCLElBQUksRUFBRSxhQUFLLENBQUMsSUFBSSxFQUFFO0lBQ2xCLElBQUksRUFBRSxhQUFLLENBQUMsT0FBTyxFQUFFLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQztJQUNwQyxRQUFRLEVBQUUsYUFBSyxDQUFDLElBQUksRUFBRSxDQUFDLFFBQVEsRUFBRTtDQUNqQyxDQUFDLENBQUEifQ==
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.OrderNoteService = void 0;
|
|
4
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
5
|
+
const order_note_1 = require("./models/order-note");
|
|
6
|
+
class OrderNoteService extends (0, utils_1.MedusaService)({ OrderNote: order_note_1.OrderNote }) {
|
|
7
|
+
constructor({ logger, event_bus }, _options) {
|
|
8
|
+
super(...arguments);
|
|
9
|
+
this.logger_ = logger;
|
|
10
|
+
this.eventBusService_ = event_bus;
|
|
11
|
+
}
|
|
12
|
+
async createNote(data) {
|
|
13
|
+
const orderNote = await this.createOrderNotes(data);
|
|
14
|
+
await this.eventBusService_.emit({
|
|
15
|
+
name: 'order-note.created',
|
|
16
|
+
data: { id: orderNote.id }
|
|
17
|
+
});
|
|
18
|
+
this.logger_.info(`Order note created: ${orderNote.id} (sent: ${data.sent})`);
|
|
19
|
+
return orderNote;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
exports.OrderNoteService = OrderNoteService;
|
|
23
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9tb2R1bGVzL29yZGVyLW5vdGUvc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFDQSxxREFBeUQ7QUFDekQsb0RBQStDO0FBSS9DLE1BQWEsZ0JBQWlCLFNBQVEsSUFBQSxxQkFBYSxFQUFDLEVBQUUsU0FBUyxFQUFULHNCQUFTLEVBQUUsQ0FBQztJQUlqRSxZQUNDLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBbUQsRUFDdEUsUUFBYztRQUVkLEtBQUssQ0FBQyxHQUFHLFNBQVMsQ0FBQyxDQUFBO1FBQ25CLElBQUksQ0FBQyxPQUFPLEdBQUcsTUFBTSxDQUFBO1FBQ3JCLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxTQUFTLENBQUE7SUFDbEMsQ0FBQztJQUVELEtBQUssQ0FBQyxVQUFVLENBQUMsSUFNaEI7UUFDQSxNQUFNLFNBQVMsR0FBRyxNQUFNLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsQ0FBQTtRQUVuRCxNQUFNLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUM7WUFDaEMsSUFBSSxFQUFFLG9CQUFvQjtZQUMxQixJQUFJLEVBQUUsRUFBRSxFQUFFLEVBQUUsU0FBUyxDQUFDLEVBQUUsRUFBRTtTQUMxQixDQUFDLENBQUE7UUFFRixJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyx1QkFBdUIsU0FBUyxDQUFDLEVBQUUsV0FBVyxJQUFJLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQTtRQUU3RSxPQUFPLFNBQVMsQ0FBQTtJQUNqQixDQUFDO0NBQ0Q7QUEvQkQsNENBK0JDIn0=
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Lacey Pevey
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# medusa-plugin-order-notes
|
|
2
|
+
|
|
3
|
+
Order notes plugin adding Medusa v1-style notes for Medusa v2. Add internal notes to orders and optionally send them to customers via email.
|
|
4
|
+
|
|
5
|
+
[Documentation](https://pevey.com/medusa-plugin-order-notes)
|
|
6
|
+
|
|
7
|
+
If you are not familiar with Medusa, you can learn more on [the project web site](https://www.medusajs.com/).
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- Add notes to any order from the Order detail page
|
|
12
|
+
- Option to mark notes as "sent to customer" for email notification
|
|
13
|
+
- Widget on Order detail page displaying all notes with timestamps
|
|
14
|
+
- Delete notes when no longer needed
|
|
15
|
+
- Filterable by order ID via the admin API
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
Inside your medusa backend root folder:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
yarn add medusa-plugin-order-notes
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Replace "yarn add" with the correct command for your package manager if you are using (for example) npm, pnpm, or bun.
|
|
26
|
+
|
|
27
|
+
## Configuration
|
|
28
|
+
|
|
29
|
+
Enable in your `medusa-config.ts` file. Example:
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
module.exports = defineConfig({
|
|
33
|
+
//... other config
|
|
34
|
+
plugins: [
|
|
35
|
+
{
|
|
36
|
+
resolve: 'medusa-plugin-order-notes',
|
|
37
|
+
options: {}
|
|
38
|
+
}
|
|
39
|
+
// ... other plugins
|
|
40
|
+
]
|
|
41
|
+
})
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
To ensure order notes cannot be queried in GET requests to the API, add 'order_note' to your restricted fields in `medusa-config.ts`.
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
module.exports = defineConfig({
|
|
48
|
+
projectConfig: {
|
|
49
|
+
// ... other settings
|
|
50
|
+
http: {
|
|
51
|
+
// ... other settings
|
|
52
|
+
restrictedFields: {
|
|
53
|
+
store: ['order_note']
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
})
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Usage
|
|
61
|
+
|
|
62
|
+
- Navigate to any Order detail page in the Medusa admin.
|
|
63
|
+
- Use the Order Notes widget to add, view, and delete notes.
|
|
64
|
+
- Check "Send to customer" when creating a note to trigger an email notification.
|
package/package.json
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "medusa-plugin-order-notes",
|
|
3
|
+
"version": "0.1.2",
|
|
4
|
+
"description": "Order notes plugin adding Medusa v1-style notes for Medusa v2",
|
|
5
|
+
"author": "Lacey Pevey",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/pevey/medusa-plugins"
|
|
10
|
+
},
|
|
11
|
+
"homepage": "https://pevey.com/medusa-plugin-order-notes",
|
|
12
|
+
"files": [
|
|
13
|
+
".medusa/server"
|
|
14
|
+
],
|
|
15
|
+
"exports": {
|
|
16
|
+
"./package.json": "./package.json",
|
|
17
|
+
"./admin": {
|
|
18
|
+
"import": "./.medusa/server/src/admin/index.mjs",
|
|
19
|
+
"require": "./.medusa/server/src/admin/index.js",
|
|
20
|
+
"default": "./.medusa/server/src/admin/index.js"
|
|
21
|
+
},
|
|
22
|
+
"./.medusa/server/src/modules/*": "./.medusa/server/src/modules/*/index.js",
|
|
23
|
+
"./modules/*": "./.medusa/server/src/modules/*/index.js",
|
|
24
|
+
"./providers/*": "./.medusa/server/src/providers/*/index.js",
|
|
25
|
+
"./*": "./.medusa/server/src/*.js",
|
|
26
|
+
".": "./.medusa/server/src/modules/order-note/index.js"
|
|
27
|
+
},
|
|
28
|
+
"keywords": [
|
|
29
|
+
"medusa-v2",
|
|
30
|
+
"medusa",
|
|
31
|
+
"order notes",
|
|
32
|
+
"notes"
|
|
33
|
+
],
|
|
34
|
+
"scripts": {
|
|
35
|
+
"build": "medusa plugin:build",
|
|
36
|
+
"clean:snapshots": "find . -name '.snapshot-*.json' -path '*/migrations/*' -delete",
|
|
37
|
+
"dev": "medusa plugin:develop",
|
|
38
|
+
"prepublishOnly": "medusa plugin:build",
|
|
39
|
+
"test:unit": "TEST_TYPE=unit NODE_OPTIONS=--experimental-vm-modules jest --silent --runInBand --detectOpenHandles --forceExit --passWithNoTests",
|
|
40
|
+
"test:integration:http": "TEST_TYPE=integration:http NODE_OPTIONS=--experimental-vm-modules jest --silent=false --runInBand --detectOpenHandles --forceExit"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"@medusajs/admin-sdk": "2.13.6",
|
|
44
|
+
"@medusajs/cli": "2.13.6",
|
|
45
|
+
"@medusajs/framework": "2.13.6",
|
|
46
|
+
"@medusajs/icons": "2.13.6",
|
|
47
|
+
"@medusajs/js-sdk": "2.13.6",
|
|
48
|
+
"@medusajs/medusa": "2.13.6",
|
|
49
|
+
"@medusajs/test-utils": "2.13.6",
|
|
50
|
+
"@medusajs/ui": "4.0.25",
|
|
51
|
+
"@swc/core": "^1.7.28",
|
|
52
|
+
"@swc/jest": "^0.2.39",
|
|
53
|
+
"@types/jest": "^30.0.0",
|
|
54
|
+
"@types/node": "^20.0.0",
|
|
55
|
+
"@types/react": "^18.3.2",
|
|
56
|
+
"@types/react-dom": "^18.2.25",
|
|
57
|
+
"jest": "^29.7.0",
|
|
58
|
+
"prop-types": "^15.8.1",
|
|
59
|
+
"react": "^18.2.0",
|
|
60
|
+
"react-dom": "^18.2.0",
|
|
61
|
+
"ts-node": "^10.9.2",
|
|
62
|
+
"typescript": "^5.6.2",
|
|
63
|
+
"vite": "^5.2.11",
|
|
64
|
+
"yalc": "^1.0.0-pre.53"
|
|
65
|
+
},
|
|
66
|
+
"peerDependencies": {
|
|
67
|
+
"@medusajs/admin-sdk": "2.13.6",
|
|
68
|
+
"@medusajs/cli": "2.13.6",
|
|
69
|
+
"@medusajs/framework": "2.13.6",
|
|
70
|
+
"@medusajs/icons": "2.13.6",
|
|
71
|
+
"@medusajs/medusa": "2.13.6",
|
|
72
|
+
"@medusajs/test-utils": "2.13.6",
|
|
73
|
+
"@medusajs/ui": "4.0.25"
|
|
74
|
+
},
|
|
75
|
+
"engines": {
|
|
76
|
+
"node": ">=20"
|
|
77
|
+
}
|
|
78
|
+
}
|