@pisell/private-materials 6.3.220 → 6.3.222

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.
Files changed (125) hide show
  1. package/build/lowcode/assets-daily.json +11 -11
  2. package/build/lowcode/assets-dev.json +2 -2
  3. package/build/lowcode/assets-prod.json +11 -11
  4. package/build/lowcode/meta.js +1 -1
  5. package/build/lowcode/render/default/view.css +1 -1
  6. package/build/lowcode/render/default/view.js +13 -13
  7. package/build/lowcode/view.css +1 -1
  8. package/build/lowcode/view.js +13 -13
  9. package/es/components/kioskSkuDetail/index.js +7 -7
  10. package/es/components/pay/toC/PaymentMethods/MWCreditCard/tds2.js +53 -26
  11. package/es/components/scanOrder/components/Content/index.js +14 -2
  12. package/es/components/scanOrder/components/ExitConfirmModal/index.js +84 -0
  13. package/es/components/scanOrder/components/ExitConfirmModal/index.less +182 -0
  14. package/es/components/scanOrder/locales.js +20 -0
  15. package/es/index.d.ts +9 -1
  16. package/es/index.js +6 -2
  17. package/es/plus/inventory/BindingModal.js +94 -0
  18. package/es/plus/inventory/InventoryItemManagement.d.ts +7 -0
  19. package/es/plus/inventory/InventoryItemManagement.js +204 -0
  20. package/es/plus/inventory/InventoryLocationManagement.d.ts +7 -0
  21. package/es/plus/inventory/InventoryLocationManagement.js +296 -0
  22. package/es/plus/inventory/InventoryUnitManagement.d.ts +7 -0
  23. package/es/plus/inventory/InventoryUnitManagement.js +144 -0
  24. package/es/plus/inventory/ItemDrawer.js +266 -0
  25. package/es/plus/inventory/RecordDialog.js +141 -0
  26. package/es/plus/inventory/StockList.js +132 -0
  27. package/es/plus/inventory/api.js +66 -0
  28. package/es/plus/inventory/components.js +172 -0
  29. package/es/plus/inventory/context.js +118 -0
  30. package/es/plus/inventory/forms.js +46 -0
  31. package/es/plus/inventory/hooks.js +235 -0
  32. package/es/plus/inventory/index.less +559 -0
  33. package/es/plus/inventory/locales.js +277 -0
  34. package/es/plus/inventory/types.d.ts +10 -0
  35. package/es/plus/inventory/utils.js +24 -0
  36. package/es/plus/panpacificTask/JobCard.js +22 -0
  37. package/es/plus/panpacificTask/JobDrawer.js +366 -0
  38. package/es/plus/panpacificTask/JobForm.js +312 -0
  39. package/es/plus/panpacificTask/JobStatus.js +29 -0
  40. package/es/plus/panpacificTask/PanpacificTask.d.ts +7 -0
  41. package/es/plus/panpacificTask/PanpacificTask.js +552 -0
  42. package/es/plus/panpacificTask/PhotoPreview.js +37 -0
  43. package/es/plus/panpacificTask/README.md +114 -0
  44. package/es/plus/panpacificTask/attachments.js +64 -0
  45. package/es/plus/panpacificTask/index.d.ts +2 -0
  46. package/es/plus/panpacificTask/index.less +539 -0
  47. package/es/plus/panpacificTask/locales.js +586 -0
  48. package/es/plus/panpacificTask/model.js +260 -0
  49. package/es/plus/panpacificTask/saveJob.js +68 -0
  50. package/es/plus/panpacificTask/serve.js +243 -0
  51. package/es/plus/panpacificTask/tenant.js +16 -0
  52. package/es/plus/panpacificTask/types.d.ts +19 -0
  53. package/es/plus/pisellReservation/data/bookingToReservationTables.js +1 -1
  54. package/es/plus/pisellReservation/floorMap/floorPlanApi.js +1 -1
  55. package/es/plus/pisellReservation/floorMap/reservationMock.js +1 -1
  56. package/es/plus/pisellSupersetDashboard/README.md +291 -0
  57. package/es/plus/pisellSupersetDashboard/index.d.ts +15 -0
  58. package/es/plus/pisellSupersetDashboard/index.js +187 -0
  59. package/es/plus/pisellSupersetDashboard/index.less +83 -0
  60. package/es/plus/pisellSupersetDashboard/locales.js +36 -0
  61. package/es/plus/pisellSupersetDashboard/serve.js +51 -0
  62. package/es/plus/pisellSupersetDashboard/types.d.ts +17 -0
  63. package/es/plus/skuOptionsSelection/store/createStore.js +2 -2
  64. package/es/private-materials/lowcode/authmodal/meta.d.ts +1 -0
  65. package/es/pro/Login2.0/AuthModal.d.ts +1 -1
  66. package/es/pro/Login2.0/index.d.ts +1 -2
  67. package/es/pro/Login2.0/shared/types.d.ts +1 -1
  68. package/lib/components/kioskSkuDetail/index.js +7 -7
  69. package/lib/components/pay/toC/PaymentMethods/MWCreditCard/tds2.js +53 -26
  70. package/lib/components/scanOrder/components/Content/index.js +14 -2
  71. package/lib/components/scanOrder/components/ExitConfirmModal/index.js +86 -0
  72. package/lib/components/scanOrder/components/ExitConfirmModal/index.less +182 -0
  73. package/lib/components/scanOrder/locales.js +20 -0
  74. package/lib/index.d.ts +9 -1
  75. package/lib/index.js +136 -126
  76. package/lib/plus/inventory/BindingModal.js +96 -0
  77. package/lib/plus/inventory/InventoryItemManagement.d.ts +7 -0
  78. package/lib/plus/inventory/InventoryItemManagement.js +206 -0
  79. package/lib/plus/inventory/InventoryLocationManagement.d.ts +7 -0
  80. package/lib/plus/inventory/InventoryLocationManagement.js +298 -0
  81. package/lib/plus/inventory/InventoryUnitManagement.d.ts +7 -0
  82. package/lib/plus/inventory/InventoryUnitManagement.js +146 -0
  83. package/lib/plus/inventory/ItemDrawer.js +268 -0
  84. package/lib/plus/inventory/RecordDialog.js +143 -0
  85. package/lib/plus/inventory/StockList.js +134 -0
  86. package/lib/plus/inventory/api.js +66 -0
  87. package/lib/plus/inventory/components.js +181 -0
  88. package/lib/plus/inventory/context.js +121 -0
  89. package/lib/plus/inventory/forms.js +50 -0
  90. package/lib/plus/inventory/hooks.js +240 -0
  91. package/lib/plus/inventory/index.less +559 -0
  92. package/lib/plus/inventory/locales.js +277 -0
  93. package/lib/plus/inventory/types.d.ts +10 -0
  94. package/lib/plus/inventory/utils.js +30 -0
  95. package/lib/plus/panpacificTask/JobCard.js +24 -0
  96. package/lib/plus/panpacificTask/JobDrawer.js +368 -0
  97. package/lib/plus/panpacificTask/JobForm.js +314 -0
  98. package/lib/plus/panpacificTask/JobStatus.js +33 -0
  99. package/lib/plus/panpacificTask/PanpacificTask.d.ts +7 -0
  100. package/lib/plus/panpacificTask/PanpacificTask.js +555 -0
  101. package/lib/plus/panpacificTask/PhotoPreview.js +39 -0
  102. package/lib/plus/panpacificTask/README.md +114 -0
  103. package/lib/plus/panpacificTask/attachments.js +66 -0
  104. package/lib/plus/panpacificTask/index.d.ts +2 -0
  105. package/lib/plus/panpacificTask/index.less +539 -0
  106. package/lib/plus/panpacificTask/locales.js +586 -0
  107. package/lib/plus/panpacificTask/model.js +289 -0
  108. package/lib/plus/panpacificTask/saveJob.js +68 -0
  109. package/lib/plus/panpacificTask/serve.js +260 -0
  110. package/lib/plus/panpacificTask/tenant.js +17 -0
  111. package/lib/plus/panpacificTask/types.d.ts +19 -0
  112. package/lib/plus/pisellSupersetDashboard/README.md +291 -0
  113. package/lib/plus/pisellSupersetDashboard/index.d.ts +15 -0
  114. package/lib/plus/pisellSupersetDashboard/index.js +189 -0
  115. package/lib/plus/pisellSupersetDashboard/index.less +83 -0
  116. package/lib/plus/pisellSupersetDashboard/locales.js +36 -0
  117. package/lib/plus/pisellSupersetDashboard/serve.js +52 -0
  118. package/lib/plus/pisellSupersetDashboard/types.d.ts +17 -0
  119. package/lowcode/inventory-item-management/meta.ts +20 -0
  120. package/lowcode/inventory-location-management/meta.ts +20 -0
  121. package/lowcode/inventory-unit-management/meta.ts +20 -0
  122. package/lowcode/panpacific-task/meta.ts +51 -0
  123. package/lowcode/pisell-superset-dashboard/meta.ts +75 -0
  124. package/package.json +4 -2
  125. package/es/plus/pisellReservation/index.js +0 -17
