@mulmoclaude/collection-plugin 0.5.17 → 0.5.18
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/vue/components/CollectionRecordPanel.vue.d.ts.map +1 -1
- package/dist/vue/useCollectionRendering.d.ts +3 -2
- package/dist/vue/useCollectionRendering.d.ts.map +1 -1
- package/dist/vue.cjs +172 -110
- package/dist/vue.cjs.map +1 -1
- package/dist/vue.js +172 -110
- package/dist/vue.js.map +1 -1
- package/package.json +1 -1
package/dist/vue.cjs
CHANGED
|
@@ -1904,82 +1904,90 @@ var _hoisted_13$4 = {
|
|
|
1904
1904
|
key: 0,
|
|
1905
1905
|
class: "text-rose-500 font-bold"
|
|
1906
1906
|
};
|
|
1907
|
-
var _hoisted_14$4 =
|
|
1907
|
+
var _hoisted_14$4 = [
|
|
1908
|
+
"id",
|
|
1909
|
+
"onUpdate:modelValue",
|
|
1910
|
+
"required",
|
|
1911
|
+
"data-testid"
|
|
1912
|
+
];
|
|
1913
|
+
var _hoisted_15$4 = { value: "" };
|
|
1914
|
+
var _hoisted_16$4 = ["value"];
|
|
1915
|
+
var _hoisted_17$4 = {
|
|
1908
1916
|
key: 0,
|
|
1909
1917
|
class: "inline-flex items-center gap-2.5 text-sm text-slate-700 cursor-pointer select-none"
|
|
1910
1918
|
};
|
|
1911
|
-
var
|
|
1919
|
+
var _hoisted_18$4 = [
|
|
1912
1920
|
"id",
|
|
1913
1921
|
"onUpdate:modelValue",
|
|
1914
1922
|
"data-testid",
|
|
1915
1923
|
"onChange"
|
|
1916
1924
|
];
|
|
1917
|
-
var
|
|
1925
|
+
var _hoisted_19$3 = [
|
|
1918
1926
|
"id",
|
|
1919
1927
|
"onUpdate:modelValue",
|
|
1920
1928
|
"required",
|
|
1921
1929
|
"data-testid"
|
|
1922
1930
|
];
|
|
1923
|
-
var
|
|
1924
|
-
var
|
|
1925
|
-
var
|
|
1931
|
+
var _hoisted_20$3 = { value: "" };
|
|
1932
|
+
var _hoisted_21$3 = ["value"];
|
|
1933
|
+
var _hoisted_22$3 = [
|
|
1926
1934
|
"id",
|
|
1927
1935
|
"onUpdate:modelValue",
|
|
1928
1936
|
"required",
|
|
1929
1937
|
"data-testid"
|
|
1930
1938
|
];
|
|
1931
|
-
var
|
|
1932
|
-
var
|
|
1933
|
-
var
|
|
1934
|
-
var
|
|
1939
|
+
var _hoisted_23$3 = { value: "" };
|
|
1940
|
+
var _hoisted_24$2 = ["value"];
|
|
1941
|
+
var _hoisted_25$2 = ["data-testid"];
|
|
1942
|
+
var _hoisted_26$2 = {
|
|
1935
1943
|
key: 0,
|
|
1936
1944
|
class: "overflow-hidden border border-slate-200 rounded-lg shadow-sm"
|
|
1937
1945
|
};
|
|
1938
|
-
var
|
|
1939
|
-
var
|
|
1940
|
-
var
|
|
1941
|
-
var
|
|
1942
|
-
var _hoisted_28$1 = ["onUpdate:modelValue", "required"];
|
|
1943
|
-
var _hoisted_29$1 = { value: "" };
|
|
1944
|
-
var _hoisted_30$1 = ["value"];
|
|
1946
|
+
var _hoisted_27$2 = { class: "w-full text-xs text-slate-600 bg-white" };
|
|
1947
|
+
var _hoisted_28$1 = { class: "bg-slate-50 border-b border-slate-200 text-slate-500 font-bold uppercase tracking-wider" };
|
|
1948
|
+
var _hoisted_29$1 = { class: "divide-y divide-slate-100" };
|
|
1949
|
+
var _hoisted_30$1 = ["onUpdate:modelValue", "onChange"];
|
|
1945
1950
|
var _hoisted_31$1 = ["onUpdate:modelValue", "required"];
|
|
1946
1951
|
var _hoisted_32$1 = { value: "" };
|
|
1947
1952
|
var _hoisted_33$1 = ["value"];
|
|
1948
|
-
var _hoisted_34$1 =
|
|
1953
|
+
var _hoisted_34$1 = ["onUpdate:modelValue", "required"];
|
|
1954
|
+
var _hoisted_35$1 = { value: "" };
|
|
1955
|
+
var _hoisted_36$1 = ["value"];
|
|
1956
|
+
var _hoisted_37$1 = {
|
|
1949
1957
|
key: 3,
|
|
1950
1958
|
class: "relative flex items-center"
|
|
1951
1959
|
};
|
|
1952
|
-
var
|
|
1953
|
-
var
|
|
1954
|
-
var
|
|
1960
|
+
var _hoisted_38$1 = { class: "absolute left-1.5 text-[10px] text-slate-400 font-bold pr-1 border-r border-slate-200" };
|
|
1961
|
+
var _hoisted_39$1 = ["onUpdate:modelValue", "required"];
|
|
1962
|
+
var _hoisted_40$1 = [
|
|
1955
1963
|
"onUpdate:modelValue",
|
|
1956
1964
|
"type",
|
|
1957
1965
|
"step",
|
|
1958
1966
|
"required"
|
|
1959
1967
|
];
|
|
1960
|
-
var
|
|
1961
|
-
var
|
|
1968
|
+
var _hoisted_41$1 = { class: "text-center px-1" };
|
|
1969
|
+
var _hoisted_42$1 = [
|
|
1962
1970
|
"aria-label",
|
|
1963
1971
|
"data-testid",
|
|
1964
1972
|
"onClick"
|
|
1965
1973
|
];
|
|
1966
|
-
var
|
|
1974
|
+
var _hoisted_43$1 = {
|
|
1967
1975
|
key: 1,
|
|
1968
1976
|
class: "text-xs text-slate-400 italic"
|
|
1969
1977
|
};
|
|
1970
|
-
var
|
|
1971
|
-
var
|
|
1978
|
+
var _hoisted_44$1 = ["data-testid", "onClick"];
|
|
1979
|
+
var _hoisted_45$1 = {
|
|
1972
1980
|
key: 4,
|
|
1973
1981
|
class: "relative flex items-center"
|
|
1974
1982
|
};
|
|
1975
|
-
var
|
|
1976
|
-
var
|
|
1983
|
+
var _hoisted_46$1 = { class: "absolute left-3 text-slate-400 font-bold text-xs select-none pr-1.5 border-r border-slate-200" };
|
|
1984
|
+
var _hoisted_47$1 = [
|
|
1977
1985
|
"id",
|
|
1978
1986
|
"onUpdate:modelValue",
|
|
1979
1987
|
"required",
|
|
1980
1988
|
"data-testid"
|
|
1981
1989
|
];
|
|
1982
|
-
var
|
|
1990
|
+
var _hoisted_48$1 = [
|
|
1983
1991
|
"id",
|
|
1984
1992
|
"onUpdate:modelValue",
|
|
1985
1993
|
"type",
|
|
@@ -1988,104 +1996,104 @@ var _hoisted_45$1 = [
|
|
|
1988
1996
|
"disabled",
|
|
1989
1997
|
"data-testid"
|
|
1990
1998
|
];
|
|
1991
|
-
var
|
|
1999
|
+
var _hoisted_49$1 = [
|
|
1992
2000
|
"id",
|
|
1993
2001
|
"onUpdate:modelValue",
|
|
1994
2002
|
"rows",
|
|
1995
2003
|
"required",
|
|
1996
2004
|
"data-testid"
|
|
1997
2005
|
];
|
|
1998
|
-
var
|
|
1999
|
-
var
|
|
2006
|
+
var _hoisted_50$1 = ["data-testid"];
|
|
2007
|
+
var _hoisted_51$1 = {
|
|
2000
2008
|
key: 0,
|
|
2001
2009
|
class: "inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-[10px] font-semibold bg-emerald-50 text-emerald-700 border border-emerald-200/40"
|
|
2002
2010
|
};
|
|
2003
|
-
var
|
|
2011
|
+
var _hoisted_52$1 = {
|
|
2004
2012
|
key: 1,
|
|
2005
2013
|
class: "inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-[10px] font-semibold bg-slate-50 text-slate-400 border border-slate-200/20"
|
|
2006
2014
|
};
|
|
2007
|
-
var
|
|
2015
|
+
var _hoisted_53$1 = {
|
|
2008
2016
|
key: 0,
|
|
2009
2017
|
class: "inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-[10px] font-semibold bg-emerald-50 text-emerald-700 border border-emerald-200/40"
|
|
2010
2018
|
};
|
|
2011
|
-
var
|
|
2019
|
+
var _hoisted_54$1 = {
|
|
2012
2020
|
key: 1,
|
|
2013
2021
|
class: "inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-[10px] font-semibold bg-slate-50 text-slate-400 border border-slate-200/20"
|
|
2014
2022
|
};
|
|
2015
|
-
var
|
|
2023
|
+
var _hoisted_55$1 = {
|
|
2016
2024
|
key: 2,
|
|
2017
2025
|
class: "text-slate-300"
|
|
2018
2026
|
};
|
|
2019
|
-
var
|
|
2027
|
+
var _hoisted_56$1 = [
|
|
2020
2028
|
"href",
|
|
2021
2029
|
"tabindex",
|
|
2022
2030
|
"data-testid",
|
|
2023
2031
|
"onClick",
|
|
2024
2032
|
"onKeydown"
|
|
2025
2033
|
];
|
|
2026
|
-
var
|
|
2034
|
+
var _hoisted_57$1 = {
|
|
2027
2035
|
key: 3,
|
|
2028
2036
|
class: "font-semibold text-slate-900 tabular-nums text-sm"
|
|
2029
2037
|
};
|
|
2030
|
-
var
|
|
2038
|
+
var _hoisted_58$1 = {
|
|
2031
2039
|
key: 4,
|
|
2032
2040
|
class: "inline-block truncate tabular-nums font-bold text-indigo-900 bg-indigo-50/50 px-2 py-0.5 rounded border border-indigo-100/50"
|
|
2033
2041
|
};
|
|
2034
|
-
var
|
|
2042
|
+
var _hoisted_59$1 = {
|
|
2035
2043
|
key: 5,
|
|
2036
2044
|
class: "border border-slate-200/80 rounded-xl overflow-hidden shadow-sm mt-1"
|
|
2037
2045
|
};
|
|
2038
|
-
var
|
|
2039
|
-
var
|
|
2040
|
-
var
|
|
2041
|
-
var
|
|
2046
|
+
var _hoisted_60$1 = { class: "w-full text-[11px] text-slate-600 bg-white" };
|
|
2047
|
+
var _hoisted_61$1 = { class: "bg-slate-50 border-b border-slate-200 text-slate-500 font-bold uppercase tracking-wider" };
|
|
2048
|
+
var _hoisted_62$1 = { class: "divide-y divide-slate-100" };
|
|
2049
|
+
var _hoisted_63$1 = {
|
|
2042
2050
|
key: 0,
|
|
2043
2051
|
class: "material-icons text-emerald-600 text-base"
|
|
2044
2052
|
};
|
|
2045
|
-
var
|
|
2053
|
+
var _hoisted_64$1 = {
|
|
2046
2054
|
key: 1,
|
|
2047
2055
|
class: "text-slate-300"
|
|
2048
2056
|
};
|
|
2049
|
-
var
|
|
2057
|
+
var _hoisted_65$1 = {
|
|
2050
2058
|
key: 6,
|
|
2051
2059
|
class: "text-slate-400 italic"
|
|
2052
2060
|
};
|
|
2053
|
-
var
|
|
2061
|
+
var _hoisted_66$1 = {
|
|
2054
2062
|
key: 7,
|
|
2055
2063
|
class: "bg-slate-50 rounded-xl p-4 border border-slate-200/60 text-slate-600 text-xs whitespace-pre-wrap leading-relaxed max-h-[30vh] overflow-y-auto"
|
|
2056
2064
|
};
|
|
2057
|
-
var
|
|
2065
|
+
var _hoisted_67$1 = [
|
|
2058
2066
|
"src",
|
|
2059
2067
|
"alt",
|
|
2060
2068
|
"data-testid"
|
|
2061
2069
|
];
|
|
2062
|
-
var
|
|
2063
|
-
var
|
|
2064
|
-
var
|
|
2070
|
+
var _hoisted_68$1 = ["href", "data-testid"];
|
|
2071
|
+
var _hoisted_69$1 = ["href", "data-testid"];
|
|
2072
|
+
var _hoisted_70$1 = [
|
|
2065
2073
|
"href",
|
|
2066
2074
|
"data-testid",
|
|
2067
2075
|
"onClick"
|
|
2068
2076
|
];
|
|
2069
|
-
var
|
|
2077
|
+
var _hoisted_71$1 = {
|
|
2070
2078
|
key: 13,
|
|
2071
2079
|
class: "text-slate-800 font-semibold"
|
|
2072
2080
|
};
|
|
2073
|
-
var
|
|
2081
|
+
var _hoisted_72$1 = {
|
|
2074
2082
|
key: 0,
|
|
2075
2083
|
class: "col-span-full text-xs font-semibold text-red-600 bg-red-50 border border-red-100 p-2.5 rounded-xl"
|
|
2076
2084
|
};
|
|
2077
|
-
var
|
|
2085
|
+
var _hoisted_73$1 = {
|
|
2078
2086
|
key: 1,
|
|
2079
2087
|
class: "mt-5 pt-4 border-t border-slate-200/60",
|
|
2080
2088
|
"data-testid": "collections-detail-chat"
|
|
2081
2089
|
};
|
|
2082
|
-
var
|
|
2090
|
+
var _hoisted_74$1 = {
|
|
2083
2091
|
class: "block text-[10px] font-bold text-slate-400 uppercase tracking-wider mb-1.5",
|
|
2084
2092
|
for: "collections-detail-chat-input"
|
|
2085
2093
|
};
|
|
2086
|
-
var
|
|
2087
|
-
var
|
|
2088
|
-
var
|
|
2094
|
+
var _hoisted_75$1 = { class: "flex items-end gap-2" };
|
|
2095
|
+
var _hoisted_76$1 = ["placeholder", "onKeydown"];
|
|
2096
|
+
var _hoisted_77$1 = ["disabled"];
|
|
2089
2097
|
//#endregion
|
|
2090
2098
|
//#region src/vue/components/CollectionRecordPanel.vue
|
|
2091
2099
|
var CollectionRecordPanel_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
@@ -2134,12 +2142,17 @@ var CollectionRecordPanel_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
2134
2142
|
emit("itemChat", message);
|
|
2135
2143
|
chatMessage.value = "";
|
|
2136
2144
|
}
|
|
2137
|
-
const embedViews = (0, vue.computed)(() => props.render.embedViews.value);
|
|
2138
2145
|
/** The record the read-only displays render from: the live draft while
|
|
2139
2146
|
* editing (so non-editable cells like derived/embed preview the in-flight
|
|
2140
2147
|
* values), else the open record. Always an object so `[key]` lookups are
|
|
2141
2148
|
* safe in the template. */
|
|
2142
2149
|
const detailRecord = (0, vue.computed)(() => editing.value ? props.liveDerived ?? props.liveRecord ?? {} : props.viewing ?? {});
|
|
2150
|
+
const embedViews = (0, vue.computed)(() => props.render.embedViewsFor(detailRecord.value));
|
|
2151
|
+
const embedOwnedKeys = (0, vue.computed)(() => {
|
|
2152
|
+
const keys = /* @__PURE__ */ new Set();
|
|
2153
|
+
for (const field of Object.values(props.collection.schema.fields)) if (field.type === "embed" && field.idField) keys.add(field.idField);
|
|
2154
|
+
return keys;
|
|
2155
|
+
});
|
|
2143
2156
|
/** Title for the header: the create label, the edited record's id, or the
|
|
2144
2157
|
* open record's title — same h2 slot in every mode. */
|
|
2145
2158
|
const headerTitle = (0, vue.computed)(() => {
|
|
@@ -2172,8 +2185,9 @@ var CollectionRecordPanel_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
2172
2185
|
* cell appears or disappears on toggle: respect the `when` predicate
|
|
2173
2186
|
* (against the active record) and hide the primary key except while
|
|
2174
2187
|
* creating. */
|
|
2175
|
-
function cellVisible(field) {
|
|
2188
|
+
function cellVisible(field, key) {
|
|
2176
2189
|
if (field.primary && editing.value?.mode !== "create") return false;
|
|
2190
|
+
if (embedOwnedKeys.value.has(key)) return false;
|
|
2177
2191
|
return (0, _mulmoclaude_core_collection.fieldVisible)(field, detailRecord.value);
|
|
2178
2192
|
}
|
|
2179
2193
|
/** Mirror of the create-mode primary-key carve-out: drop the HTML5
|
|
@@ -2184,6 +2198,12 @@ var CollectionRecordPanel_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
2184
2198
|
if (editing.value?.mode === "create" && field.primary === true) return false;
|
|
2185
2199
|
return true;
|
|
2186
2200
|
}
|
|
2201
|
+
/** Required flag for an embed's per-record picker — read off the storage
|
|
2202
|
+
* field it writes (`idField`), since the embed itself stores nothing. */
|
|
2203
|
+
function embedPickerRequired(field) {
|
|
2204
|
+
const target = field.idField ? props.collection.schema.fields[field.idField] : void 0;
|
|
2205
|
+
return target ? isFieldRequiredInUi(target) : false;
|
|
2206
|
+
}
|
|
2187
2207
|
/** Tailwind fill/text/border classes tinting an enum `<select>` by its current
|
|
2188
2208
|
* value's colour (palette, or notification red/amber/grey when the field is
|
|
2189
2209
|
* the schema's notifyWhen target). */
|
|
@@ -2261,53 +2281,65 @@ var CollectionRecordPanel_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
2261
2281
|
]))]),
|
|
2262
2282
|
!editing.value && __props.actionError ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("p", _hoisted_10$5, (0, vue.toDisplayString)(__props.actionError), 1)) : (0, vue.createCommentVNode)("", true),
|
|
2263
2283
|
(0, vue.createElementVNode)("div", _hoisted_11$5, [((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(__props.collection.schema.fields, (field, key) => {
|
|
2264
|
-
return (0, vue.openBlock)(), (0, vue.createElementBlock)(vue.Fragment, { key }, [cellVisible(field) ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", {
|
|
2284
|
+
return (0, vue.openBlock)(), (0, vue.createElementBlock)(vue.Fragment, { key }, [cellVisible(field, String(key)) ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", {
|
|
2265
2285
|
key: 0,
|
|
2266
2286
|
class: (0, vue.normalizeClass)(["flex flex-col gap-1.5", colSpanClass(field)])
|
|
2267
2287
|
}, [(0, vue.createElementVNode)("label", {
|
|
2268
2288
|
class: "text-[10px] font-bold text-slate-400 uppercase tracking-wider flex items-center gap-1",
|
|
2269
2289
|
for: `collections-field-${key}`
|
|
2270
|
-
}, [(0, vue.createTextVNode)((0, vue.toDisplayString)(field.label) + " ", 1), editing.value && field.required ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_13$4, "*")) : (0, vue.createCommentVNode)("", true)], 8, _hoisted_12$5), editing.value &&
|
|
2290
|
+
}, [(0, vue.createTextVNode)((0, vue.toDisplayString)(field.label) + " ", 1), editing.value && field.required ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_13$4, "*")) : (0, vue.createCommentVNode)("", true)], 8, _hoisted_12$5), editing.value && field.type === "embed" && field.idField ? (0, vue.withDirectives)(((0, vue.openBlock)(), (0, vue.createElementBlock)("select", {
|
|
2291
|
+
key: 0,
|
|
2292
|
+
id: `collections-field-${key}`,
|
|
2293
|
+
"onUpdate:modelValue": ($event) => editing.value.text[field.idField] = $event,
|
|
2294
|
+
required: embedPickerRequired(field),
|
|
2295
|
+
class: "w-full rounded-xl border border-slate-200 px-3 py-2 text-xs bg-slate-50 hover:bg-slate-50/50 focus:bg-white focus:border-indigo-500 focus:ring-2 focus:ring-indigo-500/20 focus:outline-none transition-all cursor-pointer font-medium text-slate-700",
|
|
2296
|
+
"data-testid": `collections-input-${key}`
|
|
2297
|
+
}, [(0, vue.createElementVNode)("option", _hoisted_15$4, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.selectPlaceholder")), 1), ((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(__props.render.embedOptions(field.to ?? ""), (opt) => {
|
|
2298
|
+
return (0, vue.openBlock)(), (0, vue.createElementBlock)("option", {
|
|
2299
|
+
key: opt.slug,
|
|
2300
|
+
value: opt.slug
|
|
2301
|
+
}, (0, vue.toDisplayString)(opt.display), 9, _hoisted_16$4);
|
|
2302
|
+
}), 128))], 8, _hoisted_14$4)), [[vue.vModelSelect, editing.value.text[field.idField]]]) : editing.value && isEditableType(field.type) ? ((0, vue.openBlock)(), (0, vue.createElementBlock)(vue.Fragment, { key: 1 }, [field.type === "boolean" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("label", _hoisted_17$4, [(0, vue.withDirectives)((0, vue.createElementVNode)("input", {
|
|
2271
2303
|
id: `collections-field-${key}`,
|
|
2272
2304
|
"onUpdate:modelValue": ($event) => editing.value.bool[key] = $event,
|
|
2273
2305
|
type: "checkbox",
|
|
2274
2306
|
class: "h-5 w-5 rounded border-slate-300 text-indigo-600 focus:ring-indigo-500/20 cursor-pointer",
|
|
2275
2307
|
"data-testid": `collections-input-${key}`,
|
|
2276
2308
|
onChange: ($event) => markBoolTouched(String(key))
|
|
2277
|
-
}, null, 40,
|
|
2309
|
+
}, null, 40, _hoisted_18$4), [[vue.vModelCheckbox, editing.value.bool[key]]]), (0, vue.createElementVNode)("span", { class: (0, vue.normalizeClass)(["text-xs font-semibold", editing.value.bool[key] ? "text-indigo-600" : "text-slate-500"]) }, (0, vue.toDisplayString)(editing.value.bool[key] ? (0, vue.unref)(t)("common.yes") : (0, vue.unref)(t)("common.no")), 3)])) : field.type === "ref" && field.to && __props.render.refOptions(field.to).length > 0 ? (0, vue.withDirectives)(((0, vue.openBlock)(), (0, vue.createElementBlock)("select", {
|
|
2278
2310
|
key: 1,
|
|
2279
2311
|
id: `collections-field-${key}`,
|
|
2280
2312
|
"onUpdate:modelValue": ($event) => editing.value.text[key] = $event,
|
|
2281
2313
|
required: isFieldRequiredInUi(field),
|
|
2282
2314
|
class: "w-full rounded-xl border border-slate-200 px-3 py-2 text-xs bg-slate-50 hover:bg-slate-50/50 focus:bg-white focus:border-indigo-500 focus:ring-2 focus:ring-indigo-500/20 focus:outline-none transition-all cursor-pointer font-medium text-slate-700",
|
|
2283
2315
|
"data-testid": `collections-input-${key}`
|
|
2284
|
-
}, [(0, vue.createElementVNode)("option",
|
|
2316
|
+
}, [(0, vue.createElementVNode)("option", _hoisted_20$3, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.selectPlaceholder")), 1), ((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(__props.render.refOptions(field.to), (opt) => {
|
|
2285
2317
|
return (0, vue.openBlock)(), (0, vue.createElementBlock)("option", {
|
|
2286
2318
|
key: opt.slug,
|
|
2287
2319
|
value: opt.slug
|
|
2288
|
-
}, (0, vue.toDisplayString)(opt.display), 9,
|
|
2289
|
-
}), 128))], 8,
|
|
2320
|
+
}, (0, vue.toDisplayString)(opt.display), 9, _hoisted_21$3);
|
|
2321
|
+
}), 128))], 8, _hoisted_19$3)), [[vue.vModelSelect, editing.value.text[key]]]) : field.type === "enum" && Array.isArray(field.values) && field.values.length > 0 ? (0, vue.withDirectives)(((0, vue.openBlock)(), (0, vue.createElementBlock)("select", {
|
|
2290
2322
|
key: 2,
|
|
2291
2323
|
id: `collections-field-${key}`,
|
|
2292
2324
|
"onUpdate:modelValue": ($event) => editing.value.text[key] = $event,
|
|
2293
2325
|
required: isFieldRequiredInUi(field),
|
|
2294
2326
|
class: (0, vue.normalizeClass)(["w-full rounded-xl border px-3 py-2 text-xs focus:bg-white focus:border-indigo-500 focus:ring-2 focus:ring-indigo-500/20 focus:outline-none transition-all cursor-pointer font-medium", enumControlClass(String(key), editing.value.text[key])]),
|
|
2295
2327
|
"data-testid": `collections-input-${key}`
|
|
2296
|
-
}, [(0, vue.createElementVNode)("option",
|
|
2328
|
+
}, [(0, vue.createElementVNode)("option", _hoisted_23$3, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.selectPlaceholder")), 1), ((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(field.values, (value) => {
|
|
2297
2329
|
return (0, vue.openBlock)(), (0, vue.createElementBlock)("option", {
|
|
2298
2330
|
key: value,
|
|
2299
2331
|
value
|
|
2300
|
-
}, (0, vue.toDisplayString)(value), 9,
|
|
2301
|
-
}), 128))], 10,
|
|
2332
|
+
}, (0, vue.toDisplayString)(value), 9, _hoisted_24$2);
|
|
2333
|
+
}), 128))], 10, _hoisted_22$3)), [[vue.vModelSelect, editing.value.text[key]]]) : field.type === "table" && field.of ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", {
|
|
2302
2334
|
key: 3,
|
|
2303
2335
|
class: "border border-slate-200 bg-slate-50/30 rounded-xl p-4 space-y-3",
|
|
2304
2336
|
"data-testid": `collections-table-${key}`
|
|
2305
|
-
}, [editing.value.table[key] && editing.value.table[key].length > 0 ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div",
|
|
2337
|
+
}, [editing.value.table[key] && editing.value.table[key].length > 0 ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_26$2, [(0, vue.createElementVNode)("table", _hoisted_27$2, [(0, vue.createElementVNode)("thead", _hoisted_28$1, [(0, vue.createElementVNode)("tr", null, [((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(field.of, (subField, subKey) => {
|
|
2306
2338
|
return (0, vue.openBlock)(), (0, vue.createElementBlock)("th", {
|
|
2307
2339
|
key: subKey,
|
|
2308
2340
|
class: "text-left px-3 py-2 font-bold"
|
|
2309
2341
|
}, (0, vue.toDisplayString)(subField.label), 1);
|
|
2310
|
-
}), 128)), _cache[9] || (_cache[9] = (0, vue.createElementVNode)("th", { class: "w-9" }, null, -1))])]), (0, vue.createElementVNode)("tbody",
|
|
2342
|
+
}), 128)), _cache[9] || (_cache[9] = (0, vue.createElementVNode)("th", { class: "w-9" }, null, -1))])]), (0, vue.createElementVNode)("tbody", _hoisted_29$1, [((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(editing.value.table[key], (row, rowIdx) => {
|
|
2311
2343
|
return (0, vue.openBlock)(), (0, vue.createElementBlock)("tr", {
|
|
2312
2344
|
key: rowIdx,
|
|
2313
2345
|
class: "hover:bg-slate-50/50"
|
|
@@ -2321,53 +2353,53 @@ var CollectionRecordPanel_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
2321
2353
|
type: "checkbox",
|
|
2322
2354
|
class: "h-4 w-4 rounded border-slate-300 text-indigo-600 focus:ring-indigo-500/20 cursor-pointer",
|
|
2323
2355
|
onChange: ($event) => markRowBoolTouched(row, String(subKey))
|
|
2324
|
-
}, null, 40,
|
|
2356
|
+
}, null, 40, _hoisted_30$1)), [[vue.vModelCheckbox, row.bool[subKey]]]) : subField.type === "enum" && Array.isArray(subField.values) && subField.values.length > 0 ? (0, vue.withDirectives)(((0, vue.openBlock)(), (0, vue.createElementBlock)("select", {
|
|
2325
2357
|
key: 1,
|
|
2326
2358
|
"onUpdate:modelValue": ($event) => row.text[subKey] = $event,
|
|
2327
2359
|
required: subField.required,
|
|
2328
2360
|
class: "w-full rounded-lg border border-slate-200 px-2 py-1 text-xs focus:border-indigo-500 focus:outline-none cursor-pointer bg-slate-50 font-medium"
|
|
2329
|
-
}, [(0, vue.createElementVNode)("option",
|
|
2361
|
+
}, [(0, vue.createElementVNode)("option", _hoisted_32$1, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.selectPlaceholder")), 1), ((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(subField.values, (value) => {
|
|
2330
2362
|
return (0, vue.openBlock)(), (0, vue.createElementBlock)("option", {
|
|
2331
2363
|
key: value,
|
|
2332
2364
|
value
|
|
2333
|
-
}, (0, vue.toDisplayString)(value), 9,
|
|
2334
|
-
}), 128))], 8,
|
|
2365
|
+
}, (0, vue.toDisplayString)(value), 9, _hoisted_33$1);
|
|
2366
|
+
}), 128))], 8, _hoisted_31$1)), [[vue.vModelSelect, row.text[subKey]]]) : subField.type === "ref" && subField.to && __props.render.refOptions(subField.to).length > 0 ? (0, vue.withDirectives)(((0, vue.openBlock)(), (0, vue.createElementBlock)("select", {
|
|
2335
2367
|
key: 2,
|
|
2336
2368
|
"onUpdate:modelValue": ($event) => row.text[subKey] = $event,
|
|
2337
2369
|
required: subField.required,
|
|
2338
2370
|
class: "w-full rounded-lg border border-slate-200 px-2 py-1 text-xs focus:border-indigo-500 focus:outline-none cursor-pointer bg-slate-50 font-medium"
|
|
2339
|
-
}, [(0, vue.createElementVNode)("option",
|
|
2371
|
+
}, [(0, vue.createElementVNode)("option", _hoisted_35$1, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.selectPlaceholder")), 1), ((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(__props.render.refOptions(subField.to), (opt) => {
|
|
2340
2372
|
return (0, vue.openBlock)(), (0, vue.createElementBlock)("option", {
|
|
2341
2373
|
key: opt.slug,
|
|
2342
2374
|
value: opt.slug
|
|
2343
|
-
}, (0, vue.toDisplayString)(opt.display), 9,
|
|
2344
|
-
}), 128))], 8,
|
|
2375
|
+
}, (0, vue.toDisplayString)(opt.display), 9, _hoisted_36$1);
|
|
2376
|
+
}), 128))], 8, _hoisted_34$1)), [[vue.vModelSelect, row.text[subKey]]]) : subField.type === "money" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_37$1, [(0, vue.createElementVNode)("span", _hoisted_38$1, (0, vue.toDisplayString)(__props.render.currencySymbol(__props.render.resolveCurrency(subField, __props.liveRecord))), 1), (0, vue.withDirectives)((0, vue.createElementVNode)("input", {
|
|
2345
2377
|
"onUpdate:modelValue": ($event) => row.text[subKey] = $event,
|
|
2346
2378
|
type: "number",
|
|
2347
2379
|
step: "0.01",
|
|
2348
2380
|
required: subField.required,
|
|
2349
2381
|
class: "w-full rounded-lg border border-slate-200 pl-6 pr-1.5 py-1 text-xs focus:border-indigo-500 focus:outline-none font-semibold text-slate-800"
|
|
2350
|
-
}, null, 8,
|
|
2382
|
+
}, null, 8, _hoisted_39$1), [[vue.vModelText, row.text[subKey]]])])) : (0, vue.withDirectives)(((0, vue.openBlock)(), (0, vue.createElementBlock)("input", {
|
|
2351
2383
|
key: 4,
|
|
2352
2384
|
"onUpdate:modelValue": ($event) => row.text[subKey] = $event,
|
|
2353
2385
|
type: __props.render.inputTypeFor(subField.type),
|
|
2354
2386
|
step: __props.render.stepFor(subField.type),
|
|
2355
2387
|
required: subField.required,
|
|
2356
2388
|
class: "w-full rounded-lg border border-slate-200 px-2 py-1 text-xs focus:border-indigo-500 focus:outline-none font-medium text-slate-700"
|
|
2357
|
-
}, null, 8,
|
|
2358
|
-
}), 128)), (0, vue.createElementVNode)("td",
|
|
2389
|
+
}, null, 8, _hoisted_40$1)), [[vue.vModelDynamic, row.text[subKey]]])]);
|
|
2390
|
+
}), 128)), (0, vue.createElementVNode)("td", _hoisted_41$1, [(0, vue.createElementVNode)("button", {
|
|
2359
2391
|
type: "button",
|
|
2360
2392
|
class: "h-7 w-7 flex items-center justify-center rounded-lg text-slate-400 hover:text-rose-600 hover:bg-rose-50 transition-colors",
|
|
2361
2393
|
"aria-label": (0, vue.unref)(t)("collectionsView.removeRow"),
|
|
2362
2394
|
"data-testid": `collections-table-${key}-remove-${rowIdx}`,
|
|
2363
2395
|
onClick: ($event) => removeTableRow(String(key), rowIdx)
|
|
2364
|
-
}, [..._cache[10] || (_cache[10] = [(0, vue.createElementVNode)("span", { class: "material-icons text-base" }, "close", -1)])], 8,
|
|
2365
|
-
}), 128))])])])) : ((0, vue.openBlock)(), (0, vue.createElementBlock)("p",
|
|
2396
|
+
}, [..._cache[10] || (_cache[10] = [(0, vue.createElementVNode)("span", { class: "material-icons text-base" }, "close", -1)])], 8, _hoisted_42$1)])]);
|
|
2397
|
+
}), 128))])])])) : ((0, vue.openBlock)(), (0, vue.createElementBlock)("p", _hoisted_43$1, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.noRows")), 1)), (0, vue.createElementVNode)("button", {
|
|
2366
2398
|
type: "button",
|
|
2367
2399
|
class: "inline-flex items-center gap-1 text-xs text-indigo-600 hover:text-indigo-800 font-bold hover:underline",
|
|
2368
2400
|
"data-testid": `collections-table-${key}-add`,
|
|
2369
2401
|
onClick: ($event) => addTableRow(String(key), field.of)
|
|
2370
|
-
}, [_cache[11] || (_cache[11] = (0, vue.createElementVNode)("span", { class: "material-icons text-xs" }, "add", -1)), (0, vue.createElementVNode)("span", null, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.addRow")), 1)], 8,
|
|
2402
|
+
}, [_cache[11] || (_cache[11] = (0, vue.createElementVNode)("span", { class: "material-icons text-xs" }, "add", -1)), (0, vue.createElementVNode)("span", null, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.addRow")), 1)], 8, _hoisted_44$1)], 8, _hoisted_25$2)) : field.type === "money" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_45$1, [(0, vue.createElementVNode)("div", _hoisted_46$1, (0, vue.toDisplayString)(__props.render.currencySymbol(__props.render.resolveCurrency(field, __props.liveRecord))), 1), (0, vue.withDirectives)((0, vue.createElementVNode)("input", {
|
|
2371
2403
|
id: `collections-field-${key}`,
|
|
2372
2404
|
"onUpdate:modelValue": ($event) => editing.value.text[key] = $event,
|
|
2373
2405
|
type: "number",
|
|
@@ -2375,7 +2407,7 @@ var CollectionRecordPanel_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
2375
2407
|
required: isFieldRequiredInUi(field),
|
|
2376
2408
|
class: "w-full rounded-xl border border-slate-200 pl-11 pr-3 py-2 text-xs focus:border-indigo-500 focus:ring-2 focus:ring-indigo-500/20 focus:outline-none font-semibold text-slate-800 transition-all",
|
|
2377
2409
|
"data-testid": `collections-input-${key}`
|
|
2378
|
-
}, null, 8,
|
|
2410
|
+
}, null, 8, _hoisted_47$1), [[vue.vModelText, editing.value.text[key]]])])) : [
|
|
2379
2411
|
"string",
|
|
2380
2412
|
"email",
|
|
2381
2413
|
"number",
|
|
@@ -2394,7 +2426,7 @@ var CollectionRecordPanel_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
2394
2426
|
disabled: field.primary === true && (editing.value.mode === "edit" || __props.isSingleton),
|
|
2395
2427
|
class: "w-full rounded-xl border border-slate-200 px-3 py-2 text-xs focus:border-indigo-500 focus:ring-2 focus:ring-indigo-500/20 focus:outline-none disabled:bg-slate-100 disabled:text-slate-400 font-medium text-slate-700 transition-all",
|
|
2396
2428
|
"data-testid": `collections-input-${key}`
|
|
2397
|
-
}, null, 8,
|
|
2429
|
+
}, null, 8, _hoisted_48$1)), [[vue.vModelDynamic, editing.value.text[key]]]) : (0, vue.withDirectives)(((0, vue.openBlock)(), (0, vue.createElementBlock)("textarea", {
|
|
2398
2430
|
key: 6,
|
|
2399
2431
|
id: `collections-field-${key}`,
|
|
2400
2432
|
"onUpdate:modelValue": ($event) => editing.value.text[key] = $event,
|
|
@@ -2402,11 +2434,11 @@ var CollectionRecordPanel_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
2402
2434
|
required: isFieldRequiredInUi(field),
|
|
2403
2435
|
class: "w-full rounded-xl border border-slate-200 px-3 py-2 text-xs focus:border-indigo-500 focus:ring-2 focus:ring-indigo-500/20 focus:outline-none font-medium text-slate-700 transition-all",
|
|
2404
2436
|
"data-testid": `collections-input-${key}`
|
|
2405
|
-
}, null, 8,
|
|
2406
|
-
key:
|
|
2437
|
+
}, null, 8, _hoisted_49$1)), [[vue.vModelText, editing.value.text[key]]])], 64)) : ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", {
|
|
2438
|
+
key: 2,
|
|
2407
2439
|
class: "text-xs font-medium text-slate-700 break-words",
|
|
2408
2440
|
"data-testid": `collections-detail-value-${key}`
|
|
2409
|
-
}, [field.type === "toggle" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)(vue.Fragment, { key: 0 }, [field.field !== void 0 && String(detailRecord.value[field.field] ?? "") === field.onValue ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span",
|
|
2441
|
+
}, [field.type === "toggle" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)(vue.Fragment, { key: 0 }, [field.field !== void 0 && String(detailRecord.value[field.field] ?? "") === field.onValue ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_51$1, [_cache[12] || (_cache[12] = (0, vue.createElementVNode)("span", { class: "h-1.5 w-1.5 rounded-full bg-emerald-500" }, null, -1)), (0, vue.createTextVNode)(" " + (0, vue.toDisplayString)((0, vue.unref)(t)("common.yes")), 1)])) : ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_52$1, (0, vue.toDisplayString)((0, vue.unref)(t)("common.no")), 1))], 64)) : field.type === "boolean" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)(vue.Fragment, { key: 1 }, [detailRecord.value[key] === true ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_53$1, [_cache[13] || (_cache[13] = (0, vue.createElementVNode)("span", { class: "h-1.5 w-1.5 rounded-full bg-emerald-500" }, null, -1)), (0, vue.createTextVNode)(" " + (0, vue.toDisplayString)((0, vue.unref)(t)("common.yes")), 1)])) : detailRecord.value[key] === false ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_54$1, (0, vue.toDisplayString)((0, vue.unref)(t)("common.no")), 1)) : ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_55$1, "—"))], 64)) : field.type === "ref" && field.to && typeof detailRecord.value[key] === "string" && detailRecord.value[key] ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("a", {
|
|
2410
2442
|
key: 2,
|
|
2411
2443
|
href: (0, vue.unref)(cui).recordHref?.(field.to, String(detailRecord.value[key])),
|
|
2412
2444
|
tabindex: (0, vue.unref)(cui).recordHref?.(field.to, String(detailRecord.value[key])) ? void 0 : 0,
|
|
@@ -2415,12 +2447,12 @@ var CollectionRecordPanel_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
2415
2447
|
"data-testid": `collections-detail-ref-${key}`,
|
|
2416
2448
|
onClick: ($event) => (0, vue.unref)(activateRefLink)($event, field.to, String(detailRecord.value[key])),
|
|
2417
2449
|
onKeydown: [(0, vue.withKeys)(($event) => (0, vue.unref)(activateRefLink)($event, field.to, String(detailRecord.value[key])), ["enter"]), (0, vue.withKeys)(($event) => (0, vue.unref)(activateRefLink)($event, field.to, String(detailRecord.value[key])), ["space"])]
|
|
2418
|
-
}, (0, vue.toDisplayString)(__props.render.refDisplay(field.to, String(detailRecord.value[key]))), 41,
|
|
2450
|
+
}, (0, vue.toDisplayString)(__props.render.refDisplay(field.to, String(detailRecord.value[key]))), 41, _hoisted_56$1)) : field.type === "money" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_57$1, (0, vue.toDisplayString)(__props.render.formatMoney(detailRecord.value[key], __props.render.resolveCurrency(field, detailRecord.value), __props.locale)), 1)) : field.type === "derived" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_58$1, (0, vue.toDisplayString)(__props.render.derivedDisplay(field, __props.render.evaluateDerivedAgainstItem(field, String(key), detailRecord.value), detailRecord.value)), 1)) : field.type === "table" && field.of && __props.render.hasTableRows(detailRecord.value[key]) ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_59$1, [(0, vue.createElementVNode)("table", _hoisted_60$1, [(0, vue.createElementVNode)("thead", _hoisted_61$1, [(0, vue.createElementVNode)("tr", null, [((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(field.of, (subField, subKey) => {
|
|
2419
2451
|
return (0, vue.openBlock)(), (0, vue.createElementBlock)("th", {
|
|
2420
2452
|
key: subKey,
|
|
2421
2453
|
class: "text-left px-4 py-2 font-bold"
|
|
2422
2454
|
}, (0, vue.toDisplayString)(subField.label), 1);
|
|
2423
|
-
}), 128))])]), (0, vue.createElementVNode)("tbody",
|
|
2455
|
+
}), 128))])]), (0, vue.createElementVNode)("tbody", _hoisted_62$1, [((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(__props.render.tableRows(detailRecord.value[key]), (row, rowIdx) => {
|
|
2424
2456
|
return (0, vue.openBlock)(), (0, vue.createElementBlock)("tr", {
|
|
2425
2457
|
key: rowIdx,
|
|
2426
2458
|
class: "hover:bg-slate-50/50"
|
|
@@ -2428,12 +2460,12 @@ var CollectionRecordPanel_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
2428
2460
|
return (0, vue.openBlock)(), (0, vue.createElementBlock)("td", {
|
|
2429
2461
|
key: subKey,
|
|
2430
2462
|
class: "px-4 py-2 align-middle font-medium"
|
|
2431
|
-
}, [subField.type === "boolean" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)(vue.Fragment, { key: 0 }, [row[subKey] === true ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span",
|
|
2463
|
+
}, [subField.type === "boolean" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)(vue.Fragment, { key: 0 }, [row[subKey] === true ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_63$1, "check_circle")) : ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_64$1, "—"))], 64)) : ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", {
|
|
2432
2464
|
key: 1,
|
|
2433
2465
|
class: (0, vue.normalizeClass)([subField.type === "money" ? "font-bold text-slate-800 tabular-nums" : ""])
|
|
2434
2466
|
}, (0, vue.toDisplayString)(__props.render.formatSubCell(subField, row[subKey], detailRecord.value)), 3))]);
|
|
2435
2467
|
}), 128))]);
|
|
2436
|
-
}), 128))])])])) : field.type === "table" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span",
|
|
2468
|
+
}), 128))])])])) : field.type === "table" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_65$1, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.noRows")), 1)) : field.type === "markdown" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_66$1, (0, vue.toDisplayString)(__props.render.detailText(detailRecord.value[key])), 1)) : field.type === "embed" && embedViews.value[key] ? ((0, vue.openBlock)(), (0, vue.createBlock)(CollectionEmbedView_default, {
|
|
2437
2469
|
key: 8,
|
|
2438
2470
|
view: embedViews.value[key],
|
|
2439
2471
|
"field-key": String(key)
|
|
@@ -2443,29 +2475,29 @@ var CollectionRecordPanel_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
2443
2475
|
alt: field.label,
|
|
2444
2476
|
class: "max-h-64 max-w-full object-contain rounded-lg border border-slate-200 bg-slate-50",
|
|
2445
2477
|
"data-testid": `collections-detail-image-${key}`
|
|
2446
|
-
}, null, 8,
|
|
2478
|
+
}, null, 8, _hoisted_67$1)) : field.type !== "file" && __props.render.isExternalUrl(detailRecord.value[key]) ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("a", {
|
|
2447
2479
|
key: 10,
|
|
2448
2480
|
href: String(detailRecord.value[key]),
|
|
2449
2481
|
target: "_blank",
|
|
2450
2482
|
rel: "noopener noreferrer",
|
|
2451
2483
|
class: "text-blue-600 hover:text-blue-800 font-semibold hover:underline break-all",
|
|
2452
2484
|
"data-testid": `collections-detail-url-${key}`
|
|
2453
|
-
}, (0, vue.toDisplayString)(String(detailRecord.value[key])), 9,
|
|
2485
|
+
}, (0, vue.toDisplayString)(String(detailRecord.value[key])), 9, _hoisted_68$1)) : field.type === "file" && __props.render.artifactUrl(detailRecord.value[key]) ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("a", {
|
|
2454
2486
|
key: 11,
|
|
2455
2487
|
href: __props.render.artifactUrl(detailRecord.value[key]) ?? void 0,
|
|
2456
2488
|
target: "_blank",
|
|
2457
2489
|
rel: "noopener noreferrer",
|
|
2458
2490
|
class: "text-blue-600 hover:text-blue-800 font-semibold hover:underline break-all",
|
|
2459
2491
|
"data-testid": `collections-detail-file-${key}`
|
|
2460
|
-
}, (0, vue.toDisplayString)(String(detailRecord.value[key])), 9,
|
|
2492
|
+
}, (0, vue.toDisplayString)(String(detailRecord.value[key])), 9, _hoisted_69$1)) : field.type === "file" && __props.render.fileRoutePath(detailRecord.value[key]) ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("a", {
|
|
2461
2493
|
key: 12,
|
|
2462
2494
|
href: __props.render.fileRoutePath(detailRecord.value[key]) ?? void 0,
|
|
2463
2495
|
class: "text-blue-600 hover:text-blue-800 font-semibold hover:underline break-all",
|
|
2464
2496
|
"data-testid": `collections-detail-file-${key}`,
|
|
2465
2497
|
onClick: ($event) => (0, vue.unref)(activatePathLink)($event, __props.render.fileRoutePath(detailRecord.value[key]) ?? "")
|
|
2466
|
-
}, (0, vue.toDisplayString)(String(detailRecord.value[key])), 9,
|
|
2467
|
-
}), 128)), editing.value && __props.saveError ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("p",
|
|
2468
|
-
!editing.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div",
|
|
2498
|
+
}, (0, vue.toDisplayString)(String(detailRecord.value[key])), 9, _hoisted_70$1)) : ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_71$1, (0, vue.toDisplayString)(__props.render.formatCell(detailRecord.value[key], field.type)), 1))], 8, _hoisted_50$1))], 2)) : (0, vue.createCommentVNode)("", true)], 64);
|
|
2499
|
+
}), 128)), editing.value && __props.saveError ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("p", _hoisted_72$1, (0, vue.toDisplayString)(__props.saveError), 1)) : (0, vue.createCommentVNode)("", true)]),
|
|
2500
|
+
!editing.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_73$1, [(0, vue.createElementVNode)("label", _hoisted_74$1, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.itemChatLabel")), 1), (0, vue.createElementVNode)("div", _hoisted_75$1, [(0, vue.withDirectives)((0, vue.createElementVNode)("textarea", {
|
|
2469
2501
|
id: "collections-detail-chat-input",
|
|
2470
2502
|
"onUpdate:modelValue": _cache[4] || (_cache[4] = ($event) => chatMessage.value = $event),
|
|
2471
2503
|
rows: "2",
|
|
@@ -2473,13 +2505,13 @@ var CollectionRecordPanel_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
2473
2505
|
class: "flex-1 bg-slate-50 border border-slate-200/80 rounded-xl px-3 py-2 text-xs placeholder-slate-400 focus:outline-none focus:ring-2 focus:ring-indigo-500/20 focus:border-indigo-500 focus:bg-white transition-all resize-none",
|
|
2474
2506
|
"data-testid": "collections-detail-chat-input",
|
|
2475
2507
|
onKeydown: [(0, vue.withKeys)((0, vue.withModifiers)(submitItemChat, ["meta"]), ["enter"]), (0, vue.withKeys)((0, vue.withModifiers)(submitItemChat, ["ctrl"]), ["enter"])]
|
|
2476
|
-
}, null, 40,
|
|
2508
|
+
}, null, 40, _hoisted_76$1), [[vue.vModelText, chatMessage.value]]), (0, vue.createElementVNode)("button", {
|
|
2477
2509
|
type: "button",
|
|
2478
2510
|
class: "h-8 px-2.5 rounded bg-indigo-600 text-white font-bold text-xs hover:bg-indigo-700 disabled:opacity-50 transition-all shadow-sm shadow-indigo-600/10 flex items-center gap-1 shrink-0",
|
|
2479
2511
|
disabled: !chatMessage.value.trim(),
|
|
2480
2512
|
"data-testid": "collections-detail-chat-send",
|
|
2481
2513
|
onClick: submitItemChat
|
|
2482
|
-
}, [_cache[14] || (_cache[14] = (0, vue.createElementVNode)("span", { class: "material-icons text-sm" }, "forum", -1)), (0, vue.createElementVNode)("span", null, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.chat")), 1)], 8,
|
|
2514
|
+
}, [_cache[14] || (_cache[14] = (0, vue.createElementVNode)("span", { class: "material-icons text-sm" }, "forum", -1)), (0, vue.createElementVNode)("span", null, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.chat")), 1)], 8, _hoisted_77$1)])])) : (0, vue.createCommentVNode)("", true)
|
|
2483
2515
|
]),
|
|
2484
2516
|
_: 1
|
|
2485
2517
|
}, 40, ["data-testid"]);
|
|
@@ -2855,17 +2887,43 @@ function useCollectionRendering(collection, locale) {
|
|
|
2855
2887
|
display
|
|
2856
2888
|
})).sort((left, right) => left.display.localeCompare(right.display));
|
|
2857
2889
|
}
|
|
2858
|
-
|
|
2859
|
-
|
|
2890
|
+
/** Dropdown options for an `embed` field's per-record picker (`idField`):
|
|
2891
|
+
* every record in the target collection, labelled by its name/title (or
|
|
2892
|
+
* primary key). Built from `embedCache` so it works for embed targets
|
|
2893
|
+
* that aren't also `ref` targets (the profile collection, say). */
|
|
2894
|
+
function embedOptions(targetSlug) {
|
|
2895
|
+
const data = embedCache.value[targetSlug];
|
|
2896
|
+
if (!data) return [];
|
|
2897
|
+
const { fields, primaryKey } = data.schema;
|
|
2898
|
+
const displayField = "name" in fields ? "name" : "title" in fields ? "title" : primaryKey;
|
|
2899
|
+
return data.items.map((item) => {
|
|
2900
|
+
const slug = String(item[primaryKey] ?? "");
|
|
2901
|
+
const labelRaw = item[displayField];
|
|
2902
|
+
return {
|
|
2903
|
+
slug,
|
|
2904
|
+
display: typeof labelRaw === "string" && labelRaw.length > 0 ? labelRaw : slug
|
|
2905
|
+
};
|
|
2906
|
+
}).filter((opt) => opt.slug.length > 0).sort((left, right) => left.display.localeCompare(right.display));
|
|
2907
|
+
}
|
|
2908
|
+
/** The target record id an embed points at: its fixed `id`, or the
|
|
2909
|
+
* value of the sibling `idField` on the open record (per-record). */
|
|
2910
|
+
function embedTargetId(field, record) {
|
|
2911
|
+
if (field.id) return field.id;
|
|
2912
|
+
if (field.idField && record) return String(record[field.idField] ?? "");
|
|
2913
|
+
return "";
|
|
2914
|
+
}
|
|
2915
|
+
function resolveEmbed(field, record) {
|
|
2916
|
+
if (field.type !== "embed" || !field.to) return {
|
|
2860
2917
|
schema: null,
|
|
2861
2918
|
item: null
|
|
2862
2919
|
};
|
|
2863
|
-
const
|
|
2920
|
+
const targetId = embedTargetId(field, record);
|
|
2921
|
+
const data = targetId ? embedCache.value[field.to] : void 0;
|
|
2864
2922
|
if (!data) return {
|
|
2865
2923
|
schema: null,
|
|
2866
2924
|
item: null
|
|
2867
2925
|
};
|
|
2868
|
-
const item = data.items.find((entry) => String(entry[data.schema.primaryKey] ?? "") ===
|
|
2926
|
+
const item = data.items.find((entry) => String(entry[data.schema.primaryKey] ?? "") === targetId) ?? null;
|
|
2869
2927
|
return {
|
|
2870
2928
|
schema: data.schema,
|
|
2871
2929
|
item
|
|
@@ -2875,12 +2933,15 @@ function useCollectionRendering(collection, locale) {
|
|
|
2875
2933
|
if (field.type === "money") return formatMoney(value, resolveCurrency(field, record), locale.value);
|
|
2876
2934
|
return detailText(value);
|
|
2877
2935
|
}
|
|
2878
|
-
|
|
2936
|
+
/** Build the read-only embed view-models for one record. A function of
|
|
2937
|
+
* the open record (not a bare computed) because a per-record `idField`
|
|
2938
|
+
* embed resolves a different target per row. */
|
|
2939
|
+
function embedViewsFor(record) {
|
|
2879
2940
|
const out = {};
|
|
2880
2941
|
if (!collection.value) return out;
|
|
2881
2942
|
for (const [key, field] of Object.entries(collection.value.schema.fields)) {
|
|
2882
2943
|
if (field.type !== "embed") continue;
|
|
2883
|
-
const { schema, item } = resolveEmbed(field);
|
|
2944
|
+
const { schema, item } = resolveEmbed(field, record);
|
|
2884
2945
|
const rows = [];
|
|
2885
2946
|
if (schema && item) for (const [subKey, subField] of Object.entries(schema.fields)) {
|
|
2886
2947
|
const value = item[subKey];
|
|
@@ -2897,11 +2958,11 @@ function useCollectionRendering(collection, locale) {
|
|
|
2897
2958
|
found: Boolean(item),
|
|
2898
2959
|
rows,
|
|
2899
2960
|
targetSlug: field.to ?? "",
|
|
2900
|
-
recordId: field
|
|
2961
|
+
recordId: embedTargetId(field, record)
|
|
2901
2962
|
};
|
|
2902
2963
|
}
|
|
2903
2964
|
return out;
|
|
2904
|
-
}
|
|
2965
|
+
}
|
|
2905
2966
|
function resolveCurrency(field, record) {
|
|
2906
2967
|
if (field.currencyField && record) {
|
|
2907
2968
|
const code = record[field.currencyField];
|
|
@@ -2992,7 +3053,8 @@ function useCollectionRendering(collection, locale) {
|
|
|
2992
3053
|
loadLinkedCollections,
|
|
2993
3054
|
refDisplay,
|
|
2994
3055
|
refOptions,
|
|
2995
|
-
|
|
3056
|
+
embedOptions,
|
|
3057
|
+
embedViewsFor,
|
|
2996
3058
|
resolveCurrency,
|
|
2997
3059
|
currencySymbol,
|
|
2998
3060
|
formatMoney,
|