@mmlogic/components 0.5.15 → 0.5.16
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/cjs/loader.cjs.js +1 -1
- package/dist/cjs/mosterdcomponents.cjs.js +1 -1
- package/dist/cjs/mrd-boolean-field_28.cjs.entry.js +209 -42
- package/dist/collection/components/form/mrd-field/mrd-field.css +69 -0
- package/dist/collection/components/form/mrd-field/mrd-field.js +95 -25
- package/dist/collection/components/layout/mrd-layout-section/field-value.js +19 -2
- package/dist/collection/components/layout/mrd-layout-section/layout-helpers.js +10 -0
- package/dist/collection/components/layout/mrd-layout-section/mrd-layout-section.css +4 -3
- package/dist/collection/components/layout/mrd-layout-section/mrd-layout-section.js +48 -10
- package/dist/collection/components/memo/mrd-memo-container/mrd-memo-container.js +78 -3
- package/dist/collection/components/memo/mrd-memo-list/mrd-memo-list.css +14 -0
- package/dist/collection/components/memo/mrd-memo-list/mrd-memo-list.js +50 -2
- package/dist/collection/dev/app.js +13 -15
- package/dist/collection/dev/example-data.js +15 -1
- package/dist/components/mrd-field2.js +1 -1
- package/dist/components/mrd-layout-section.js +1 -1
- package/dist/components/mrd-memo-container2.js +1 -1
- package/dist/components/mrd-memo-list2.js +1 -1
- package/dist/esm/loader.js +1 -1
- package/dist/esm/mosterdcomponents.js +1 -1
- package/dist/esm/mrd-boolean-field_28.entry.js +209 -42
- package/dist/mosterdcomponents/cell-renderer-CMUxFREW.js.map +1 -0
- package/dist/mosterdcomponents/client-layout-BJkVeSq6.js.map +1 -0
- package/dist/mosterdcomponents/document-attachments-BufPmMRv.js.map +1 -0
- package/dist/mosterdcomponents/field-helpers-BWAp5fD8.js.map +1 -0
- package/dist/mosterdcomponents/file-upload-common-DDWuC9-3.js.map +1 -0
- package/dist/mosterdcomponents/format-gcecItcD.js.map +1 -0
- package/dist/mosterdcomponents/i18n-OzbszktW.js.map +1 -0
- package/dist/mosterdcomponents/index-1ayBojyN.js.map +1 -0
- package/dist/mosterdcomponents/index-CkcFwdPc.js.map +1 -0
- package/dist/mosterdcomponents/index.esm.js.map +1 -0
- package/dist/mosterdcomponents/mosterdcomponents.esm.js +1 -1
- package/dist/mosterdcomponents/mosterdcomponents.esm.js.map +1 -0
- package/dist/mosterdcomponents/p-8a7fa81d.entry.js +3 -0
- package/dist/mosterdcomponents/purify.es-_duHfPgC.js.map +1 -0
- package/dist/mosterdcomponents/query-params-3TXd5CUO.js.map +1 -0
- package/dist/mosterdcomponents/quill-C9pgw_k-.js.map +1 -0
- package/dist/mosterdcomponents/table-query-DJq1uKqJ.js.map +1 -0
- package/dist/mosterdcomponents/validation-B_0Lx9DE.js.map +1 -0
- package/dist/types/components/form/mrd-field/mrd-field.d.ts +16 -0
- package/dist/types/components/layout/mrd-layout-section/field-value.d.ts +4 -0
- package/dist/types/components/layout/mrd-layout-section/layout-helpers.d.ts +3 -0
- package/dist/types/components/layout/mrd-layout-section/mrd-layout-section.d.ts +5 -0
- package/dist/types/components/memo/mrd-memo-container/mrd-memo-container.d.ts +22 -1
- package/dist/types/components/memo/mrd-memo-list/mrd-memo-list.d.ts +12 -0
- package/dist/types/components.d.ts +43 -0
- package/package.json +1 -1
- package/dist/mosterdcomponents/p-d64ba1f2.entry.js +0 -3
|
@@ -102,4 +102,73 @@
|
|
|
102
102
|
}
|
|
103
103
|
.mrd-field__history-editor-add:hover {
|
|
104
104
|
background-color: var(--mrd-color-primary-light);
|
|
105
|
+
}
|
|
106
|
+
.mrd-field__multi {
|
|
107
|
+
display: flex;
|
|
108
|
+
flex-direction: column;
|
|
109
|
+
gap: var(--mrd-space-1);
|
|
110
|
+
}
|
|
111
|
+
.mrd-field__multi__label {
|
|
112
|
+
display: block;
|
|
113
|
+
font-family: var(--mrd-font-family);
|
|
114
|
+
font-size: var(--mrd-label-font-size);
|
|
115
|
+
font-weight: var(--mrd-label-font-weight);
|
|
116
|
+
color: var(--mrd-label-color);
|
|
117
|
+
}
|
|
118
|
+
.mrd-field__multi__label--required::after {
|
|
119
|
+
content: " *";
|
|
120
|
+
color: var(--mrd-color-danger);
|
|
121
|
+
}
|
|
122
|
+
.mrd-field__multi__error {
|
|
123
|
+
font-family: var(--mrd-font-family);
|
|
124
|
+
font-size: var(--mrd-error-font-size);
|
|
125
|
+
color: var(--mrd-error-color);
|
|
126
|
+
}
|
|
127
|
+
.mrd-field__multi-row {
|
|
128
|
+
display: flex;
|
|
129
|
+
align-items: flex-start;
|
|
130
|
+
gap: var(--mrd-space-2);
|
|
131
|
+
}
|
|
132
|
+
.mrd-field__multi-row-input {
|
|
133
|
+
flex: 1 1 0;
|
|
134
|
+
min-width: 0;
|
|
135
|
+
}
|
|
136
|
+
.mrd-field__multi-remove {
|
|
137
|
+
display: inline-flex;
|
|
138
|
+
align-items: center;
|
|
139
|
+
justify-content: center;
|
|
140
|
+
flex-shrink: 0;
|
|
141
|
+
width: 2rem;
|
|
142
|
+
height: var(--mrd-input-height);
|
|
143
|
+
padding: 0;
|
|
144
|
+
background: transparent;
|
|
145
|
+
border: none;
|
|
146
|
+
border-radius: var(--mrd-border-radius-sm);
|
|
147
|
+
color: var(--mrd-color-neutral-400);
|
|
148
|
+
cursor: pointer;
|
|
149
|
+
transition: color var(--mrd-transition-fast), background-color var(--mrd-transition-fast);
|
|
150
|
+
}
|
|
151
|
+
.mrd-field__multi-remove:hover {
|
|
152
|
+
color: var(--mrd-color-danger);
|
|
153
|
+
background-color: var(--mrd-color-danger-light);
|
|
154
|
+
}
|
|
155
|
+
.mrd-field__multi-remove svg {
|
|
156
|
+
width: 1rem;
|
|
157
|
+
height: 1rem;
|
|
158
|
+
}
|
|
159
|
+
.mrd-field__multi-add {
|
|
160
|
+
align-self: flex-start;
|
|
161
|
+
padding: var(--mrd-space-1) var(--mrd-space-3);
|
|
162
|
+
font-family: var(--mrd-font-family);
|
|
163
|
+
font-size: var(--mrd-font-size-xs);
|
|
164
|
+
font-weight: var(--mrd-font-weight-medium);
|
|
165
|
+
color: var(--mrd-color-primary);
|
|
166
|
+
background: transparent;
|
|
167
|
+
border: var(--mrd-border-width) solid var(--mrd-color-primary);
|
|
168
|
+
border-radius: var(--mrd-border-radius-md);
|
|
169
|
+
cursor: pointer;
|
|
170
|
+
transition: background-color var(--mrd-transition-fast), color var(--mrd-transition-fast);
|
|
171
|
+
}
|
|
172
|
+
.mrd-field__multi-add:hover {
|
|
173
|
+
background-color: var(--mrd-color-primary-light);
|
|
105
174
|
}
|
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
import { Host, h } from "@stencil/core";
|
|
2
2
|
import { ClientLayoutItemType, ClientLayoutItemFieldDataType, ClientLayoutItemRelationDisplayType, } from "../../../types";
|
|
3
3
|
import { t } from "../../../utils/i18n";
|
|
4
|
+
import { FieldLabel, FieldError, requiredError } from "../../fields/field-helpers";
|
|
4
5
|
export class MrdField {
|
|
5
6
|
constructor() {
|
|
6
7
|
this.locale = navigator.language;
|
|
7
8
|
this.historyEntries = [];
|
|
8
9
|
this.currentValue = undefined;
|
|
10
|
+
this.multiValues = [];
|
|
11
|
+
this.multiError = '';
|
|
12
|
+
this.handleMultiRowBlur = () => {
|
|
13
|
+
var _a;
|
|
14
|
+
this.multiError = requiredError(this.multiValues, (_a = this.item.required) !== null && _a !== void 0 ? _a : false, this.locale);
|
|
15
|
+
this.mrdBlur.emit({ name: this.item.name, value: this.multiValues });
|
|
16
|
+
};
|
|
9
17
|
this.handleChange = (e) => {
|
|
10
18
|
var _a, _b, _c, _d;
|
|
11
19
|
e.stopPropagation();
|
|
@@ -50,9 +58,11 @@ export class MrdField {
|
|
|
50
58
|
}
|
|
51
59
|
componentWillLoad() {
|
|
52
60
|
this.initHistoryState();
|
|
61
|
+
this.initMultiState();
|
|
53
62
|
}
|
|
54
63
|
valueChanged() {
|
|
55
64
|
this.initHistoryState();
|
|
65
|
+
this.initMultiState();
|
|
56
66
|
}
|
|
57
67
|
initHistoryState() {
|
|
58
68
|
var _a, _b, _c, _d, _e;
|
|
@@ -63,6 +73,43 @@ export class MrdField {
|
|
|
63
73
|
this.currentValue = (_e = raw === null || raw === void 0 ? void 0 : raw.current) !== null && _e !== void 0 ? _e : raw;
|
|
64
74
|
this.historyEntries = Array.isArray(raw === null || raw === void 0 ? void 0 : raw.history) ? [...raw.history] : [];
|
|
65
75
|
}
|
|
76
|
+
/** LIST/FILE/IMAGE already own their multiple-value UI end to end; every
|
|
77
|
+
* other scalar dataType routes through the generic repeater below instead
|
|
78
|
+
* of each leaf field re-implementing add/remove itself (FINDING-0149). */
|
|
79
|
+
isMultiScalar() {
|
|
80
|
+
var _a, _b;
|
|
81
|
+
if (((_a = this.item) === null || _a === void 0 ? void 0 : _a.type) !== ClientLayoutItemType.FIELD || !((_b = this.item) === null || _b === void 0 ? void 0 : _b.multiple))
|
|
82
|
+
return false;
|
|
83
|
+
const dt = this.item.dataType;
|
|
84
|
+
return dt !== ClientLayoutItemFieldDataType.LIST
|
|
85
|
+
&& dt !== ClientLayoutItemFieldDataType.FILE
|
|
86
|
+
&& dt !== ClientLayoutItemFieldDataType.IMAGE;
|
|
87
|
+
}
|
|
88
|
+
initMultiState() {
|
|
89
|
+
if (!this.isMultiScalar())
|
|
90
|
+
return;
|
|
91
|
+
const v = this.value;
|
|
92
|
+
this.multiValues = Array.isArray(v) ? [...v] : (v != null && v !== '' ? [v] : []);
|
|
93
|
+
}
|
|
94
|
+
emptyRowValue() {
|
|
95
|
+
var _a;
|
|
96
|
+
switch (this.item.dataType) {
|
|
97
|
+
case ClientLayoutItemFieldDataType.INTEGER:
|
|
98
|
+
case ClientLayoutItemFieldDataType.DECIMAL:
|
|
99
|
+
case ClientLayoutItemFieldDataType.PERCENTAGE:
|
|
100
|
+
return null;
|
|
101
|
+
case ClientLayoutItemFieldDataType.CURRENCY:
|
|
102
|
+
return { amount: null, currency: (_a = this.item.currencyCode) !== null && _a !== void 0 ? _a : 'EUR' };
|
|
103
|
+
case ClientLayoutItemFieldDataType.BOOLEAN:
|
|
104
|
+
return false;
|
|
105
|
+
default:
|
|
106
|
+
return '';
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
emitMultiChange(values) {
|
|
110
|
+
this.multiValues = values;
|
|
111
|
+
this.mrdChange.emit({ name: this.item.name, value: values });
|
|
112
|
+
}
|
|
66
113
|
getDisplayValue() {
|
|
67
114
|
var _a, _b, _c, _d;
|
|
68
115
|
const hist = (_b = (_a = this.item) === null || _a === void 0 ? void 0 : _a.historyEnabled) !== null && _b !== void 0 ? _b : (_d = (_c = this.item) === null || _c === void 0 ? void 0 : _c.field) === null || _d === void 0 ? void 0 : _d.historyEnabled;
|
|
@@ -91,6 +138,9 @@ export class MrdField {
|
|
|
91
138
|
value: { current: this.currentValue, history: entries },
|
|
92
139
|
});
|
|
93
140
|
}
|
|
141
|
+
renderRemoveIcon() {
|
|
142
|
+
return (h("svg", { viewBox: "0 0 20 20", fill: "currentColor", "aria-hidden": "true" }, h("path", { "fill-rule": "evenodd", d: "M8.75 1A2.75 2.75 0 006 3.75v.443c-.795.077-1.584.176-2.365.298a.75.75 0 10.23 1.482l.149-.022.841 10.518A2.75 2.75 0 007.596 19h4.807a2.75 2.75 0 002.742-2.53l.841-10.52.149.023a.75.75 0 00.23-1.482A41.03 41.03 0 0014 4.193V3.75A2.75 2.75 0 0011.25 1h-2.5zM10 4c.84 0 1.673.025 2.5.075V3.75c0-.69-.56-1.25-1.25-1.25h-2.5c-.69 0-1.25.56-1.25 1.25v.325C8.327 4.025 9.16 4 10 4zM8.58 7.72a.75.75 0 00-1.5.06l.3 7.5a.75.75 0 101.5-.06l-.3-7.5zm4.34.06a.75.75 0 10-1.5-.06l-.3 7.5a.75.75 0 101.5.06l.3-7.5z", "clip-rule": "evenodd" })));
|
|
143
|
+
}
|
|
94
144
|
renderHistoryEditor() {
|
|
95
145
|
var _a, _b, _c, _d;
|
|
96
146
|
const hist = (_b = (_a = this.item) === null || _a === void 0 ? void 0 : _a.historyEnabled) !== null && _b !== void 0 ? _b : (_d = (_c = this.item) === null || _c === void 0 ? void 0 : _c.field) === null || _d === void 0 ? void 0 : _d.historyEnabled;
|
|
@@ -108,62 +158,80 @@ export class MrdField {
|
|
|
108
158
|
const addEntry = () => {
|
|
109
159
|
this.emitHistoryChange([...this.historyEntries, { value: '', until: '' }]);
|
|
110
160
|
};
|
|
111
|
-
return (h("div", { class: "mrd-field__history-editor" }, this.historyEntries.length > 0 && (h("span", { class: "mrd-field__history-editor-label" }, t('history_badge_tooltip', locale))), this.historyEntries.map((entry, i) => (h("div", { key: String(i), class: "mrd-field__history-editor-row" }, h("input", { class: "mrd-field__history-editor-value", type: valueType, value: entry.value, onInput: (e) => updateEntry(i, 'value', e.target.value) }), h("span", { class: "mrd-field__history-editor-sep" }, t('history_until', locale)), h("input", { class: "mrd-field__history-editor-until", type: "date", value: entry.until, onInput: (e) => updateEntry(i, 'until', e.target.value) }), h("button", { type: "button", class: "mrd-field__history-editor-remove", onClick: () => removeEntry(i), "aria-label": t('remove', locale) },
|
|
161
|
+
return (h("div", { class: "mrd-field__history-editor" }, this.historyEntries.length > 0 && (h("span", { class: "mrd-field__history-editor-label" }, t('history_badge_tooltip', locale))), this.historyEntries.map((entry, i) => (h("div", { key: String(i), class: "mrd-field__history-editor-row" }, h("input", { class: "mrd-field__history-editor-value", type: valueType, value: entry.value, onInput: (e) => updateEntry(i, 'value', e.target.value) }), h("span", { class: "mrd-field__history-editor-sep" }, t('history_until', locale)), h("input", { class: "mrd-field__history-editor-until", type: "date", value: entry.until, onInput: (e) => updateEntry(i, 'until', e.target.value) }), h("button", { type: "button", class: "mrd-field__history-editor-remove", onClick: () => removeEntry(i), "aria-label": t('remove', locale) }, this.renderRemoveIcon())))), h("button", { type: "button", class: "mrd-field__history-editor-add", onClick: addEntry }, "+ ", t('add', locale))));
|
|
112
162
|
}
|
|
113
|
-
renderLeafField(displayValue) {
|
|
114
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6;
|
|
163
|
+
renderLeafField(displayValue, onChange = this.handleChange, onBlur = this.handleBlur, overrides = {}) {
|
|
164
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8;
|
|
115
165
|
const { item, locale } = this;
|
|
116
166
|
const commonProps = {
|
|
117
167
|
name: item.name,
|
|
118
|
-
label: item.label,
|
|
119
|
-
required: item.required,
|
|
120
|
-
disabled: (
|
|
168
|
+
label: (_a = overrides.label) !== null && _a !== void 0 ? _a : item.label,
|
|
169
|
+
required: (_b = overrides.required) !== null && _b !== void 0 ? _b : item.required,
|
|
170
|
+
disabled: (_c = item.disabled) !== null && _c !== void 0 ? _c : false,
|
|
121
171
|
locale,
|
|
122
|
-
onMrdChange:
|
|
123
|
-
onMrdBlur:
|
|
172
|
+
onMrdChange: onChange,
|
|
173
|
+
onMrdBlur: onBlur,
|
|
124
174
|
};
|
|
125
175
|
switch (item.dataType) {
|
|
126
176
|
case ClientLayoutItemFieldDataType.TEXT:
|
|
127
|
-
return (h("mrd-text-field", Object.assign({}, commonProps, { value: (
|
|
177
|
+
return (h("mrd-text-field", Object.assign({}, commonProps, { value: (_d = displayValue) !== null && _d !== void 0 ? _d : '', placeholder: (_e = item.placeholder) !== null && _e !== void 0 ? _e : '' })));
|
|
128
178
|
case ClientLayoutItemFieldDataType.TEXTBLOCK:
|
|
129
|
-
return (h("mrd-textarea-field", Object.assign({}, commonProps, { value: (
|
|
179
|
+
return (h("mrd-textarea-field", Object.assign({}, commonProps, { value: (_f = displayValue) !== null && _f !== void 0 ? _f : '', placeholder: (_g = item.placeholder) !== null && _g !== void 0 ? _g : '' })));
|
|
130
180
|
case ClientLayoutItemFieldDataType.INTEGER:
|
|
131
181
|
case ClientLayoutItemFieldDataType.DECIMAL:
|
|
132
182
|
case ClientLayoutItemFieldDataType.PERCENTAGE:
|
|
133
|
-
return (h("mrd-number-field", Object.assign({}, commonProps, { value: (
|
|
183
|
+
return (h("mrd-number-field", Object.assign({}, commonProps, { value: (_h = displayValue) !== null && _h !== void 0 ? _h : null, dataType: item.dataType, decimalPrecision: (_j = item.decimalPrecision) !== null && _j !== void 0 ? _j : 2, placeholder: (_k = item.placeholder) !== null && _k !== void 0 ? _k : '' })));
|
|
134
184
|
case ClientLayoutItemFieldDataType.CURRENCY:
|
|
135
185
|
return (h("mrd-currency-field", Object.assign({}, commonProps, {
|
|
136
186
|
// Input-only fallback: it preselects the layout's currencyCode in the dropdown
|
|
137
187
|
// before an amount exists. The field never emits this shape back — an empty
|
|
138
188
|
// amount emits null (FINDING-0141).
|
|
139
|
-
value: (
|
|
189
|
+
value: (_l = displayValue) !== null && _l !== void 0 ? _l : { amount: null, currency: (_m = item.currencyCode) !== null && _m !== void 0 ? _m : 'EUR' }
|
|
140
190
|
})));
|
|
141
191
|
case ClientLayoutItemFieldDataType.BOOLEAN:
|
|
142
|
-
return (h("mrd-boolean-field", Object.assign({}, commonProps, { value: (
|
|
192
|
+
return (h("mrd-boolean-field", Object.assign({}, commonProps, { value: (_o = displayValue) !== null && _o !== void 0 ? _o : false })));
|
|
143
193
|
case ClientLayoutItemFieldDataType.DATE:
|
|
144
|
-
return (h("mrd-date-field", Object.assign({}, commonProps, { value: (
|
|
194
|
+
return (h("mrd-date-field", Object.assign({}, commonProps, { value: (_p = displayValue) !== null && _p !== void 0 ? _p : '' })));
|
|
145
195
|
case ClientLayoutItemFieldDataType.DATETIME:
|
|
146
|
-
return (h("mrd-datetime-field", Object.assign({}, commonProps, { value: (
|
|
196
|
+
return (h("mrd-datetime-field", Object.assign({}, commonProps, { value: (_q = displayValue) !== null && _q !== void 0 ? _q : '' })));
|
|
147
197
|
case ClientLayoutItemFieldDataType.TIME:
|
|
148
|
-
return (h("mrd-time-field", Object.assign({}, commonProps, { value: (
|
|
198
|
+
return (h("mrd-time-field", Object.assign({}, commonProps, { value: (_r = displayValue) !== null && _r !== void 0 ? _r : '' })));
|
|
149
199
|
case ClientLayoutItemFieldDataType.EMAIL:
|
|
150
|
-
return (h("mrd-email-field", Object.assign({}, commonProps, { value: (
|
|
200
|
+
return (h("mrd-email-field", Object.assign({}, commonProps, { value: (_s = displayValue) !== null && _s !== void 0 ? _s : '', placeholder: (_t = item.placeholder) !== null && _t !== void 0 ? _t : '' })));
|
|
151
201
|
case ClientLayoutItemFieldDataType.HYPERLINK:
|
|
152
|
-
return (h("mrd-hyperlink-field", Object.assign({}, commonProps, { value: (
|
|
202
|
+
return (h("mrd-hyperlink-field", Object.assign({}, commonProps, { value: (_u = displayValue) !== null && _u !== void 0 ? _u : '', placeholder: (_v = item.placeholder) !== null && _v !== void 0 ? _v : '' })));
|
|
153
203
|
case ClientLayoutItemFieldDataType.LIST:
|
|
154
|
-
return (h("mrd-list-field", Object.assign({}, commonProps, { value: (
|
|
204
|
+
return (h("mrd-list-field", Object.assign({}, commonProps, { value: (_w = displayValue) !== null && _w !== void 0 ? _w : '', multiple: (_x = item.multiple) !== null && _x !== void 0 ? _x : false, listItems: (_y = item.listItems) !== null && _y !== void 0 ? _y : [] })));
|
|
155
205
|
case ClientLayoutItemFieldDataType.FILE:
|
|
156
|
-
return (h("mrd-file-field", Object.assign({}, commonProps, { value: displayValue, accept: (
|
|
206
|
+
return (h("mrd-file-field", Object.assign({}, commonProps, { value: displayValue, accept: (_z = item.accept) !== null && _z !== void 0 ? _z : '', maxSize: (_0 = item.maxSize) !== null && _0 !== void 0 ? _0 : 0, multiple: (_1 = item.multiple) !== null && _1 !== void 0 ? _1 : false, onMrdUpload: this.handleUpload })));
|
|
157
207
|
case ClientLayoutItemFieldDataType.IMAGE:
|
|
158
|
-
return (h("mrd-image-field", Object.assign({}, commonProps, { value: displayValue, accept: (
|
|
208
|
+
return (h("mrd-image-field", Object.assign({}, commonProps, { value: displayValue, accept: (_2 = item.accept) !== null && _2 !== void 0 ? _2 : 'image/*', maxSize: (_3 = item.maxSize) !== null && _3 !== void 0 ? _3 : 0, multiple: (_4 = item.multiple) !== null && _4 !== void 0 ? _4 : false, onMrdUpload: this.handleUpload })));
|
|
159
209
|
case ClientLayoutItemFieldDataType.LONGTEXT:
|
|
160
|
-
return (h("mrd-longtext-field", Object.assign({}, commonProps, { value: (
|
|
210
|
+
return (h("mrd-longtext-field", Object.assign({}, commonProps, { value: (_5 = displayValue) !== null && _5 !== void 0 ? _5 : '', placeholder: (_6 = item.placeholder) !== null && _6 !== void 0 ? _6 : '' })));
|
|
161
211
|
case ClientLayoutItemFieldDataType.SECRET:
|
|
162
|
-
return (h("mrd-secret-field", Object.assign({}, commonProps, { value: (
|
|
212
|
+
return (h("mrd-secret-field", Object.assign({}, commonProps, { value: (_7 = displayValue) !== null && _7 !== void 0 ? _7 : '', placeholder: (_8 = item.placeholder) !== null && _8 !== void 0 ? _8 : '' })));
|
|
163
213
|
default:
|
|
164
214
|
return null;
|
|
165
215
|
}
|
|
166
216
|
}
|
|
217
|
+
/** Repeatable-row UI for a scalar dataType with multiple: true — mirrors the
|
|
218
|
+
* add/remove pattern already established by renderHistoryEditor(), reusing
|
|
219
|
+
* the single-row renderLeafField() per entry instead of duplicating repeat
|
|
220
|
+
* UI into every leaf field component (FINDING-0149). */
|
|
221
|
+
renderMultiScalarField() {
|
|
222
|
+
var _a, _b;
|
|
223
|
+
const { item, locale } = this;
|
|
224
|
+
const updateRow = (i, val) => {
|
|
225
|
+
this.emitMultiChange(this.multiValues.map((v, idx) => (idx === i ? val : v)));
|
|
226
|
+
};
|
|
227
|
+
const removeRow = (i) => {
|
|
228
|
+
this.emitMultiChange(this.multiValues.filter((_, idx) => idx !== i));
|
|
229
|
+
};
|
|
230
|
+
const addRow = () => {
|
|
231
|
+
this.emitMultiChange([...this.multiValues, this.emptyRowValue()]);
|
|
232
|
+
};
|
|
233
|
+
return (h("div", { class: "mrd-field__multi" }, h(FieldLabel, { base: "mrd-field__multi", label: (_a = item.label) !== null && _a !== void 0 ? _a : '', required: (_b = item.required) !== null && _b !== void 0 ? _b : false }), this.multiValues.map((v, i) => (h("div", { key: String(i), class: "mrd-field__multi-row" }, h("div", { class: "mrd-field__multi-row-input" }, this.renderLeafField(v, (e) => { e.stopPropagation(); updateRow(i, e.detail.value); }, (e) => { e.stopPropagation(); this.handleMultiRowBlur(); }, { label: '', required: false })), h("button", { type: "button", class: "mrd-field__multi-remove", onClick: () => removeRow(i), "aria-label": t('remove', locale) }, this.renderRemoveIcon())))), h("button", { type: "button", class: "mrd-field__multi-add", onClick: addRow }, "+ ", t('add', locale)), h(FieldError, { base: "mrd-field__multi", error: this.multiError })));
|
|
234
|
+
}
|
|
167
235
|
render() {
|
|
168
236
|
var _a, _b, _c, _d, _e, _f;
|
|
169
237
|
const { item, locale, value } = this;
|
|
@@ -174,7 +242,7 @@ export class MrdField {
|
|
|
174
242
|
return h(Host, null);
|
|
175
243
|
}
|
|
176
244
|
const displayValue = this.getDisplayValue();
|
|
177
|
-
return (h(Host, null, h("div", { class: "mrd-field__inner" }, this.renderLeafField(displayValue), this.renderHistoryEditor())));
|
|
245
|
+
return (h(Host, null, h("div", { class: "mrd-field__inner" }, this.isMultiScalar() ? this.renderMultiScalarField() : this.renderLeafField(displayValue), this.renderHistoryEditor())));
|
|
178
246
|
}
|
|
179
247
|
static get is() { return "mrd-field"; }
|
|
180
248
|
static get encapsulation() { return "scoped"; }
|
|
@@ -256,7 +324,9 @@ export class MrdField {
|
|
|
256
324
|
static get states() {
|
|
257
325
|
return {
|
|
258
326
|
"historyEntries": {},
|
|
259
|
-
"currentValue": {}
|
|
327
|
+
"currentValue": {},
|
|
328
|
+
"multiValues": {},
|
|
329
|
+
"multiError": {}
|
|
260
330
|
};
|
|
261
331
|
}
|
|
262
332
|
static get events() {
|
|
@@ -94,7 +94,7 @@ function renderHistoryBadge(ctx, item, raw) {
|
|
|
94
94
|
ctx.on.toggleHistory(isOpen ? null : item.name);
|
|
95
95
|
} }, h("svg", { class: "mrd-layout-section__history-icon", viewBox: "0 0 20 20", fill: "currentColor", "aria-hidden": "true" }, h("path", { "fill-rule": "evenodd", d: "M10 18a8 8 0 100-16 8 8 0 000 16zm.75-13a.75.75 0 00-1.5 0v5c0 .207.085.394.22.53l2.5 2.5a.75.75 0 101.06-1.06L10.75 9.69V5z", "clip-rule": "evenodd" }))), isOpen && (h("div", { class: "mrd-layout-section__history-popover", role: "listbox" }, sorted.map((entry, i) => (h("div", { key: String(i), class: "mrd-layout-section__history-entry" }, entry.value, " (", t('history_until', ctx.locale), " ", formatDate(entry.until, ctx.locale), ")")))))));
|
|
96
96
|
}
|
|
97
|
-
|
|
97
|
+
function fieldRenderState(ctx, item) {
|
|
98
98
|
var _a, _b;
|
|
99
99
|
if (!item.name)
|
|
100
100
|
return null;
|
|
@@ -104,10 +104,27 @@ export function renderField(ctx, item) {
|
|
|
104
104
|
? raw.current
|
|
105
105
|
: raw;
|
|
106
106
|
const renderedValue = renderFieldValue(ctx, item, rawValue);
|
|
107
|
+
return { raw, rawValue, renderedValue, isEmpty: renderedValue == null };
|
|
108
|
+
}
|
|
109
|
+
/** Whether a FIELD item would render anything at all (value, or a showEmpty
|
|
110
|
+
* placeholder). A `header` field always renders. Used by mrd-layout-section
|
|
111
|
+
* to decide whether a preceding HEADER item's block is entirely empty. */
|
|
112
|
+
export function isFieldVisible(ctx, item) {
|
|
113
|
+
if (item.header)
|
|
114
|
+
return true;
|
|
115
|
+
const state = fieldRenderState(ctx, item);
|
|
116
|
+
if (!state)
|
|
117
|
+
return false;
|
|
118
|
+
return !state.isEmpty || showsEmpty(item);
|
|
119
|
+
}
|
|
120
|
+
export function renderField(ctx, item) {
|
|
121
|
+
const state = fieldRenderState(ctx, item);
|
|
122
|
+
if (!state)
|
|
123
|
+
return null;
|
|
124
|
+
const { raw, rawValue, renderedValue, isEmpty } = state;
|
|
107
125
|
if (item.header) {
|
|
108
126
|
return (h("h1", { class: "mrd-layout-section__field-header", key: item.name }, typeof renderedValue === 'string' ? renderedValue : rawValue != null ? String(rawValue) : item.label));
|
|
109
127
|
}
|
|
110
|
-
const isEmpty = renderedValue == null;
|
|
111
128
|
if (isEmpty && !showsEmpty(item))
|
|
112
129
|
return null;
|
|
113
130
|
const isBlock = item.dataType === ClientLayoutItemFieldDataType.TEXTBLOCK
|
|
@@ -12,6 +12,16 @@ export function showsEmpty(item) {
|
|
|
12
12
|
var _a, _b, _c, _d, _e;
|
|
13
13
|
return (_e = (_c = (_a = item.showEmpty) !== null && _a !== void 0 ? _a : (_b = item.field) === null || _b === void 0 ? void 0 : _b.showEmpty) !== null && _c !== void 0 ? _c : (_d = item.relation) === null || _d === void 0 ? void 0 : _d.showEmpty) !== null && _e !== void 0 ? _e : false;
|
|
14
14
|
}
|
|
15
|
+
/** Whether a RELATION item has a resolvable link value (`_links[item.name]`
|
|
16
|
+
* carries either a multi-value `values[]` or a single `name`). */
|
|
17
|
+
export function hasRelationValue(item, data) {
|
|
18
|
+
var _a, _b;
|
|
19
|
+
if (!item.name)
|
|
20
|
+
return false;
|
|
21
|
+
const links = ((_a = data === null || data === void 0 ? void 0 : data._links) !== null && _a !== void 0 ? _a : {});
|
|
22
|
+
const link = links[item.name];
|
|
23
|
+
return !!(((_b = link === null || link === void 0 ? void 0 : link.values) === null || _b === void 0 ? void 0 : _b.length) || (link === null || link === void 0 ? void 0 : link.name));
|
|
24
|
+
}
|
|
15
25
|
/** Depth-first flatten of the SECTION/GROUP tree. */
|
|
16
26
|
export function flattenItems(items) {
|
|
17
27
|
const result = [];
|
|
@@ -101,10 +101,11 @@
|
|
|
101
101
|
padding: 0;
|
|
102
102
|
}
|
|
103
103
|
.mrd-layout-section__header {
|
|
104
|
-
font-size: var(--mrd-font-size-
|
|
104
|
+
font-size: var(--mrd-font-size-sm);
|
|
105
105
|
font-weight: var(--mrd-font-weight-semibold);
|
|
106
|
-
color: var(--mrd-color-neutral-
|
|
107
|
-
|
|
106
|
+
color: var(--mrd-color-neutral-500);
|
|
107
|
+
letter-spacing: 0.01em;
|
|
108
|
+
margin: var(--mrd-space-5) 0 var(--mrd-space-2) 0;
|
|
108
109
|
padding: 0;
|
|
109
110
|
}
|
|
110
111
|
.mrd-layout-section__text {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Host, h } from "@stencil/core";
|
|
2
2
|
import { ClientLayoutItemType, ClientLayoutItemFieldDataType, ClientLayoutNavigateBehaviour, resolveArchetype, ARCHETYPE_DOCUMENT, ARCHETYPE_INVOICE, ARCHETYPE_EMAIL, ARCHETYPE_INVOICE_LINE, ARCHETYPE_MEMO, } from "../../../types/client-layout";
|
|
3
3
|
import { t } from "../../../utils/i18n";
|
|
4
|
-
import { viewKeyFor, flattenItems, buildContainerHref, showsEmpty } from "./layout-helpers";
|
|
5
|
-
import { renderField } from "./field-value";
|
|
4
|
+
import { viewKeyFor, flattenItems, buildContainerHref, showsEmpty, hasRelationValue } from "./layout-helpers";
|
|
5
|
+
import { renderField, isFieldVisible } from "./field-value";
|
|
6
6
|
export class MrdLayoutSection {
|
|
7
7
|
constructor() {
|
|
8
8
|
/** Items from one layout entry in ClientDashboardMetadata.layouts[]. */
|
|
@@ -212,7 +212,7 @@ export class MrdLayoutSection {
|
|
|
212
212
|
else if (link === null || link === void 0 ? void 0 : link.name) {
|
|
213
213
|
valueContent = makeBtn(link.href, link.name);
|
|
214
214
|
}
|
|
215
|
-
const isEmpty = !
|
|
215
|
+
const isEmpty = !hasRelationValue(item, this.data);
|
|
216
216
|
if (isEmpty && !showsEmpty(item))
|
|
217
217
|
return null;
|
|
218
218
|
return (h("div", { class: `mrd-layout-section__field${isEmpty ? ' mrd-layout-section__field--empty' : ''}`, key: item.name }, h("span", { class: "mrd-layout-section__field-label" }, item.label), h("span", { class: "mrd-layout-section__field-value" }, isEmpty ? t('value_empty', this.locale) : valueContent)));
|
|
@@ -227,7 +227,7 @@ export class MrdLayoutSection {
|
|
|
227
227
|
return (h("div", { class: "mrd-layout-section__search", key: `search-${dataClass}` }, h("div", { class: "mrd-layout-section__search-wrap" }, h("svg", { class: "mrd-layout-section__search-icon", xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 20 20", fill: "currentColor", "aria-hidden": "true" }, h("path", { "fill-rule": "evenodd", d: "M9 3.5a5.5 5.5 0 100 11 5.5 5.5 0 000-11zM2 9a7 7 0 1112.452 4.391l3.328 3.329a.75.75 0 11-1.06 1.06l-3.329-3.328A7 7 0 012 9z", "clip-rule": "evenodd" })), h("input", { class: "mrd-layout-section__search-input", type: "text", value: query, placeholder: (_c = item.label) !== null && _c !== void 0 ? _c : '', onInput: e => this.handleSearchInput(dataClass, e.target.value) })), results.length > 0 && (h("ul", { class: "mrd-layout-section__search-results" }, results.map(r => (h("li", { key: r.id, class: "mrd-layout-section__search-result" }, h("button", { class: "mrd-layout-section__search-result-btn", onClick: () => this.mrdNavigate.emit({ href: r.id, label: r.label }) }, h("span", { class: "mrd-layout-section__search-result-label" }, r.label), r.description && h("span", { class: "mrd-layout-section__search-result-desc" }, r.description)))))))));
|
|
228
228
|
}
|
|
229
229
|
renderRelatedView(item) {
|
|
230
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
230
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
231
231
|
const key = viewKeyFor(item);
|
|
232
232
|
if (!key)
|
|
233
233
|
return null;
|
|
@@ -245,7 +245,20 @@ export class MrdLayoutSection {
|
|
|
245
245
|
// fromClass (base class) rather than the route class, so polymorphic subtypes
|
|
246
246
|
// resolve to the same container the documents actually reference.
|
|
247
247
|
const containerHref = buildContainerHref(item, selfHref, parentId);
|
|
248
|
-
|
|
248
|
+
// A memo RELATED_VIEW isn't necessarily scoped by the container relation —
|
|
249
|
+
// e.g. a person's dashboard can show "memos I authored" via the author
|
|
250
|
+
// relation instead. inverseRelation names which relation on the memo points
|
|
251
|
+
// back to this parent; only when it matches the container slot does the
|
|
252
|
+
// parent's own href double as the memo's container.
|
|
253
|
+
const memoContainerRelated = item.type !== ClientLayoutItemType.RELATED_VIEW
|
|
254
|
+
|| item.inverseRelation === ((_l = memoArchetype === null || memoArchetype === void 0 ? void 0 : memoArchetype.slots) === null || _l === void 0 ? void 0 : _l.container);
|
|
255
|
+
const memoContainerHref = memoContainerRelated ? containerHref : '';
|
|
256
|
+
// Distinct from memoContainerRelated: only a genuine container-scoped
|
|
257
|
+
// RELATED_VIEW (a company's own memo tab) makes every card's container
|
|
258
|
+
// obvious from the page itself. A top-level VIEW or an author-scoped
|
|
259
|
+
// RELATED_VIEW both still need the per-card container link.
|
|
260
|
+
const memoContainerImplied = item.type === ClientLayoutItemType.RELATED_VIEW && memoContainerRelated;
|
|
261
|
+
return (h("div", { class: "mrd-layout-section__related-view", key: `view-${key}` }, showTitle && item.label && h("h3", { class: "mrd-layout-section__related-view-title" }, item.label), docArchetype && this.renderDocumentContainer(item, key, parentId, docArchetype, containerHref), memoArchetype && this.renderMemoContainer(item, key, parentId, memoArchetype, memoContainerHref, memoContainerRelated, !memoContainerImplied), !docArchetype && !memoArchetype && this.renderTable(item, key, parentId)));
|
|
249
262
|
}
|
|
250
263
|
/** Document collection view: owns the view-switch + collection actions and
|
|
251
264
|
* swaps between the folder tree and the flat table. Events are re-emitted to
|
|
@@ -285,10 +298,14 @@ export class MrdLayoutSection {
|
|
|
285
298
|
}
|
|
286
299
|
/** Memo collection view: owns the view-switch + "New memo" and swaps between
|
|
287
300
|
* the card list and the flat table, mirroring renderDocumentContainer(). */
|
|
288
|
-
renderMemoContainer(item, key, parentId, archetype, containerHref) {
|
|
301
|
+
renderMemoContainer(item, key, parentId, archetype, containerHref, containerRelated, showContainerLink) {
|
|
289
302
|
var _a, _b, _c, _d;
|
|
290
303
|
const labelsListItems = (_d = (_c = (_b = (_a = item.view) === null || _a === void 0 ? void 0 : _a.values) === null || _b === void 0 ? void 0 : _b.find(v => { var _a; return v.name === ((_a = archetype.slots) === null || _a === void 0 ? void 0 : _a.labels); })) === null || _c === void 0 ? void 0 : _c.listItems) !== null && _d !== void 0 ? _d : null;
|
|
291
|
-
return (h("mrd-memo-container", { "data-view": key, item: item, archetype: archetype, parentId: parentId, containerHref: containerHref, viewKey: key, locale: this.locale, readOnly: this.readOnly, me: this.me, labelsListItems: labelsListItems,
|
|
304
|
+
return (h("mrd-memo-container", { "data-view": key, item: item, archetype: archetype, parentId: parentId, containerHref: containerHref, containerRelated: containerRelated, showContainerLink: showContainerLink, viewKey: key, locale: this.locale, readOnly: this.readOnly, me: this.me, labelsListItems: labelsListItems, onMrdNavigate: (e) => {
|
|
305
|
+
var _a;
|
|
306
|
+
e.stopPropagation();
|
|
307
|
+
this.mrdNavigate.emit(Object.assign(Object.assign({}, e.detail), { navigateBehaviour: (_a = item.navigateBehaviour) !== null && _a !== void 0 ? _a : ClientLayoutNavigateBehaviour.PAGE }));
|
|
308
|
+
}, onMrdLoadPage: (e) => {
|
|
292
309
|
e.stopPropagation();
|
|
293
310
|
this.mrdLoadViewPage.emit(Object.assign({ name: key }, e.detail));
|
|
294
311
|
}, onMrdLoadAggregations: (e) => {
|
|
@@ -339,7 +356,26 @@ export class MrdLayoutSection {
|
|
|
339
356
|
});
|
|
340
357
|
} }));
|
|
341
358
|
}
|
|
342
|
-
|
|
359
|
+
/** Whether every FIELD/RELATION item following a HEADER (up to the next
|
|
360
|
+
* HEADER/SECTION/GROUP or the end of `siblings`) would itself render
|
|
361
|
+
* nothing — i.e. the HEADER would introduce an empty block. Other item
|
|
362
|
+
* types (VIEW, NAVIGATE, TEXT, ...) always count as visible. */
|
|
363
|
+
isHeaderBlockEmpty(siblings, index) {
|
|
364
|
+
const ctx = this.fieldCtx();
|
|
365
|
+
for (let i = index + 1; i < siblings.length; i++) {
|
|
366
|
+
const sib = siblings[i];
|
|
367
|
+
if (sib.type === ClientLayoutItemType.HEADER || sib.type === ClientLayoutItemType.SECTION || sib.type === ClientLayoutItemType.GROUP)
|
|
368
|
+
break;
|
|
369
|
+
if (sib.type === ClientLayoutItemType.FIELD && isFieldVisible(ctx, sib))
|
|
370
|
+
return false;
|
|
371
|
+
if (sib.type === ClientLayoutItemType.RELATION && (hasRelationValue(sib, this.data) || showsEmpty(sib)))
|
|
372
|
+
return false;
|
|
373
|
+
if (sib.type !== ClientLayoutItemType.FIELD && sib.type !== ClientLayoutItemType.RELATION)
|
|
374
|
+
return false;
|
|
375
|
+
}
|
|
376
|
+
return true;
|
|
377
|
+
}
|
|
378
|
+
renderItem(item, siblings = this.items, index = -1) {
|
|
343
379
|
var _a, _b;
|
|
344
380
|
switch (item.type) {
|
|
345
381
|
case ClientLayoutItemType.FIELD:
|
|
@@ -347,6 +383,8 @@ export class MrdLayoutSection {
|
|
|
347
383
|
case ClientLayoutItemType.RELATION:
|
|
348
384
|
return this.renderRelation(item);
|
|
349
385
|
case ClientLayoutItemType.HEADER:
|
|
386
|
+
if (index >= 0 && this.isHeaderBlockEmpty(siblings, index))
|
|
387
|
+
return null;
|
|
350
388
|
return (h("h2", { class: "mrd-layout-section__header", key: `header-${item.label}` }, item.label));
|
|
351
389
|
case ClientLayoutItemType.TEXT:
|
|
352
390
|
return h("div", { class: "mrd-layout-section__text", key: `text-${item.label}`, innerHTML: (_a = item.label) !== null && _a !== void 0 ? _a : '' });
|
|
@@ -356,7 +394,7 @@ export class MrdLayoutSection {
|
|
|
356
394
|
return this.renderSearch(item);
|
|
357
395
|
case ClientLayoutItemType.SECTION:
|
|
358
396
|
case ClientLayoutItemType.GROUP:
|
|
359
|
-
return (h("div", { class: "mrd-layout-section__group", key: `group-${item.label}` }, item.label && h("h3", { class: "mrd-layout-section__group-title" }, item.label), ((_b = item.items) !== null && _b !== void 0 ? _b : []).map(child => this.renderItem(child))));
|
|
397
|
+
return (h("div", { class: "mrd-layout-section__group", key: `group-${item.label}` }, item.label && h("h3", { class: "mrd-layout-section__group-title" }, item.label), ((_b = item.items) !== null && _b !== void 0 ? _b : []).map((child, i) => { var _a; return this.renderItem(child, (_a = item.items) !== null && _a !== void 0 ? _a : [], i); })));
|
|
360
398
|
case ClientLayoutItemType.RELATED_VIEW:
|
|
361
399
|
case ClientLayoutItemType.VIEW:
|
|
362
400
|
return this.renderRelatedView(item);
|
|
@@ -428,7 +466,7 @@ export class MrdLayoutSection {
|
|
|
428
466
|
const emailArchetype = !docArchetype && !invoiceArchetype ? resolveArchetype(this.archetypes, ARCHETYPE_EMAIL) : undefined;
|
|
429
467
|
const memoArchetype = !docArchetype && !invoiceArchetype && !emailArchetype ? resolveArchetype(this.archetypes, ARCHETYPE_MEMO) : undefined;
|
|
430
468
|
const anyArchetype = docArchetype || invoiceArchetype || emailArchetype || memoArchetype;
|
|
431
|
-
return (h(Host, { key: '
|
|
469
|
+
return (h(Host, { key: '057d145da172e68f84b6ff34f71ae649d6d6bf92' }, h("div", { key: 'e03a1761dc6bcd9ff54b264fee56130270bddc2f', class: "mrd-layout-section" }, docArchetype && this.renderDocumentObject(docArchetype), invoiceArchetype && this.renderInvoiceObject(invoiceArchetype), emailArchetype && this.renderEmailObject(emailArchetype), memoArchetype && this.renderMemoObject(memoArchetype), !anyArchetype && this.items.map((item, i) => this.renderItem(item, this.items, i))), this.renderImageModal()));
|
|
432
470
|
}
|
|
433
471
|
static get is() { return "mrd-layout-section"; }
|
|
434
472
|
static get encapsulation() { return "scoped"; }
|
|
@@ -29,6 +29,20 @@ export class MrdMemoContainer {
|
|
|
29
29
|
/** Canonical parent href — set when this is a RELATED_VIEW embedded under a
|
|
30
30
|
* parent record, which already gives a new memo something to attach to. */
|
|
31
31
|
this.containerHref = '';
|
|
32
|
+
/** False when this RELATED_VIEW's parent is related via a relation other than
|
|
33
|
+
* the archetype's container slot (e.g. a person's "memos I authored" list,
|
|
34
|
+
* related via `author`) — mrd-layout-section resolves this from the item's
|
|
35
|
+
* `inverseRelation`. In that case the parent is not a valid container for a
|
|
36
|
+
* new memo, and — unlike a top-level VIEW with no context at all — falling
|
|
37
|
+
* back to `me` would be wrong too (creating a memo "on myself" from someone
|
|
38
|
+
* else's authored-memos list makes no sense), so "New memo" is hidden outright. */
|
|
39
|
+
this.containerRelated = true;
|
|
40
|
+
/** True unless this is a container-scoped RELATED_VIEW (a company's own memo
|
|
41
|
+
* tab, say) where every card's container is obviously the page you're
|
|
42
|
+
* already on — forwarded to mrd-memo-list to show/hide its per-card
|
|
43
|
+
* container link. A top-level VIEW or an author-scoped RELATED_VIEW both
|
|
44
|
+
* still need it, since the container isn't implied by the page context. */
|
|
45
|
+
this.showContainerLink = true;
|
|
32
46
|
/** Lookup key used for the embedded `data-view` attribute. */
|
|
33
47
|
this.viewKey = '';
|
|
34
48
|
this.locale = navigator.language;
|
|
@@ -260,8 +274,11 @@ export class MrdMemoContainer {
|
|
|
260
274
|
return !!((_b = (_a = this.archetype) === null || _a === void 0 ? void 0 : _a.slots) === null || _b === void 0 ? void 0 : _b.important);
|
|
261
275
|
}
|
|
262
276
|
/** A parent record already gives a new memo somewhere to attach to (RELATED_VIEW);
|
|
263
|
-
* otherwise fall back to the account's own linked person (top-level VIEW)
|
|
277
|
+
* otherwise fall back to the account's own linked person (top-level VIEW) — but
|
|
278
|
+
* only when containerRelated allows it (see its doc comment). */
|
|
264
279
|
get effectiveContainerHref() {
|
|
280
|
+
if (!this.containerRelated)
|
|
281
|
+
return '';
|
|
265
282
|
return this.containerHref || this.meHref();
|
|
266
283
|
}
|
|
267
284
|
/** The author slot is always filled from `me` (there is no author picker in
|
|
@@ -307,12 +324,15 @@ export class MrdMemoContainer {
|
|
|
307
324
|
return (h("div", { class: "mrd-memo-container__modal-backdrop", onClick: this.closeDialog }, h("div", { class: "mrd-memo-container__modal", onClick: (e) => e.stopPropagation() }, this.deleteConfirmOpen ? this.renderDeleteConfirm() : this.renderForm())));
|
|
308
325
|
}
|
|
309
326
|
renderCards() {
|
|
310
|
-
return (h("mrd-memo-list", { "data-view": this.viewKey, ref: el => (this.listEl = el), item: this.item, archetype: this.archetype, parentId: this.parentId, locale: this.locale, readOnly: this.readOnly, labelsListItems: this.labelsListItems, onMrdLoadPage: (e) => {
|
|
327
|
+
return (h("mrd-memo-list", { "data-view": this.viewKey, ref: el => (this.listEl = el), item: this.item, archetype: this.archetype, parentId: this.parentId, locale: this.locale, readOnly: this.readOnly, labelsListItems: this.labelsListItems, showContainerLink: this.showContainerLink, onMrdLoadPage: (e) => {
|
|
311
328
|
e.stopPropagation();
|
|
312
329
|
this.mrdLoadPage.emit(e.detail);
|
|
313
330
|
}, onMrdEdit: (e) => {
|
|
314
331
|
e.stopPropagation();
|
|
315
332
|
this.openEdit(e.detail.row);
|
|
333
|
+
}, onMrdNavigate: (e) => {
|
|
334
|
+
e.stopPropagation();
|
|
335
|
+
this.mrdNavigate.emit(e.detail);
|
|
316
336
|
} }));
|
|
317
337
|
}
|
|
318
338
|
renderTable() {
|
|
@@ -331,7 +351,7 @@ export class MrdMemoContainer {
|
|
|
331
351
|
} }));
|
|
332
352
|
}
|
|
333
353
|
render() {
|
|
334
|
-
return (h(Host, { key: '
|
|
354
|
+
return (h(Host, { key: 'a000221db6b1ba12351f38619f319b277b791f68' }, this.renderToolbar(), h("div", { key: '712951c8e391ed693bf6e4263c4f1076172b0451', class: "mrd-memo-container__body" }, this.mode === 'cards' ? this.renderCards() : this.renderTable()), this.renderDialog()));
|
|
335
355
|
}
|
|
336
356
|
static get is() { return "mrd-memo-container"; }
|
|
337
357
|
static get encapsulation() { return "scoped"; }
|
|
@@ -436,6 +456,46 @@ export class MrdMemoContainer {
|
|
|
436
456
|
"attribute": "container-href",
|
|
437
457
|
"defaultValue": "''"
|
|
438
458
|
},
|
|
459
|
+
"containerRelated": {
|
|
460
|
+
"type": "boolean",
|
|
461
|
+
"mutable": false,
|
|
462
|
+
"complexType": {
|
|
463
|
+
"original": "boolean",
|
|
464
|
+
"resolved": "boolean",
|
|
465
|
+
"references": {}
|
|
466
|
+
},
|
|
467
|
+
"required": false,
|
|
468
|
+
"optional": false,
|
|
469
|
+
"docs": {
|
|
470
|
+
"tags": [],
|
|
471
|
+
"text": "False when this RELATED_VIEW's parent is related via a relation other than\nthe archetype's container slot (e.g. a person's \"memos I authored\" list,\nrelated via `author`) \u2014 mrd-layout-section resolves this from the item's\n`inverseRelation`. In that case the parent is not a valid container for a\nnew memo, and \u2014 unlike a top-level VIEW with no context at all \u2014 falling\nback to `me` would be wrong too (creating a memo \"on myself\" from someone\nelse's authored-memos list makes no sense), so \"New memo\" is hidden outright."
|
|
472
|
+
},
|
|
473
|
+
"getter": false,
|
|
474
|
+
"setter": false,
|
|
475
|
+
"reflect": false,
|
|
476
|
+
"attribute": "container-related",
|
|
477
|
+
"defaultValue": "true"
|
|
478
|
+
},
|
|
479
|
+
"showContainerLink": {
|
|
480
|
+
"type": "boolean",
|
|
481
|
+
"mutable": false,
|
|
482
|
+
"complexType": {
|
|
483
|
+
"original": "boolean",
|
|
484
|
+
"resolved": "boolean",
|
|
485
|
+
"references": {}
|
|
486
|
+
},
|
|
487
|
+
"required": false,
|
|
488
|
+
"optional": false,
|
|
489
|
+
"docs": {
|
|
490
|
+
"tags": [],
|
|
491
|
+
"text": "True unless this is a container-scoped RELATED_VIEW (a company's own memo\ntab, say) where every card's container is obviously the page you're\nalready on \u2014 forwarded to mrd-memo-list to show/hide its per-card\ncontainer link. A top-level VIEW or an author-scoped RELATED_VIEW both\nstill need it, since the container isn't implied by the page context."
|
|
492
|
+
},
|
|
493
|
+
"getter": false,
|
|
494
|
+
"setter": false,
|
|
495
|
+
"reflect": false,
|
|
496
|
+
"attribute": "show-container-link",
|
|
497
|
+
"defaultValue": "true"
|
|
498
|
+
},
|
|
439
499
|
"viewKey": {
|
|
440
500
|
"type": "string",
|
|
441
501
|
"mutable": false,
|
|
@@ -592,6 +652,21 @@ export class MrdMemoContainer {
|
|
|
592
652
|
"resolved": "{ path: string; qs: string; aggQs: string; }",
|
|
593
653
|
"references": {}
|
|
594
654
|
}
|
|
655
|
+
}, {
|
|
656
|
+
"method": "mrdNavigate",
|
|
657
|
+
"name": "mrdNavigate",
|
|
658
|
+
"bubbles": true,
|
|
659
|
+
"cancelable": true,
|
|
660
|
+
"composed": true,
|
|
661
|
+
"docs": {
|
|
662
|
+
"tags": [],
|
|
663
|
+
"text": "A card's container link was clicked \u2014 real navigation, unrelated to the\nquick-edit dialog (mrdEdit is internal, handled by this component itself)."
|
|
664
|
+
},
|
|
665
|
+
"complexType": {
|
|
666
|
+
"original": "{ href?: string; label: string }",
|
|
667
|
+
"resolved": "{ href?: string | undefined; label: string; }",
|
|
668
|
+
"references": {}
|
|
669
|
+
}
|
|
595
670
|
}, {
|
|
596
671
|
"method": "mrdAction",
|
|
597
672
|
"name": "mrdAction",
|