@@ -0,0 +1,555 @@
1
+ const require_runtime = require("../../_virtual/_rolldown/runtime.js");
2
+ const require_objectSpread2 = require("../../_virtual/_@oxc-project_runtime@0.122.0/helpers/objectSpread2.js");
3
+ const require_asyncToGenerator = require("../../_virtual/_@oxc-project_runtime@0.122.0/helpers/asyncToGenerator.js");
4
+ const require_useEngineContext = require("../../hooks/useEngineContext.js");
5
+ const require_index = require("../../utils/index.js");
6
+ const require_attachments = require("./attachments.js");
7
+ const require_model = require("./model.js");
8
+ const require_serve = require("./serve.js");
9
+ const require_JobForm = require("./JobForm.js");
10
+ const require_JobStatus = require("./JobStatus.js");
11
+ const require_JobDrawer = require("./JobDrawer.js");
12
+ const require_JobCard = require("./JobCard.js");
13
+ const require_locales = require("./locales.js");
14
+ let dayjs = require("dayjs");
15
+ dayjs = require_runtime.__toESM(dayjs);
16
+ let react = require("react");
17
+ react = require_runtime.__toESM(react);
18
+ let antd = require("antd");
19
+ let _pisell_utils = require("@pisell/utils");
20
+ let _pisell_materials = require("@pisell/materials");
21
+ require("./index.less");
22
+ //#region src/plus/panpacificTask/PanpacificTask.tsx
23
+ /** Complete #task workspace. All UI state belongs to this component, including its overlays. */
24
+ function PanpacificTask(props) {
25
+ return /* @__PURE__ */ react.default.createElement(antd.ConfigProvider, {
26
+ prefixCls: "pisell-lowcode",
27
+ componentSize: "middle",
28
+ theme: { token: {
29
+ colorPrimary: "#634db3",
30
+ controlHeight: 38,
31
+ controlHeightSM: 38
32
+ } }
33
+ }, /* @__PURE__ */ react.default.createElement(TaskWorkspace, props));
34
+ }
35
+ function TaskWorkspace(props) {
36
+ var _context$appHelper, _context$engine, _context$appHelper2;
37
+ const context = require_useEngineContext.default();
38
+ const utils = (context === null || context === void 0 || (_context$appHelper = context.appHelper) === null || _context$appHelper === void 0 ? void 0 : _context$appHelper.utils) || {};
39
+ if (utils.request) require_index.request.setRequest(utils.request);
40
+ const locale = (context === null || context === void 0 || (_context$engine = context.engine) === null || _context$engine === void 0 || (_context$engine = _context$engine.props) === null || _context$engine === void 0 ? void 0 : _context$engine.locale) || "en";
41
+ _pisell_utils.locales.init(require_locales.default, locale);
42
+ const getText = _pisell_utils.locales.getText;
43
+ const client = (0, react.useMemo)(() => utils.request || require_index.request.getRequest(), [utils.request]);
44
+ const { mediaUploadUrl, getHeaders } = (context === null || context === void 0 || (_context$appHelper2 = context.appHelper) === null || _context$appHelper2 === void 0 ? void 0 : _context$appHelper2.constants) || {};
45
+ const uploadPhoto = (0, react.useMemo)(() => props.uploadPhoto || require_attachments.defaultPhotoUploader({
46
+ mediaUploadUrl,
47
+ getHeaders
48
+ }), [
49
+ props.uploadPhoto,
50
+ mediaUploadUrl,
51
+ getHeaders
52
+ ]);
53
+ const [modal, modalContext] = antd.Modal.useModal();
54
+ const [tab, setTab] = (0, react.useState)(props.defaultTab || "calendar");
55
+ const [jobs, setJobs] = (0, react.useState)([]);
56
+ const [base, setBase] = (0, react.useState)(require_model.emptyBase);
57
+ const [loading, setLoading] = (0, react.useState)(false);
58
+ const [busyId, setBusyId] = (0, react.useState)();
59
+ const [month, setMonth] = (0, react.useState)((0, dayjs.default)().format("YYYY-MM"));
60
+ const [selectedDate, setSelectedDate] = (0, react.useState)(require_model.dateText((0, dayjs.default)()));
61
+ const [period, setPeriod] = (0, react.useState)(false);
62
+ const [viewport, setViewport] = (0, react.useState)({
63
+ mode: "month",
64
+ month
65
+ });
66
+ const [ganttStatus, setGanttStatus] = (0, react.useState)();
67
+ const [hoveredJob, setHoveredJob] = (0, react.useState)();
68
+ const [collapsed, setCollapsed] = (0, react.useState)([]);
69
+ const [filters, setFilters] = (0, react.useState)({
70
+ search: "",
71
+ due: ""
72
+ });
73
+ const [page, setPage] = (0, react.useState)(1);
74
+ const [pageSize, setPageSize] = (0, react.useState)(10);
75
+ const [drawer, setDrawer] = (0, react.useState)();
76
+ const [draft, setDraft] = (0, react.useState)();
77
+ const [editorKey, setEditorKey] = (0, react.useState)(0);
78
+ const editorRef = (0, react.useRef)(null);
79
+ const disposed = (0, react.useRef)(false);
80
+ const readSequence = (0, react.useRef)(0);
81
+ const writing = (0, react.useRef)(false);
82
+ const changeCallback = (0, react.useRef)(props.onJobChange);
83
+ changeCallback.current = props.onJobChange;
84
+ const load = (0, react.useCallback)(require_asyncToGenerator._asyncToGenerator(function* () {
85
+ const token = ++readSequence.current;
86
+ setLoading(true);
87
+ try {
88
+ const result = yield require_serve.getJobs(client);
89
+ if (!disposed.current && token === readSequence.current) setJobs(result);
90
+ } catch (error) {
91
+ console.warn("[PanpacificTask] Job list load failed", error);
92
+ } finally {
93
+ if (!disposed.current && token === readSequence.current) setLoading(false);
94
+ }
95
+ }), [client]);
96
+ (0, react.useEffect)(() => {
97
+ disposed.current = false;
98
+ let cancelled = false;
99
+ load();
100
+ require_serve.getJobBaseData(client).then((result) => {
101
+ if (!cancelled) setBase((previous) => require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, previous), result));
102
+ });
103
+ return () => {
104
+ cancelled = true;
105
+ disposed.current = true;
106
+ readSequence.current++;
107
+ };
108
+ }, [client, load]);
109
+ const confirm = (key) => new Promise((resolve) => modal.confirm({
110
+ title: getText(`pisell2.panpacific.task.${key}`),
111
+ okText: getText(`pisell2.panpacific.task.${key === "discardConfirm" ? "discard" : key === "removeConfirm" ? "remove" : "cancelJob"}`),
112
+ cancelText: getText("pisell2.panpacific.task.cancelAction"),
113
+ okButtonProps: { danger: true },
114
+ onOk: () => resolve(true),
115
+ onCancel: () => resolve(false)
116
+ }));
117
+ const changed = (id) => {
118
+ var _changeCallback$curre;
119
+ load();
120
+ (_changeCallback$curre = changeCallback.current) === null || _changeCallback$curre === void 0 || _changeCallback$curre.call(changeCallback, id);
121
+ };
122
+ const openCreate = (initial = require_model.draftFor(void 0, selectedDate)) => {
123
+ setEditorKey((value) => value + 1);
124
+ setDraft(initial);
125
+ };
126
+ const openJob = (job, edit = false) => {
127
+ if (!writing.current && !draft) setDrawer({
128
+ id: job.id,
129
+ edit
130
+ });
131
+ };
132
+ const mutate = function() {
133
+ var _ref = require_asyncToGenerator._asyncToGenerator(function* (job, operation, patch) {
134
+ if (writing.current) return false;
135
+ writing.current = true;
136
+ setBusyId(job.id);
137
+ try {
138
+ yield operation();
139
+ if (!disposed.current) {
140
+ var _changeCallback$curre2;
141
+ if (patch) setJobs((previous) => previous.map((row) => String(row.id) === String(job.id) ? require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, row), patch) : row));
142
+ yield load();
143
+ (_changeCallback$curre2 = changeCallback.current) === null || _changeCallback$curre2 === void 0 || _changeCallback$curre2.call(changeCallback, job.id);
144
+ }
145
+ return true;
146
+ } catch (error) {
147
+ if (!disposed.current) modal.error({ title: getText(require_serve.errorText(error)) });
148
+ return false;
149
+ } finally {
150
+ writing.current = false;
151
+ if (!disposed.current) setBusyId(void 0);
152
+ }
153
+ });
154
+ return function mutate(_x, _x2, _x3) {
155
+ return _ref.apply(this, arguments);
156
+ };
157
+ }();
158
+ const remove = function() {
159
+ var _ref2 = require_asyncToGenerator._asyncToGenerator(function* (job) {
160
+ if (yield confirm("removeConfirm")) {
161
+ if (yield mutate(job, () => require_serve.removeJob(client, job.id))) setJobs((previous) => previous.filter((row) => String(row.id) !== String(job.id)));
162
+ }
163
+ });
164
+ return function remove(_x4) {
165
+ return _ref2.apply(this, arguments);
166
+ };
167
+ }();
168
+ const cancel = function() {
169
+ var _ref3 = require_asyncToGenerator._asyncToGenerator(function* (job) {
170
+ if (yield confirm("cancelConfirm")) yield mutate(job, () => require_serve.updateJob(client, job.id, { status: "cancel" }), { status: "cancel" });
171
+ });
172
+ return function cancel(_x5) {
173
+ return _ref3.apply(this, arguments);
174
+ };
175
+ }();
176
+ const requestDates = function() {
177
+ var _ref4 = require_asyncToGenerator._asyncToGenerator(function* (change) {
178
+ const job = jobs.find((row) => String(row.id) === change.item.id);
179
+ if (!job || writing.current) return {
180
+ accepted: false,
181
+ reason: getText("pisell2.panpacific.task.requestFailed")
182
+ };
183
+ const currentRange = require_model.jobRange(job);
184
+ if (!currentRange || currentRange.start !== change.before.start || currentRange.endExclusive !== change.before.endExclusive) return {
185
+ accepted: false,
186
+ reason: getText("pisell2.panpacific.task.requestFailed")
187
+ };
188
+ const patch = require_model.shiftDates(job, change.after, change.action);
189
+ const accepted = yield mutate(job, () => require_serve.updateJob(client, job.id, patch), patch);
190
+ return require_objectSpread2._objectSpread2({ accepted }, accepted ? {} : { reason: getText("pisell2.panpacific.task.requestFailed") });
191
+ });
192
+ return function requestDates(_x6) {
193
+ return _ref4.apply(this, arguments);
194
+ };
195
+ }();
196
+ const statusOptions = require_model.displayStatuses.map((value) => ({
197
+ value,
198
+ label: getText(`pisell2.panpacific.task.${value}`)
199
+ }));
200
+ const statusSelect = (value, onChange) => /* @__PURE__ */ react.default.createElement(antd.Select, {
201
+ size: "small",
202
+ allowClear: true,
203
+ showSearch: true,
204
+ optionFilterProp: "label",
205
+ className: "pp-task-filter-status",
206
+ "aria-label": getText("pisell2.panpacific.task.status"),
207
+ placeholder: getText("pisell2.panpacific.task.allStatuses"),
208
+ options: [{
209
+ value: "",
210
+ label: getText("pisell2.panpacific.task.allStatuses")
211
+ }, ...statusOptions],
212
+ value: value || "",
213
+ onChange: (next) => onChange(next || void 0)
214
+ });
215
+ const deferredFilters = (0, react.useDeferredValue)(filters);
216
+ const filtered = (0, react.useMemo)(() => require_model.filterJobs(jobs, deferredFilters, base), [
217
+ jobs,
218
+ deferredFilters,
219
+ base
220
+ ]);
221
+ (0, react.useEffect)(() => {
222
+ const last = Math.max(1, Math.ceil(filtered.length / pageSize));
223
+ if (page > last) setPage(last);
224
+ }, [
225
+ filtered.length,
226
+ page,
227
+ pageSize
228
+ ]);
229
+ const updateFilter = (patch) => {
230
+ setFilters((previous) => Object.keys(patch).every((key) => previous[key] === patch[key]) ? previous : require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, previous), patch));
231
+ setPage(1);
232
+ };
233
+ const columns = [
234
+ {
235
+ key: "code",
236
+ title: getText("pisell2.panpacific.task.code"),
237
+ width: 230,
238
+ render: (_, job) => /* @__PURE__ */ react.default.createElement(antd.Button, {
239
+ type: "link",
240
+ className: "pp-task-code-link",
241
+ onClick: () => openJob(job)
242
+ }, job.job_number)
243
+ },
244
+ {
245
+ key: "supplier",
246
+ title: getText("pisell2.panpacific.task.supplier"),
247
+ width: 210,
248
+ render: (_, job) => require_model.companyName(job) || "—"
249
+ },
250
+ {
251
+ key: "schedule",
252
+ title: getText("pisell2.panpacific.task.schedule"),
253
+ width: 310,
254
+ render: (_, job) => `${require_model.scheduleText(job)} · ${getText("pisell2.panpacific.task.due")} ${require_model.dateText(job.due_date)}`
255
+ },
256
+ {
257
+ key: "due",
258
+ title: getText("pisell2.panpacific.task.due"),
259
+ width: 130,
260
+ render: (_, job) => require_model.dateText(job.due_date) || "—"
261
+ },
262
+ {
263
+ key: "status",
264
+ title: getText("pisell2.panpacific.task.status"),
265
+ width: 140,
266
+ render: (_, job) => /* @__PURE__ */ react.default.createElement(require_JobStatus.JobStatus, {
267
+ job,
268
+ getText
269
+ })
270
+ },
271
+ {
272
+ key: "items",
273
+ title: getText("pisell2.panpacific.task.items"),
274
+ width: 90,
275
+ render: (_, job) => {
276
+ var _job$job_materials$fi, _job$job_materials;
277
+ return (_job$job_materials$fi = (_job$job_materials = job.job_materials) === null || _job$job_materials === void 0 ? void 0 : _job$job_materials.filter((row) => row.deleted_at == null).length) !== null && _job$job_materials$fi !== void 0 ? _job$job_materials$fi : "—";
278
+ }
279
+ },
280
+ {
281
+ key: "payment",
282
+ title: getText("pisell2.panpacific.task.payment"),
283
+ width: 170,
284
+ render: (_, job) => [require_model.paymentTerm(job, base), job.payment_term_days != null ? `${job.payment_term_days} ${getText("pisell2.panpacific.task.dayUnit")}` : ""].filter(Boolean).join(" · ") || "—"
285
+ },
286
+ {
287
+ key: "actions",
288
+ fixed: "right",
289
+ title: getText("pisell2.panpacific.task.actions"),
290
+ width: 260,
291
+ render: (_, job) => /* @__PURE__ */ react.default.createElement("div", {
292
+ className: "pp-task-row-actions",
293
+ onClick: (event) => event.stopPropagation()
294
+ }, /* @__PURE__ */ react.default.createElement(antd.Button, {
295
+ size: "small",
296
+ onClick: () => openJob(job)
297
+ }, getText("pisell2.panpacific.task.view")), /* @__PURE__ */ react.default.createElement(antd.Button, {
298
+ size: "small",
299
+ onClick: () => openJob(job, true)
300
+ }, getText("pisell2.panpacific.task.edit")), /* @__PURE__ */ react.default.createElement(antd.Button, {
301
+ size: "small",
302
+ disabled: job.status === "cancel" || busyId != null,
303
+ onClick: () => cancel(job)
304
+ }, getText("pisell2.panpacific.task.cancelJob")), /* @__PURE__ */ react.default.createElement(antd.Button, {
305
+ size: "small",
306
+ danger: true,
307
+ disabled: busyId != null,
308
+ onClick: () => remove(job)
309
+ }, getText("pisell2.panpacific.task.remove")))
310
+ }
311
+ ];
312
+ const selectedJobs = (0, react.useMemo)(() => require_model.jobsOnDate(jobs, selectedDate, period), [
313
+ jobs,
314
+ selectedDate,
315
+ period
316
+ ]);
317
+ const items = (0, react.useMemo)(() => require_model.calendarItems(jobs), [jobs]);
318
+ const ganttStart = viewport.mode === "month" ? viewport.month + "-01" : viewport.range.start;
319
+ const ganttEnd = viewport.mode === "month" ? (0, dayjs.default)(ganttStart).add(1, "month").format("YYYY-MM-DD") : viewport.range.endExclusive;
320
+ const ganttItems = (0, react.useMemo)(() => require_model.calendarItems(require_model.filterJobs(jobs, { status: ganttStatus }, base)).filter((item) => item.range.start < ganttEnd && item.range.endExclusive > ganttStart), [
321
+ jobs,
322
+ ganttStatus,
323
+ base,
324
+ ganttStart,
325
+ ganttEnd
326
+ ]);
327
+ const calendar = /* @__PURE__ */ react.default.createElement(react.default.Fragment, null, /* @__PURE__ */ react.default.createElement(require_JobStatus.StatusLegend, { getText }), /* @__PURE__ */ react.default.createElement("div", { className: "pp-task-calendar-layout" }, /* @__PURE__ */ react.default.createElement("div", { className: "pp-task-calendar-main" }, /* @__PURE__ */ react.default.createElement(_pisell_materials.PisellCalendar, {
328
+ items,
329
+ today: require_model.dateText((0, dayjs.default)()),
330
+ month,
331
+ onMonthChange: setMonth,
332
+ selectedDate,
333
+ onSelectedDateChange: setSelectedDate,
334
+ displayMode: period ? "range" : "custom-date",
335
+ getDisplayDate: (item) => {
336
+ var _item$data;
337
+ return require_model.dateText((_item$data = item.data) === null || _item$data === void 0 ? void 0 : _item$data.due_date);
338
+ },
339
+ loading,
340
+ interaction: { move: true },
341
+ moveAnchor: "grabbed-date",
342
+ canStartInteraction: () => ({ allowed: !writing.current }),
343
+ onRequestChange: requestDates,
344
+ onChangeCommitted: (change) => setSelectedDate(change.target.date),
345
+ onItemClick: ({ item }) => item.data && openJob(item.data),
346
+ onDateDoubleClick: ({ date }) => {
347
+ setSelectedDate(date);
348
+ openCreate(require_model.draftFor(void 0, date));
349
+ },
350
+ selectedItemId: drawer && String(drawer.id),
351
+ density: "compact",
352
+ maxEventsPerDay: 4,
353
+ classNames: { overflowPanel: "pp-task-calendar-popup" },
354
+ locale,
355
+ toolbarExtra: /* @__PURE__ */ react.default.createElement("label", { className: "pp-task-period" }, /* @__PURE__ */ react.default.createElement(antd.Switch, {
356
+ size: "small",
357
+ checked: period,
358
+ onChange: setPeriod
359
+ }), getText("pisell2.panpacific.task.period")),
360
+ styles: { event: (ctx) => require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, require_model.jobStyle((ctx === null || ctx === void 0 ? void 0 : ctx.item.data) || {})), (ctx === null || ctx === void 0 ? void 0 : ctx.item.id) === hoveredJob ? {
361
+ outline: "2px solid #634db3",
362
+ outlineOffset: "-2px"
363
+ } : {}) },
364
+ renderEventContent: ({ item }) => /* @__PURE__ */ react.default.createElement("span", { className: "pp-task-event-content" }, /* @__PURE__ */ react.default.createElement("span", { title: item.title }, item.title), require_model.hasInvoice(item.data || {}) && /* @__PURE__ */ react.default.createElement(require_JobStatus.InvoiceMark, { getText }))
365
+ })), /* @__PURE__ */ react.default.createElement("aside", { className: "pp-task-calendar-side" }, /* @__PURE__ */ react.default.createElement("h2", null, selectedDate), /* @__PURE__ */ react.default.createElement("p", null, selectedJobs.length, " ", getText("pisell2.panpacific.task.job")), /* @__PURE__ */ react.default.createElement(antd.Button, {
366
+ block: true,
367
+ type: "primary",
368
+ onClick: () => openCreate()
369
+ }, "+ ", getText("pisell2.panpacific.task.createJob")), /* @__PURE__ */ react.default.createElement("div", {
370
+ className: "pp-task-job-cards pp-job-list",
371
+ role: "list"
372
+ }, selectedJobs.length ? selectedJobs.map((job) => /* @__PURE__ */ react.default.createElement("div", {
373
+ role: "listitem",
374
+ key: String(job.id)
375
+ }, /* @__PURE__ */ react.default.createElement(require_JobCard.JobCard, {
376
+ job,
377
+ getText,
378
+ selected: String(drawer === null || drawer === void 0 ? void 0 : drawer.id) === String(job.id),
379
+ onOpen: () => openJob(job),
380
+ onHover: setHoveredJob
381
+ }))) : /* @__PURE__ */ react.default.createElement(antd.Empty, {
382
+ image: antd.Empty.PRESENTED_IMAGE_SIMPLE,
383
+ description: getText("pisell2.panpacific.task.noJobs")
384
+ })))));
385
+ const timeline = /* @__PURE__ */ react.default.createElement(react.default.Fragment, null, /* @__PURE__ */ react.default.createElement(require_JobStatus.StatusLegend, { getText }), /* @__PURE__ */ react.default.createElement(_pisell_materials.PisellGantt, {
386
+ items: ganttItems,
387
+ today: require_model.dateText((0, dayjs.default)()),
388
+ viewport,
389
+ onViewportChange: setViewport,
390
+ loading,
391
+ locale,
392
+ rowHeight: 60,
393
+ getGroupKey: (item) => {
394
+ var _item$data2;
395
+ return ((_item$data2 = item.data) === null || _item$data2 === void 0 ? void 0 : _item$data2.status) || "create";
396
+ },
397
+ groups: require_model.statuses.filter((id) => ganttItems.some((item) => item.data.status === id)).map((id) => ({
398
+ id,
399
+ title: getText(`pisell2.panpacific.task.${id}`)
400
+ })),
401
+ collapsedGroupIds: collapsed,
402
+ onCollapsedGroupIdsChange: setCollapsed,
403
+ toolbarExtra: /* @__PURE__ */ react.default.createElement("label", { className: "pp-task-timeline-filter" }, /* @__PURE__ */ react.default.createElement("span", null, getText("pisell2.panpacific.task.status")), statusSelect(ganttStatus, setGanttStatus)),
404
+ selectedItemId: drawer && String(drawer.id),
405
+ onItemClick: ({ item }) => item.data && openJob(item.data),
406
+ interaction: {
407
+ move: true,
408
+ resizeStart: true,
409
+ resizeEnd: true
410
+ },
411
+ canStartInteraction: () => ({ allowed: !writing.current }),
412
+ onRequestChange: requestDates,
413
+ renderRowLabel: ({ item }) => /* @__PURE__ */ react.default.createElement(antd.Button, {
414
+ type: "text",
415
+ onClick: () => item.data && openJob(item.data)
416
+ }, item.title),
417
+ styles: { taskBar: (ctx) => require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, require_model.jobStyle((ctx === null || ctx === void 0 ? void 0 : ctx.item.data) || {})), {}, { border: "1px solid #d1d5db" }) },
418
+ renderTaskContent: ({ item }) => {
419
+ var _item$data3, _item$data4;
420
+ return /* @__PURE__ */ react.default.createElement("div", { className: "pp-task-gantt-content" }, /* @__PURE__ */ react.default.createElement("strong", null, item.title), /* @__PURE__ */ react.default.createElement("small", null, ((_item$data3 = item.data) === null || _item$data3 === void 0 ? void 0 : _item$data3.company_contact) || "—", " · ", require_model.dateText((_item$data4 = item.data) === null || _item$data4 === void 0 ? void 0 : _item$data4.due_date), require_model.hasInvoice(item.data || {}) && /* @__PURE__ */ react.default.createElement(require_JobStatus.InvoiceMark, { getText })));
421
+ }
422
+ }));
423
+ const list = /* @__PURE__ */ react.default.createElement(react.default.Fragment, null, /* @__PURE__ */ react.default.createElement("div", { className: "pp-task-filters" }, /* @__PURE__ */ react.default.createElement("label", null, /* @__PURE__ */ react.default.createElement("span", null, getText("pisell2.panpacific.task.search")), /* @__PURE__ */ react.default.createElement(antd.Input, {
424
+ allowClear: true,
425
+ placeholder: getText("pisell2.panpacific.task.searchHint"),
426
+ value: filters.search,
427
+ "aria-label": getText("pisell2.panpacific.task.search"),
428
+ onInput: (event) => updateFilter({ search: event.currentTarget.value }),
429
+ onChange: (event) => updateFilter({ search: event.target.value })
430
+ })), /* @__PURE__ */ react.default.createElement("label", null, /* @__PURE__ */ react.default.createElement("span", null, getText("pisell2.panpacific.task.due")), /* @__PURE__ */ react.default.createElement(antd.DatePicker, {
431
+ allowClear: true,
432
+ placeholder: getText("pisell2.panpacific.task.allDates"),
433
+ value: filters.due ? (0, dayjs.default)(filters.due) : null,
434
+ onChange: (value) => updateFilter({ due: require_model.dateText(value) })
435
+ })), /* @__PURE__ */ react.default.createElement("label", null, /* @__PURE__ */ react.default.createElement("span", null, getText("pisell2.panpacific.task.status")), statusSelect(filters.status, (status) => updateFilter({ status }))), /* @__PURE__ */ react.default.createElement(antd.Button, { onClick: () => {
436
+ setFilters({
437
+ search: "",
438
+ due: ""
439
+ });
440
+ setPage(1);
441
+ } }, getText("pisell2.panpacific.task.reset")), /* @__PURE__ */ react.default.createElement(antd.Button, {
442
+ type: "primary",
443
+ onClick: () => openCreate()
444
+ }, "+ ", getText("pisell2.panpacific.task.createJob"))), /* @__PURE__ */ react.default.createElement(antd.Table, {
445
+ size: "small",
446
+ rowKey: (job) => String(job.id),
447
+ columns,
448
+ dataSource: filtered,
449
+ loading,
450
+ scroll: { x: 1640 },
451
+ locale: { emptyText: getText("pisell2.panpacific.task.noJobs") },
452
+ pagination: {
453
+ current: page,
454
+ pageSize,
455
+ showSizeChanger: true,
456
+ onChange: (next, size) => {
457
+ setPage(size !== pageSize ? 1 : next);
458
+ setPageSize(size);
459
+ }
460
+ },
461
+ onRow: (job) => ({ onClick: (event) => {
462
+ if (!event.target.closest("button, a, input")) openJob(job);
463
+ } })
464
+ }));
465
+ return /* @__PURE__ */ react.default.createElement("div", {
466
+ className: ["pp-task", props.className].filter(Boolean).join(" "),
467
+ style: props.style
468
+ }, modalContext, /* @__PURE__ */ react.default.createElement("header", { className: "pp-task-heading" }, /* @__PURE__ */ react.default.createElement("h1", null, getText("pisell2.panpacific.task.job"))), /* @__PURE__ */ react.default.createElement(antd.Tabs, {
469
+ activeKey: tab,
470
+ onChange: (value) => setTab(value),
471
+ destroyInactiveTabPane: true,
472
+ items: [
473
+ {
474
+ key: "calendar",
475
+ label: getText("pisell2.panpacific.task.calendar"),
476
+ children: calendar
477
+ },
478
+ {
479
+ key: "timeline",
480
+ label: getText("pisell2.panpacific.task.timeline"),
481
+ children: timeline
482
+ },
483
+ {
484
+ key: "list",
485
+ label: getText("pisell2.panpacific.task.list"),
486
+ children: list
487
+ }
488
+ ]
489
+ }), /* @__PURE__ */ react.default.createElement(antd.Modal, {
490
+ open: !!draft,
491
+ title: getText("pisell2.panpacific.task.createJob"),
492
+ width: "min(1100px, 96vw)",
493
+ wrapClassName: "pp-task-overlay pp-task-modal",
494
+ footer: null,
495
+ destroyOnClose: true,
496
+ maskClosable: false,
497
+ onCancel: () => {
498
+ var _editorRef$current;
499
+ return (_editorRef$current = editorRef.current) === null || _editorRef$current === void 0 ? void 0 : _editorRef$current.close();
500
+ },
501
+ bodyStyle: {
502
+ maxHeight: "76vh",
503
+ overflowY: "auto",
504
+ position: "relative"
505
+ }
506
+ }, draft && /* @__PURE__ */ react.default.createElement(require_JobForm.JobForm, {
507
+ key: editorKey,
508
+ ref: editorRef,
509
+ initial: draft,
510
+ jobs,
511
+ base,
512
+ request: client,
513
+ getText,
514
+ confirmDiscard: () => confirm("discardConfirm"),
515
+ onCancel: () => {
516
+ setDraft(void 0);
517
+ load();
518
+ },
519
+ onSaved: (id, values) => {
520
+ var _jobRange;
521
+ const date = period ? (_jobRange = require_model.jobRange(values)) === null || _jobRange === void 0 ? void 0 : _jobRange.start : require_model.dateText(values.due_date);
522
+ if (date) {
523
+ setSelectedDate(date);
524
+ setMonth(date.slice(0, 7));
525
+ setViewport({
526
+ mode: "month",
527
+ month: date.slice(0, 7)
528
+ });
529
+ }
530
+ setDraft(void 0);
531
+ changed(id);
532
+ }
533
+ })), drawer && /* @__PURE__ */ react.default.createElement(require_JobDrawer.JobDrawer, {
534
+ key: `${drawer.id}:${!!drawer.edit}`,
535
+ id: drawer.id,
536
+ startEditing: drawer.edit,
537
+ jobs,
538
+ base,
539
+ request: client,
540
+ getText,
541
+ uploadPhoto,
542
+ confirm,
543
+ onClose: () => {
544
+ setDrawer(void 0);
545
+ load();
546
+ },
547
+ onChanged: changed,
548
+ onDuplicate: (initial) => {
549
+ setDrawer(void 0);
550
+ openCreate(initial);
551
+ }
552
+ }));
553
+ }
554
+ //#endregion
555
+ exports.default = PanpacificTask;
@@ -0,0 +1,39 @@
1
+ const require_runtime = require("../../_virtual/_rolldown/runtime.js");
2
+ const require_attachments = require("./attachments.js");
3
+ let react = require("react");
4
+ react = require_runtime.__toESM(react);
5
+ let antd = require("antd");
6
+ let _ant_design_icons = require("@ant-design/icons");
7
+ //#region src/plus/panpacificTask/PhotoPreview.tsx
8
+ function PhotoPreview({ value, label, compact, disabled, getText, onRemove }) {
9
+ const [visible, setVisible] = (0, react.useState)(false);
10
+ const images = require_attachments.attachments(value);
11
+ const remove = (index) => {
12
+ if (disabled || !onRemove) return;
13
+ setVisible(false);
14
+ onRemove(index);
15
+ };
16
+ const removeLabel = getText("pisell2.panpacific.task.removePhoto");
17
+ return /* @__PURE__ */ react.default.createElement(antd.Image.PreviewGroup, { preview: {
18
+ visible,
19
+ onVisibleChange: setVisible,
20
+ rootClassName: "pp-task-photo-preview",
21
+ toolbarRender: (toolbar, { current }) => /* @__PURE__ */ react.default.createElement(react.default.Fragment, null, toolbar, onRemove && /* @__PURE__ */ react.default.createElement(antd.Button, {
22
+ className: "pp-task-photo-preview-remove",
23
+ danger: true,
24
+ icon: /* @__PURE__ */ react.default.createElement(_ant_design_icons.DeleteOutlined, null),
25
+ disabled,
26
+ onClick: () => remove(current)
27
+ }, removeLabel))
28
+ } }, images.map((item, index) => /* @__PURE__ */ react.default.createElement("figure", {
29
+ className: "pp-task-photo",
30
+ key: `${item.url}-${index}`
31
+ }, /* @__PURE__ */ react.default.createElement(antd.Image, {
32
+ width: compact ? 38 : 92,
33
+ height: compact ? 38 : 72,
34
+ src: item.url,
35
+ alt: item.name || label || getText("pisell2.panpacific.task.photo")
36
+ }), !compact && /* @__PURE__ */ react.default.createElement("figcaption", null, label || item.name))));
37
+ }
38
+ //#endregion
39
+ exports.PhotoPreview = PhotoPreview;