imean-service-engine-htmx-plugin 2.10.1 → 2.11.1
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/index.d.mts +78 -31
- package/dist/index.d.ts +78 -31
- package/dist/index.js +475 -212
- package/dist/index.mjs +475 -212
- package/docs/filter-schema-type-conversion.md +405 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -878,6 +878,22 @@ function convertBoolean(value) {
|
|
|
878
878
|
}
|
|
879
879
|
return value;
|
|
880
880
|
}
|
|
881
|
+
function convertDate(value) {
|
|
882
|
+
if (typeof value === "string") {
|
|
883
|
+
const trimmed = value.trim();
|
|
884
|
+
if (trimmed !== "") {
|
|
885
|
+
const dateValue = new Date(trimmed);
|
|
886
|
+
if (!isNaN(dateValue.getTime())) {
|
|
887
|
+
return dateValue;
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
return value;
|
|
891
|
+
}
|
|
892
|
+
if (value instanceof Date) {
|
|
893
|
+
return value;
|
|
894
|
+
}
|
|
895
|
+
return value;
|
|
896
|
+
}
|
|
881
897
|
function processArrayElement(item, elementType) {
|
|
882
898
|
if (typeof item === "object" && item !== null && !Array.isArray(item)) {
|
|
883
899
|
const { typeName } = resolveZodType(elementType);
|
|
@@ -997,6 +1013,9 @@ function preprocessFormData(data, zodSchema) {
|
|
|
997
1013
|
case "boolean":
|
|
998
1014
|
processed[fieldName] = convertBoolean(value);
|
|
999
1015
|
break;
|
|
1016
|
+
case "date":
|
|
1017
|
+
processed[fieldName] = convertDate(value);
|
|
1018
|
+
break;
|
|
1000
1019
|
case "array":
|
|
1001
1020
|
processed[fieldName] = processArrayType(value, actualSchema);
|
|
1002
1021
|
break;
|
|
@@ -1019,6 +1038,8 @@ function convertValueByType(value, schema) {
|
|
|
1019
1038
|
return convertNumber(value);
|
|
1020
1039
|
case "boolean":
|
|
1021
1040
|
return convertBoolean(value);
|
|
1041
|
+
case "date":
|
|
1042
|
+
return convertDate(value);
|
|
1022
1043
|
default:
|
|
1023
1044
|
return value;
|
|
1024
1045
|
}
|
|
@@ -1244,6 +1265,11 @@ var BaseModelFeature = class extends BaseFeature {
|
|
|
1244
1265
|
};
|
|
1245
1266
|
var BaseFormFeature = class extends BaseModelFeature {
|
|
1246
1267
|
groups;
|
|
1268
|
+
options;
|
|
1269
|
+
constructor(options) {
|
|
1270
|
+
super(options);
|
|
1271
|
+
this.options = options;
|
|
1272
|
+
}
|
|
1247
1273
|
/**
|
|
1248
1274
|
* 设置标题和描述到 context
|
|
1249
1275
|
*/
|
|
@@ -1316,13 +1342,13 @@ var BaseFormFeature = class extends BaseModelFeature {
|
|
|
1316
1342
|
* 处理请求
|
|
1317
1343
|
*/
|
|
1318
1344
|
async handler(context) {
|
|
1319
|
-
context.actions =
|
|
1345
|
+
context.actions = [
|
|
1346
|
+
...this.options.actions ?? [],
|
|
1347
|
+
...this.getDefaultActions(context)
|
|
1348
|
+
];
|
|
1320
1349
|
if (context.ctx.req.method === "GET") {
|
|
1321
1350
|
const initialData = await this.getInitialData(context);
|
|
1322
|
-
await this.setTitleAndDescription(
|
|
1323
|
-
context,
|
|
1324
|
-
initialData
|
|
1325
|
-
);
|
|
1351
|
+
await this.setTitleAndDescription(context, initialData);
|
|
1326
1352
|
return this.renderForm(context, initialData);
|
|
1327
1353
|
}
|
|
1328
1354
|
const formData = preprocessFormData(context.body, this.schema);
|
|
@@ -1424,22 +1450,21 @@ var BaseFormFeature = class extends BaseModelFeature {
|
|
|
1424
1450
|
|
|
1425
1451
|
// src/features/default-create-feature.tsx
|
|
1426
1452
|
var DefaultCreateFeature = class extends BaseFormFeature {
|
|
1427
|
-
|
|
1453
|
+
createItem;
|
|
1454
|
+
constructor(createOptions) {
|
|
1428
1455
|
super({
|
|
1429
|
-
...
|
|
1456
|
+
...createOptions,
|
|
1430
1457
|
name: "create",
|
|
1431
1458
|
type: "create",
|
|
1432
1459
|
routes: [
|
|
1433
1460
|
{ method: "get", path: "/new" },
|
|
1434
1461
|
{ method: "post", path: "" }
|
|
1435
1462
|
],
|
|
1436
|
-
permission:
|
|
1463
|
+
permission: createOptions.permission || "create"
|
|
1437
1464
|
});
|
|
1438
|
-
this.
|
|
1439
|
-
this.
|
|
1440
|
-
this.groups = options.groups;
|
|
1465
|
+
this.createItem = createOptions.createItem;
|
|
1466
|
+
this.groups = createOptions.groups;
|
|
1441
1467
|
}
|
|
1442
|
-
createItem;
|
|
1443
1468
|
getFormAction() {
|
|
1444
1469
|
return "create";
|
|
1445
1470
|
}
|
|
@@ -1964,24 +1989,23 @@ var DefaultDetailFeature = class extends BaseModelFeature {
|
|
|
1964
1989
|
|
|
1965
1990
|
// src/features/default-edit-feature.tsx
|
|
1966
1991
|
var DefaultEditFeature = class extends BaseFormFeature {
|
|
1967
|
-
|
|
1992
|
+
getItem;
|
|
1993
|
+
updateItem;
|
|
1994
|
+
constructor(editOptions) {
|
|
1968
1995
|
super({
|
|
1969
|
-
...
|
|
1996
|
+
...editOptions,
|
|
1970
1997
|
name: "edit",
|
|
1971
1998
|
type: "edit",
|
|
1972
1999
|
routes: [
|
|
1973
2000
|
{ method: "get", path: "/edit/:id" },
|
|
1974
2001
|
{ method: "put", path: "/:id" }
|
|
1975
2002
|
],
|
|
1976
|
-
permission:
|
|
2003
|
+
permission: editOptions.permission || "edit"
|
|
1977
2004
|
});
|
|
1978
|
-
this.
|
|
1979
|
-
this.
|
|
1980
|
-
this.
|
|
1981
|
-
this.groups = options.groups;
|
|
2005
|
+
this.getItem = editOptions.getItem;
|
|
2006
|
+
this.updateItem = editOptions.updateItem;
|
|
2007
|
+
this.groups = editOptions.groups;
|
|
1982
2008
|
}
|
|
1983
|
-
getItem;
|
|
1984
|
-
updateItem;
|
|
1985
2009
|
getFormAction() {
|
|
1986
2010
|
return "edit";
|
|
1987
2011
|
}
|
|
@@ -2023,154 +2047,315 @@ var DefaultEditFeature = class extends BaseFormFeature {
|
|
|
2023
2047
|
return void 0;
|
|
2024
2048
|
}
|
|
2025
2049
|
};
|
|
2026
|
-
function
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
const value = currentFilters[field.name];
|
|
2034
|
-
if (value === null || value === void 0 || value === "") {
|
|
2035
|
-
return "";
|
|
2050
|
+
function SubmitButton() {
|
|
2051
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2052
|
+
"button",
|
|
2053
|
+
{
|
|
2054
|
+
type: "submit",
|
|
2055
|
+
className: "px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors font-medium text-sm",
|
|
2056
|
+
children: "\u7B5B\u9009"
|
|
2036
2057
|
}
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2058
|
+
);
|
|
2059
|
+
}
|
|
2060
|
+
function ResetButton({ listPath }) {
|
|
2061
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2062
|
+
"a",
|
|
2063
|
+
{
|
|
2064
|
+
href: listPath,
|
|
2065
|
+
"hx-get": listPath,
|
|
2066
|
+
className: "px-4 py-2 bg-gray-200 text-gray-800 rounded-lg hover:bg-gray-300 transition-colors font-medium text-sm",
|
|
2067
|
+
children: "\u91CD\u7F6E"
|
|
2043
2068
|
}
|
|
2044
|
-
|
|
2045
|
-
|
|
2069
|
+
);
|
|
2070
|
+
}
|
|
2071
|
+
function AddConditionButton() {
|
|
2072
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2073
|
+
"button",
|
|
2074
|
+
{
|
|
2075
|
+
type: "button",
|
|
2076
|
+
"x-show": "getAvailableFields().length > 0",
|
|
2077
|
+
className: "px-4 py-2 bg-gray-100 text-gray-700 rounded-lg hover:bg-gray-200 transition-colors font-medium text-sm flex items-center gap-2",
|
|
2078
|
+
"x-on:click": "showFieldSelector=!showFieldSelector",
|
|
2079
|
+
children: [
|
|
2080
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2081
|
+
"svg",
|
|
2082
|
+
{
|
|
2083
|
+
className: "w-4 h-4",
|
|
2084
|
+
fill: "none",
|
|
2085
|
+
stroke: "currentColor",
|
|
2086
|
+
viewBox: "0 0 24 24",
|
|
2087
|
+
"aria-hidden": "true",
|
|
2088
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2089
|
+
"path",
|
|
2090
|
+
{
|
|
2091
|
+
strokeLinecap: "round",
|
|
2092
|
+
strokeLinejoin: "round",
|
|
2093
|
+
strokeWidth: 2,
|
|
2094
|
+
d: "M12 4v16m8-8H4"
|
|
2095
|
+
}
|
|
2096
|
+
)
|
|
2097
|
+
}
|
|
2098
|
+
),
|
|
2099
|
+
"\u6DFB\u52A0\u7B5B\u9009\u6761\u4EF6"
|
|
2100
|
+
]
|
|
2101
|
+
}
|
|
2102
|
+
);
|
|
2103
|
+
}
|
|
2104
|
+
function FieldInput() {
|
|
2105
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2106
|
+
/* @__PURE__ */ jsxRuntime.jsx("template", { "x-if": "getField(condition.fieldName)?.type === 'checkbox'", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2107
|
+
"select",
|
|
2108
|
+
{
|
|
2109
|
+
className: "w-full h-full px-3 py-2 border-0 rounded-none focus:outline-none focus:ring-2 focus:ring-blue-500 bg-white text-sm appearance-none",
|
|
2110
|
+
"x-bind:name": "condition.fieldName",
|
|
2111
|
+
"x-model": "condition.value",
|
|
2112
|
+
autocomplete: "off",
|
|
2113
|
+
children: [
|
|
2114
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "true", children: "\u662F" }),
|
|
2115
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "false", children: "\u5426" })
|
|
2116
|
+
]
|
|
2117
|
+
}
|
|
2118
|
+
) }),
|
|
2119
|
+
/* @__PURE__ */ jsxRuntime.jsx("template", { "x-if": "getField(condition.fieldName)?.type === 'select' && getField(condition.fieldName)?.options", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2120
|
+
"select",
|
|
2121
|
+
{
|
|
2122
|
+
className: "w-full h-full px-3 py-2 border-0 rounded-none focus:outline-none focus:ring-2 focus:ring-blue-500 bg-white text-sm appearance-none",
|
|
2123
|
+
"x-bind:name": "condition.fieldName",
|
|
2124
|
+
"x-model": "condition.value",
|
|
2125
|
+
autocomplete: "off",
|
|
2126
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2127
|
+
"template",
|
|
2128
|
+
{
|
|
2129
|
+
"x-for": "option in getField(condition.fieldName)?.options",
|
|
2130
|
+
"x-bind:key": "option.value",
|
|
2131
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2132
|
+
"option",
|
|
2133
|
+
{
|
|
2134
|
+
"x-bind:value": "String(option.value)",
|
|
2135
|
+
"x-text": "option.label"
|
|
2136
|
+
}
|
|
2137
|
+
)
|
|
2138
|
+
}
|
|
2139
|
+
)
|
|
2140
|
+
}
|
|
2141
|
+
) }),
|
|
2142
|
+
/* @__PURE__ */ jsxRuntime.jsx("template", { "x-if": "getField(condition.fieldName)?.type === 'date'", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2143
|
+
"input",
|
|
2144
|
+
{
|
|
2145
|
+
type: "date",
|
|
2146
|
+
className: "w-full h-full px-3 py-2 border-0 rounded-none focus:outline-none focus:ring-2 focus:ring-blue-500 bg-white text-sm",
|
|
2147
|
+
"x-bind:name": "condition.fieldName",
|
|
2148
|
+
"x-model": "condition.value",
|
|
2149
|
+
autocomplete: "off"
|
|
2150
|
+
}
|
|
2151
|
+
) }),
|
|
2152
|
+
/* @__PURE__ */ jsxRuntime.jsx("template", { "x-if": "getField(condition.fieldName)?.type === 'number'", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2153
|
+
"input",
|
|
2154
|
+
{
|
|
2155
|
+
type: "number",
|
|
2156
|
+
className: "w-full h-full px-3 py-2 border-0 rounded-none focus:outline-none focus:ring-2 focus:ring-blue-500 bg-white text-sm",
|
|
2157
|
+
"x-bind:name": "condition.fieldName",
|
|
2158
|
+
"x-bind:placeholder": "getField(condition.fieldName)?.placeholder || '\u8BF7\u8F93\u5165' + getField(condition.fieldName)?.label",
|
|
2159
|
+
"x-bind:step": "getField(condition.fieldName)?.step",
|
|
2160
|
+
"x-model": "condition.value",
|
|
2161
|
+
autocomplete: "off"
|
|
2162
|
+
}
|
|
2163
|
+
) }),
|
|
2164
|
+
/* @__PURE__ */ jsxRuntime.jsx("template", { "x-if": "getField(condition.fieldName)?.type === 'email'", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2165
|
+
"input",
|
|
2166
|
+
{
|
|
2167
|
+
type: "email",
|
|
2168
|
+
className: "w-full h-full px-3 py-2 border-0 rounded-none focus:outline-none focus:ring-2 focus:ring-blue-500 bg-white text-sm",
|
|
2169
|
+
"x-bind:name": "condition.fieldName",
|
|
2170
|
+
"x-bind:placeholder": "getField(condition.fieldName)?.placeholder || '\u8BF7\u8F93\u5165' + getField(condition.fieldName)?.label",
|
|
2171
|
+
"x-model": "condition.value",
|
|
2172
|
+
autocomplete: "off"
|
|
2173
|
+
}
|
|
2174
|
+
) }),
|
|
2175
|
+
/* @__PURE__ */ jsxRuntime.jsx("template", { "x-if": "!['checkbox', 'select', 'date', 'number', 'email'].includes(getField(condition.fieldName)?.type || '')", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2176
|
+
"input",
|
|
2177
|
+
{
|
|
2178
|
+
type: "text",
|
|
2179
|
+
className: "w-full h-full px-3 py-2 border-0 rounded-none focus:outline-none focus:ring-2 focus:ring-blue-500 bg-white text-sm",
|
|
2180
|
+
"x-bind:name": "condition.fieldName",
|
|
2181
|
+
"x-bind:placeholder": "getField(condition.fieldName)?.placeholder || '\u8BF7\u8F93\u5165' + getField(condition.fieldName)?.label",
|
|
2182
|
+
"x-model": "condition.value",
|
|
2183
|
+
autocomplete: "off"
|
|
2184
|
+
}
|
|
2185
|
+
) })
|
|
2186
|
+
] });
|
|
2187
|
+
}
|
|
2188
|
+
function FieldSelectorDropdown({ fields }) {
|
|
2189
|
+
const transitionProps = {
|
|
2190
|
+
"x-show": "showFieldSelector",
|
|
2191
|
+
"x-transition:enter": "transition ease-out duration-200",
|
|
2192
|
+
"x-transition:enter-start": "opacity-0 scale-95",
|
|
2193
|
+
"x-transition:enter-end": "opacity-100 scale-100",
|
|
2194
|
+
"x-transition:leave": "transition ease-in duration-150",
|
|
2195
|
+
"x-transition:leave-start": "opacity-100 scale-100",
|
|
2196
|
+
"x-transition:leave-end": "opacity-0 scale-95"
|
|
2197
|
+
};
|
|
2198
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2199
|
+
"div",
|
|
2200
|
+
{
|
|
2201
|
+
className: "absolute top-full left-0 mt-2 w-64 bg-white border border-gray-200 rounded-lg shadow-lg z-10",
|
|
2202
|
+
...transitionProps,
|
|
2203
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-3", children: [
|
|
2204
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "block text-xs font-semibold text-gray-600 mb-2", children: "\u9009\u62E9\u7B5B\u9009\u5B57\u6BB5" }),
|
|
2205
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-1 max-h-64 overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2206
|
+
"template",
|
|
2207
|
+
{
|
|
2208
|
+
"x-for": "field in getAvailableFields()",
|
|
2209
|
+
"x-bind:key": "field.name",
|
|
2210
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2211
|
+
"button",
|
|
2212
|
+
{
|
|
2213
|
+
type: "button",
|
|
2214
|
+
className: "w-full text-left px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 rounded-lg transition-colors",
|
|
2215
|
+
"x-on:click": "onFieldSelected(field.name)",
|
|
2216
|
+
"x-text": "field.label"
|
|
2217
|
+
}
|
|
2218
|
+
)
|
|
2219
|
+
}
|
|
2220
|
+
) })
|
|
2221
|
+
] })
|
|
2222
|
+
}
|
|
2223
|
+
);
|
|
2224
|
+
}
|
|
2225
|
+
function FilterConditionItem({ children }) {
|
|
2226
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-[auto_1fr_auto] items-stretch h-10 bg-gray-50 rounded-lg border border-gray-200 overflow-hidden", children: [
|
|
2227
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2228
|
+
"label",
|
|
2229
|
+
{
|
|
2230
|
+
className: "px-3 flex items-center text-xs font-semibold text-gray-600 whitespace-nowrap",
|
|
2231
|
+
"x-text": "getFieldLabel(condition.fieldName)"
|
|
2232
|
+
}
|
|
2233
|
+
),
|
|
2234
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-full border-l border-r border-gray-300", children }),
|
|
2235
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2236
|
+
"button",
|
|
2237
|
+
{
|
|
2238
|
+
type: "button",
|
|
2239
|
+
className: "px-3 flex items-center justify-center text-gray-400 hover:text-red-600 hover:bg-red-50 transition-colors",
|
|
2240
|
+
"x-on:click": "removeCondition(condition.id)",
|
|
2241
|
+
title: "\u5220\u9664\u6B64\u7B5B\u9009\u6761\u4EF6",
|
|
2242
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2243
|
+
"svg",
|
|
2244
|
+
{
|
|
2245
|
+
className: "w-4 h-4",
|
|
2246
|
+
fill: "none",
|
|
2247
|
+
stroke: "currentColor",
|
|
2248
|
+
viewBox: "0 0 24 24",
|
|
2249
|
+
"aria-hidden": "true",
|
|
2250
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2251
|
+
"path",
|
|
2252
|
+
{
|
|
2253
|
+
strokeLinecap: "round",
|
|
2254
|
+
strokeLinejoin: "round",
|
|
2255
|
+
strokeWidth: 2,
|
|
2256
|
+
d: "M6 18L18 6M6 6l12 12"
|
|
2257
|
+
}
|
|
2258
|
+
)
|
|
2259
|
+
}
|
|
2260
|
+
)
|
|
2261
|
+
}
|
|
2262
|
+
)
|
|
2263
|
+
] });
|
|
2264
|
+
}
|
|
2265
|
+
function DynamicFilters(props) {
|
|
2266
|
+
const { fields, listPath, currentFilters = {} } = props;
|
|
2046
2267
|
if (fields.length === 0) {
|
|
2047
2268
|
return null;
|
|
2048
2269
|
}
|
|
2049
|
-
|
|
2270
|
+
const systemParams = /* @__PURE__ */ new Set(["page", "pageSize", "sortBy", "sortOrder"]);
|
|
2271
|
+
const initialConditions = [];
|
|
2272
|
+
for (const field of fields) {
|
|
2273
|
+
if (currentFilters.hasOwnProperty(field.name) && !systemParams.has(field.name)) {
|
|
2274
|
+
const value = currentFilters[field.name];
|
|
2275
|
+
initialConditions.push({
|
|
2276
|
+
id: `condition-${Date.now()}-${Math.random()}`,
|
|
2277
|
+
fieldName: field.name,
|
|
2278
|
+
value: value === null || value === void 0 ? "" : String(value)
|
|
2279
|
+
});
|
|
2280
|
+
}
|
|
2281
|
+
}
|
|
2282
|
+
const availableFields = fields.map((field) => ({
|
|
2283
|
+
name: field.name,
|
|
2284
|
+
label: field.label,
|
|
2285
|
+
type: field.type,
|
|
2286
|
+
options: field.options,
|
|
2287
|
+
step: field.step,
|
|
2288
|
+
placeholder: field.placeholder
|
|
2289
|
+
}));
|
|
2290
|
+
const escapedListPath = listPath.replace(/'/g, "\\'");
|
|
2291
|
+
const alpineData = `{
|
|
2292
|
+
conditions: ${JSON.stringify(initialConditions)},
|
|
2293
|
+
availableFields: ${JSON.stringify(availableFields)},
|
|
2294
|
+
showFieldSelector: false,
|
|
2295
|
+
listPath: '${escapedListPath}',
|
|
2296
|
+
|
|
2297
|
+
|
|
2298
|
+
// \u83B7\u53D6\u5B57\u6BB5\u5B9A\u4E49
|
|
2299
|
+
getField(fieldName) {
|
|
2300
|
+
return this.availableFields.find(f => f.name === fieldName);
|
|
2301
|
+
},
|
|
2302
|
+
|
|
2303
|
+
// \u83B7\u53D6\u5B57\u6BB5\u6807\u7B7E
|
|
2304
|
+
getFieldLabel(fieldName) {
|
|
2305
|
+
const field = this.getField(fieldName);
|
|
2306
|
+
return field ? field.label : fieldName;
|
|
2307
|
+
},
|
|
2308
|
+
|
|
2309
|
+
// \u68C0\u67E5\u5B57\u6BB5\u662F\u5426\u5DF2\u88AB\u4F7F\u7528
|
|
2310
|
+
isFieldUsed(fieldName) {
|
|
2311
|
+
return this.conditions.some(c => c.fieldName === fieldName);
|
|
2312
|
+
},
|
|
2313
|
+
|
|
2314
|
+
// \u83B7\u53D6\u6240\u6709\u53EF\u7528\u5B57\u6BB5\uFF08\u672A\u4F7F\u7528\u7684\u5B57\u6BB5\uFF09
|
|
2315
|
+
getAvailableFields() {
|
|
2316
|
+
return this.availableFields.filter(f => !this.isFieldUsed(f.name));
|
|
2317
|
+
},
|
|
2318
|
+
|
|
2319
|
+
// \u5220\u9664\u6761\u4EF6
|
|
2320
|
+
removeCondition(id) {
|
|
2321
|
+
this.conditions = this.conditions.filter(c => c.id !== id);
|
|
2322
|
+
},
|
|
2323
|
+
|
|
2324
|
+
// \u5B57\u6BB5\u9009\u62E9\u56DE\u8C03\uFF08\u4ECE\u6D6E\u5C42\u9009\u62E9\u5B57\u6BB5\u65F6\u8C03\u7528\uFF09
|
|
2325
|
+
onFieldSelected(fieldName) {
|
|
2326
|
+
// \u68C0\u67E5\u5B57\u6BB5\u662F\u5426\u53EF\u7528
|
|
2327
|
+
if (!this.isFieldUsed(fieldName)) {
|
|
2328
|
+
const newCondition = {
|
|
2329
|
+
id: 'condition-' + Date.now() + '-' + Math.random().toString(36).substr(2, 9),
|
|
2330
|
+
fieldName: fieldName,
|
|
2331
|
+
value: ''
|
|
2332
|
+
};
|
|
2333
|
+
setTimeout(() => {
|
|
2334
|
+
this.conditions.push(newCondition);
|
|
2335
|
+
}, 200);
|
|
2336
|
+
}
|
|
2337
|
+
this.showFieldSelector = false;
|
|
2338
|
+
}
|
|
2339
|
+
}`;
|
|
2340
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-white border border-gray-200 rounded-lg shadow-sm p-4 mb-6", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2050
2341
|
"form",
|
|
2051
2342
|
{
|
|
2052
2343
|
method: "get",
|
|
2053
2344
|
action: listPath,
|
|
2054
2345
|
"hx-get": listPath,
|
|
2055
|
-
className: "space-y-4",
|
|
2056
|
-
"data
|
|
2057
|
-
children: [
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
{
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
checked: getCheckboxValue(field),
|
|
2067
|
-
className: "w-4 h-4 text-blue-600 bg-white border-gray-300 rounded focus:ring-blue-500 focus:ring-2",
|
|
2068
|
-
"data-testid": `filter-checkbox-${field.name}`
|
|
2069
|
-
}
|
|
2070
|
-
),
|
|
2071
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2072
|
-
"label",
|
|
2073
|
-
{
|
|
2074
|
-
htmlFor: `filter-${field.name}`,
|
|
2075
|
-
className: "text-sm font-semibold text-gray-700 cursor-pointer",
|
|
2076
|
-
"data-testid": `filter-label-${field.name}`,
|
|
2077
|
-
children: field.label
|
|
2078
|
-
}
|
|
2079
|
-
)
|
|
2080
|
-
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2081
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2082
|
-
"label",
|
|
2083
|
-
{
|
|
2084
|
-
htmlFor: `filter-${field.name}`,
|
|
2085
|
-
className: "block text-sm font-semibold text-gray-700",
|
|
2086
|
-
"data-testid": `filter-label-${field.name}`,
|
|
2087
|
-
children: field.label
|
|
2088
|
-
}
|
|
2089
|
-
),
|
|
2090
|
-
field.type === "select" ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2091
|
-
"select",
|
|
2092
|
-
{
|
|
2093
|
-
id: `filter-${field.name}`,
|
|
2094
|
-
name: field.name,
|
|
2095
|
-
className: "w-full px-4 py-2.5 border border-gray-300 rounded-lg shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all duration-200 bg-white",
|
|
2096
|
-
"data-testid": `filter-select-${field.name}`,
|
|
2097
|
-
children: [
|
|
2098
|
-
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "", selected: getFieldValue(field) === "", children: "\u5168\u90E8" }),
|
|
2099
|
-
field.options?.map((option) => {
|
|
2100
|
-
const optionValue = String(option.value);
|
|
2101
|
-
const isSelected = getFieldValue(field) === optionValue;
|
|
2102
|
-
return /* @__PURE__ */ jsxRuntime.jsx("option", { value: optionValue, selected: isSelected, children: option.label }, optionValue);
|
|
2103
|
-
})
|
|
2104
|
-
]
|
|
2105
|
-
}
|
|
2106
|
-
) : field.type === "date" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2107
|
-
"input",
|
|
2108
|
-
{
|
|
2109
|
-
id: `filter-${field.name}`,
|
|
2110
|
-
name: field.name,
|
|
2111
|
-
type: "date",
|
|
2112
|
-
value: getFieldValue(field),
|
|
2113
|
-
className: "w-full px-4 py-2.5 border border-gray-300 rounded-lg shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all duration-200 bg-white",
|
|
2114
|
-
"data-testid": `filter-input-${field.name}`
|
|
2115
|
-
}
|
|
2116
|
-
) : field.type === "number" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2117
|
-
"input",
|
|
2118
|
-
{
|
|
2119
|
-
id: `filter-${field.name}`,
|
|
2120
|
-
name: field.name,
|
|
2121
|
-
type: "number",
|
|
2122
|
-
value: getFieldValue(field),
|
|
2123
|
-
placeholder: field.placeholder || `\u8BF7\u8F93\u5165${field.label}`,
|
|
2124
|
-
step: field.step,
|
|
2125
|
-
className: "w-full px-4 py-2.5 border border-gray-300 rounded-lg shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all duration-200 bg-white",
|
|
2126
|
-
"data-testid": `filter-input-${field.name}`
|
|
2127
|
-
}
|
|
2128
|
-
) : field.type === "email" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2129
|
-
"input",
|
|
2130
|
-
{
|
|
2131
|
-
id: `filter-${field.name}`,
|
|
2132
|
-
name: field.name,
|
|
2133
|
-
type: "email",
|
|
2134
|
-
value: getFieldValue(field),
|
|
2135
|
-
placeholder: field.placeholder || `\u8BF7\u8F93\u5165${field.label}`,
|
|
2136
|
-
className: "w-full px-4 py-2.5 border border-gray-300 rounded-lg shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all duration-200 bg-white",
|
|
2137
|
-
"data-testid": `filter-input-${field.name}`
|
|
2138
|
-
}
|
|
2139
|
-
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
2140
|
-
"input",
|
|
2141
|
-
{
|
|
2142
|
-
id: `filter-${field.name}`,
|
|
2143
|
-
name: field.name,
|
|
2144
|
-
type: "text",
|
|
2145
|
-
value: getFieldValue(field),
|
|
2146
|
-
placeholder: field.placeholder || `\u8BF7\u8F93\u5165${field.label}`,
|
|
2147
|
-
className: "w-full px-4 py-2.5 border border-gray-300 rounded-lg shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all duration-200 bg-white",
|
|
2148
|
-
"data-testid": `filter-input-${field.name}`
|
|
2149
|
-
}
|
|
2150
|
-
)
|
|
2151
|
-
] }) }, field.name)) }),
|
|
2152
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 pt-2", children: [
|
|
2153
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2154
|
-
"button",
|
|
2155
|
-
{
|
|
2156
|
-
type: "submit",
|
|
2157
|
-
className: "px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors font-medium",
|
|
2158
|
-
"data-testid": "filter-submit-button",
|
|
2159
|
-
children: "\u7B5B\u9009"
|
|
2160
|
-
}
|
|
2161
|
-
),
|
|
2162
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2163
|
-
"a",
|
|
2164
|
-
{
|
|
2165
|
-
href: listPath,
|
|
2166
|
-
"hx-get": listPath,
|
|
2167
|
-
className: "px-4 py-2 bg-gray-200 text-gray-800 rounded-lg hover:bg-gray-300 transition-colors font-medium",
|
|
2168
|
-
"data-testid": "filter-reset-button",
|
|
2169
|
-
children: "\u91CD\u7F6E"
|
|
2170
|
-
}
|
|
2171
|
-
)
|
|
2346
|
+
className: "space-y-4 mb-0",
|
|
2347
|
+
"x-data": alpineData,
|
|
2348
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
2349
|
+
/* @__PURE__ */ jsxRuntime.jsx("template", { "x-for": "condition in conditions", "x-bind:key": "condition.id", children: /* @__PURE__ */ jsxRuntime.jsx(FilterConditionItem, { children: /* @__PURE__ */ jsxRuntime.jsx(FieldInput, {}) }) }),
|
|
2350
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
2351
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
|
|
2352
|
+
/* @__PURE__ */ jsxRuntime.jsx(AddConditionButton, {}),
|
|
2353
|
+
/* @__PURE__ */ jsxRuntime.jsx(FieldSelectorDropdown, { fields })
|
|
2354
|
+
] }),
|
|
2355
|
+
/* @__PURE__ */ jsxRuntime.jsx(SubmitButton, {}),
|
|
2356
|
+
/* @__PURE__ */ jsxRuntime.jsx(ResetButton, { listPath })
|
|
2172
2357
|
] })
|
|
2173
|
-
]
|
|
2358
|
+
] })
|
|
2174
2359
|
}
|
|
2175
2360
|
) });
|
|
2176
2361
|
}
|
|
@@ -2224,15 +2409,18 @@ function Pagination(props) {
|
|
|
2224
2409
|
pageSize,
|
|
2225
2410
|
total,
|
|
2226
2411
|
totalPages,
|
|
2412
|
+
nextPageState,
|
|
2413
|
+
itemCount,
|
|
2227
2414
|
baseUrl,
|
|
2228
2415
|
currentParams = {}
|
|
2229
2416
|
} = props;
|
|
2230
|
-
|
|
2417
|
+
const isCursorPagination = totalPages === void 0 && total === void 0;
|
|
2418
|
+
if (!isCursorPagination && (totalPages ?? 0) <= 1) {
|
|
2231
2419
|
return null;
|
|
2232
2420
|
}
|
|
2233
|
-
const start = (page - 1) * pageSize + 1;
|
|
2234
|
-
const end = Math.min(page * pageSize, total);
|
|
2235
|
-
const
|
|
2421
|
+
const start = page && !isCursorPagination ? (page - 1) * pageSize + 1 : void 0;
|
|
2422
|
+
const end = page && total && !isCursorPagination ? Math.min(page * pageSize, total) : void 0;
|
|
2423
|
+
const buildPageUrl = (targetPage) => {
|
|
2236
2424
|
const url = new URL(baseUrl, "http://localhost");
|
|
2237
2425
|
for (const [key, value] of Object.entries(currentParams)) {
|
|
2238
2426
|
if (value !== void 0 && value !== null && value !== "") {
|
|
@@ -2240,47 +2428,89 @@ function Pagination(props) {
|
|
|
2240
2428
|
}
|
|
2241
2429
|
}
|
|
2242
2430
|
url.searchParams.set("page", String(targetPage));
|
|
2431
|
+
url.searchParams.delete("pageState");
|
|
2243
2432
|
return url.pathname + url.search;
|
|
2244
2433
|
};
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
"
|
|
2265
|
-
"
|
|
2266
|
-
"
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
"
|
|
2277
|
-
"
|
|
2278
|
-
"
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2434
|
+
const buildCursorUrl = (pageState) => {
|
|
2435
|
+
const url = new URL(baseUrl, "http://localhost");
|
|
2436
|
+
for (const [key, value] of Object.entries(currentParams)) {
|
|
2437
|
+
if (value !== void 0 && value !== null && value !== "") {
|
|
2438
|
+
url.searchParams.set(key, String(value));
|
|
2439
|
+
}
|
|
2440
|
+
}
|
|
2441
|
+
url.searchParams.set("pageState", pageState);
|
|
2442
|
+
url.searchParams.delete("page");
|
|
2443
|
+
return url.pathname + url.search;
|
|
2444
|
+
};
|
|
2445
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2446
|
+
"nav",
|
|
2447
|
+
{
|
|
2448
|
+
className: "px-6 py-4 flex items-center justify-between border-t border-gray-200 bg-gray-50",
|
|
2449
|
+
"data-testid": "pagination",
|
|
2450
|
+
"aria-label": "\u5206\u9875\u5BFC\u822A",
|
|
2451
|
+
children: [
|
|
2452
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm text-gray-700", "data-testid": "pagination-info", children: isCursorPagination ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2453
|
+
"\u672C\u9875",
|
|
2454
|
+
" ",
|
|
2455
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", "data-testid": "pagination-count", children: itemCount ?? 0 }),
|
|
2456
|
+
" ",
|
|
2457
|
+
"\u6761"
|
|
2458
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2459
|
+
"\u663E\u793A",
|
|
2460
|
+
" ",
|
|
2461
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", "data-testid": "pagination-start", children: start }),
|
|
2462
|
+
" ",
|
|
2463
|
+
"\u5230",
|
|
2464
|
+
" ",
|
|
2465
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", "data-testid": "pagination-end", children: end }),
|
|
2466
|
+
" ",
|
|
2467
|
+
"\u6761\uFF0C\u5171",
|
|
2468
|
+
" ",
|
|
2469
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", "data-testid": "pagination-total", children: total }),
|
|
2470
|
+
" ",
|
|
2471
|
+
"\u6761"
|
|
2472
|
+
] }) }),
|
|
2473
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2", "data-testid": "pagination-controls", children: [
|
|
2474
|
+
!isCursorPagination && page && totalPages && page > 1 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2475
|
+
Button,
|
|
2476
|
+
{
|
|
2477
|
+
variant: "secondary",
|
|
2478
|
+
size: "sm",
|
|
2479
|
+
href: buildPageUrl(page - 1),
|
|
2480
|
+
"hx-get": buildPageUrl(page - 1),
|
|
2481
|
+
"data-testid": "pagination-prev",
|
|
2482
|
+
"aria-label": "\u4E0A\u4E00\u9875",
|
|
2483
|
+
children: "\u4E0A\u4E00\u9875"
|
|
2484
|
+
}
|
|
2485
|
+
),
|
|
2486
|
+
!isCursorPagination && page && totalPages && page < totalPages && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2487
|
+
Button,
|
|
2488
|
+
{
|
|
2489
|
+
variant: "secondary",
|
|
2490
|
+
size: "sm",
|
|
2491
|
+
href: buildPageUrl(page + 1),
|
|
2492
|
+
"hx-get": buildPageUrl(page + 1),
|
|
2493
|
+
"data-testid": "pagination-next",
|
|
2494
|
+
"aria-label": "\u4E0B\u4E00\u9875",
|
|
2495
|
+
children: "\u4E0B\u4E00\u9875"
|
|
2496
|
+
}
|
|
2497
|
+
),
|
|
2498
|
+
isCursorPagination && nextPageState ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2499
|
+
Button,
|
|
2500
|
+
{
|
|
2501
|
+
variant: "secondary",
|
|
2502
|
+
size: "sm",
|
|
2503
|
+
href: buildCursorUrl(nextPageState),
|
|
2504
|
+
"hx-get": buildCursorUrl(nextPageState),
|
|
2505
|
+
"data-testid": "pagination-next",
|
|
2506
|
+
"aria-label": "\u4E0B\u4E00\u9875",
|
|
2507
|
+
children: "\u4E0B\u4E00\u9875"
|
|
2508
|
+
}
|
|
2509
|
+
) : null
|
|
2510
|
+
] })
|
|
2511
|
+
]
|
|
2512
|
+
}
|
|
2513
|
+
);
|
|
2284
2514
|
}
|
|
2285
2515
|
var STYLES = {
|
|
2286
2516
|
header: {
|
|
@@ -2574,6 +2804,7 @@ function ListPage(props) {
|
|
|
2574
2804
|
pageSize: params.pageSize,
|
|
2575
2805
|
sortBy: params.sortBy,
|
|
2576
2806
|
sortOrder: params.sortOrder,
|
|
2807
|
+
pageState: params.pageState,
|
|
2577
2808
|
...params.filters
|
|
2578
2809
|
// 包含所有筛选条件
|
|
2579
2810
|
};
|
|
@@ -2596,7 +2827,7 @@ function ListPage(props) {
|
|
|
2596
2827
|
];
|
|
2597
2828
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-6", children: [
|
|
2598
2829
|
filterFields && filterFields.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2599
|
-
|
|
2830
|
+
DynamicFilters,
|
|
2600
2831
|
{
|
|
2601
2832
|
fields: filterFields,
|
|
2602
2833
|
listPath,
|
|
@@ -2618,14 +2849,16 @@ function ListPage(props) {
|
|
|
2618
2849
|
method: action.method,
|
|
2619
2850
|
target: action.target
|
|
2620
2851
|
})) : void 0,
|
|
2621
|
-
pagination: {
|
|
2852
|
+
pagination: result.totalPages !== void 0 || result.pageState !== void 0 ? {
|
|
2622
2853
|
page: result.page,
|
|
2623
2854
|
pageSize: result.pageSize,
|
|
2624
2855
|
total: result.total,
|
|
2625
2856
|
totalPages: result.totalPages,
|
|
2857
|
+
nextPageState: result.pageState,
|
|
2858
|
+
itemCount: result.items.length,
|
|
2626
2859
|
baseUrl: listPath,
|
|
2627
2860
|
currentParams
|
|
2628
|
-
},
|
|
2861
|
+
} : void 0,
|
|
2629
2862
|
tableActions,
|
|
2630
2863
|
actionStyle: "link"
|
|
2631
2864
|
}
|
|
@@ -2634,21 +2867,49 @@ function ListPage(props) {
|
|
|
2634
2867
|
}
|
|
2635
2868
|
|
|
2636
2869
|
// src/utils/params.ts
|
|
2637
|
-
function parseListParams(ctx) {
|
|
2870
|
+
function parseListParams(ctx, filterSchema) {
|
|
2638
2871
|
const url = new URL(ctx.req.url);
|
|
2639
|
-
const systemParams = /* @__PURE__ */ new Set([
|
|
2872
|
+
const systemParams = /* @__PURE__ */ new Set([
|
|
2873
|
+
"page",
|
|
2874
|
+
"pageSize",
|
|
2875
|
+
"sortBy",
|
|
2876
|
+
"sortOrder",
|
|
2877
|
+
"pageState"
|
|
2878
|
+
]);
|
|
2640
2879
|
const filters = {};
|
|
2641
2880
|
for (const [key, value] of url.searchParams.entries()) {
|
|
2642
|
-
if (!systemParams.has(key)
|
|
2881
|
+
if (!systemParams.has(key)) {
|
|
2643
2882
|
filters[key] = value;
|
|
2644
2883
|
}
|
|
2645
2884
|
}
|
|
2885
|
+
let processedFilters = void 0;
|
|
2886
|
+
if (filterSchema && Object.keys(filters).length > 0) {
|
|
2887
|
+
const emptyStringFields = /* @__PURE__ */ new Set();
|
|
2888
|
+
for (const [key, value] of Object.entries(filters)) {
|
|
2889
|
+
if (value === "") {
|
|
2890
|
+
emptyStringFields.add(key);
|
|
2891
|
+
}
|
|
2892
|
+
}
|
|
2893
|
+
const preprocessed = preprocessFormData(filters, filterSchema);
|
|
2894
|
+
const cleanedFilters = {};
|
|
2895
|
+
for (const [key, value] of Object.entries(preprocessed)) {
|
|
2896
|
+
if (emptyStringFields.has(key)) {
|
|
2897
|
+
cleanedFilters[key] = "";
|
|
2898
|
+
} else if (value !== void 0 && value !== null) {
|
|
2899
|
+
cleanedFilters[key] = value;
|
|
2900
|
+
}
|
|
2901
|
+
}
|
|
2902
|
+
processedFilters = Object.keys(cleanedFilters).length > 0 ? cleanedFilters : void 0;
|
|
2903
|
+
} else if (Object.keys(filters).length > 0) {
|
|
2904
|
+
processedFilters = filters;
|
|
2905
|
+
}
|
|
2646
2906
|
return {
|
|
2647
2907
|
page: parseInt(url.searchParams.get("page") || "1", 10),
|
|
2648
2908
|
pageSize: parseInt(url.searchParams.get("pageSize") || "10", 10),
|
|
2649
2909
|
sortBy: url.searchParams.get("sortBy") || void 0,
|
|
2650
2910
|
sortOrder: url.searchParams.get("sortOrder") || void 0,
|
|
2651
|
-
|
|
2911
|
+
pageState: url.searchParams.get("pageState") || void 0,
|
|
2912
|
+
filters: processedFilters
|
|
2652
2913
|
};
|
|
2653
2914
|
}
|
|
2654
2915
|
var DefaultListFeature = class extends BaseModelFeature {
|
|
@@ -2677,7 +2938,7 @@ var DefaultListFeature = class extends BaseModelFeature {
|
|
|
2677
2938
|
const prefix = context.prefix || "";
|
|
2678
2939
|
const basePath = `${prefix}/${model.modelName}`;
|
|
2679
2940
|
const hasCreate = model.features.get("create") !== void 0;
|
|
2680
|
-
const actions = [];
|
|
2941
|
+
const actions = [...this.options.actions ?? []];
|
|
2681
2942
|
if (hasCreate) {
|
|
2682
2943
|
const createMode = this.openMode?.create || "dialog";
|
|
2683
2944
|
const createUrl = createMode === "dialog" ? `${basePath}/new?dialog=true` : `${basePath}/new`;
|
|
@@ -2699,8 +2960,10 @@ var DefaultListFeature = class extends BaseModelFeature {
|
|
|
2699
2960
|
return actions;
|
|
2700
2961
|
}
|
|
2701
2962
|
async handler(context) {
|
|
2702
|
-
const params = parseListParams(context.ctx);
|
|
2703
|
-
const result = await this.getList(
|
|
2963
|
+
const params = this.filterSchema ? parseListParams(context.ctx, this.filterSchema) : parseListParams(context.ctx);
|
|
2964
|
+
const result = await this.getList(
|
|
2965
|
+
params
|
|
2966
|
+
);
|
|
2704
2967
|
context.actions = this.getDefaultActions(context);
|
|
2705
2968
|
const title = this.options?.title;
|
|
2706
2969
|
if (typeof title === "function") {
|
|
@@ -5431,9 +5694,9 @@ exports.DefaultEditFeature = DefaultEditFeature;
|
|
|
5431
5694
|
exports.DefaultListFeature = DefaultListFeature;
|
|
5432
5695
|
exports.DetailFieldRenderer = DetailFieldRenderer;
|
|
5433
5696
|
exports.Dialog = Dialog;
|
|
5697
|
+
exports.DynamicFilters = DynamicFilters;
|
|
5434
5698
|
exports.EmptyState = EmptyState;
|
|
5435
5699
|
exports.ErrorAlert = ErrorAlert;
|
|
5436
|
-
exports.FilterForm = FilterForm;
|
|
5437
5700
|
exports.FragmentFeature = FragmentFeature;
|
|
5438
5701
|
exports.Header = Header;
|
|
5439
5702
|
exports.HtmxAdminPlugin = HtmxAdminPlugin;
|