@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
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"table-query-DJq1uKqJ.js","sources":["src/components/table/mrd-table/table-query.ts"],"sourcesContent":["import { ColumnFilter, TableColumn } from '../../../utils/cell-renderer';\nimport { ViewFilter } from '../../../types/client-layout';\nimport { applyViewFilters } from '../../../utils/query-params';\n\n/**\n * Pure sort/filter/aggregation query logic for mrd-table.\n * No component state — everything is passed in.\n */\n\nexport const TEXT_TYPES = new Set(['TEXT', 'TEXTBLOCK', 'EMAIL', 'HYPERLINK']);\nexport const NUMERIC_TYPES = new Set(['INTEGER', 'DECIMAL', 'PERCENTAGE', 'CURRENCY']);\nexport const DATE_TYPES = new Set(['DATE', 'DATETIME', 'TIME']);\nexport const NO_FILTER_TYPES = new Set(['FILE', 'IMAGE']);\n\n/** Column types that cannot be sorted or filtered (not stored in PostgreSQL). */\nexport const NON_INTERACTIVE_TYPES = new Set(['LONGTEXT', 'JSON', 'FILE', 'IMAGE']);\n\n/** Wait this long (ms) after the user stops typing in the free-text search box\n * before firing the search request — mirrors REQUEST_DEBOUNCE_MS's purpose\n * (skip intermediate keystrokes) but is tuned for typing, not scrolling. */\nexport const SEARCH_DEBOUNCE_MS = 400;\n\nexport function parseDefaultSort(defaultSort: string): { field: string; dir: 'asc' | 'desc' } {\n if (!defaultSort) return { field: '', dir: 'asc' };\n const parts = defaultSort.split(',');\n return { field: parts[0].trim(), dir: parts[1]?.trim() === 'desc' ? 'desc' : 'asc' };\n}\n\n/** Raw sort query-param value, e.g. \"name\" or \"name,desc\". */\nexport function buildSortParam(field: string, dir: 'asc' | 'desc'): string {\n if (!field) return '';\n return dir === 'desc' ? `${field},desc` : field;\n}\n\n/** Query params for a page request: page + sort + filterClass + view filters + active column filters. */\nexport function buildTableQueryParams(opts: {\n page: number;\n sort: string;\n filterClass?: string | null;\n viewFilters?: ViewFilter[] | null;\n activeFilters: Iterable<ColumnFilter>;\n /** Free-text search query from the toolbar's search box (VIEW only). */\n query?: string;\n}): string {\n const p = new URLSearchParams();\n if (opts.page > 0) p.set('page', String(opts.page));\n if (opts.sort) p.set('sort', opts.sort);\n if (opts.filterClass) p.set('type', opts.filterClass);\n applyViewFilters(p, opts.viewFilters);\n if (opts.query) p.set('q', opts.query);\n for (const f of opts.activeFilters) {\n if (f.operator === 'isEmpty') { p.set(f.field, ''); continue; }\n if (f.operator === 'isNotEmpty') { p.set(f.field + '_notempty', 'true'); continue; }\n if (f.operator === 'startsWith') { p.set(f.field + '_startswith', String(f.value ?? '')); continue; }\n if (f.values?.length) { p.set(f.field, f.values.join(',')); continue; }\n if (f.value != null) p.set(f.field, String(f.value));\n if (f.from != null) p.set(f.field + '_from', String(f.from));\n if (f.to != null) p.set(f.field + '_to', String(f.to));\n }\n return p.toString();\n}\n\n/** Groups aggregate columns by function; null when the view has no aggregates. */\nexport function buildAggregationParams(columns: TableColumn[]): { sum?: string[]; avg?: string[]; count?: string[] } | null {\n const groups: { sum: string[]; avg: string[]; count: string[] } = { sum: [], avg: [], count: [] };\n for (const col of columns) {\n if (col.type !== 'FIELD' || !col.aggregate) continue;\n const fn = col.aggregate.toLowerCase() as 'sum' | 'avg' | 'count';\n if (fn in groups) groups[fn].push(col.name ?? '');\n }\n const params: { sum?: string[]; avg?: string[]; count?: string[] } = {};\n if (groups.sum.length) params.sum = groups.sum;\n if (groups.avg.length) params.avg = groups.avg;\n if (groups.count.length) params.count = groups.count;\n return Object.keys(params).length > 0 ? params : null;\n}\n\n/** Aggregation query string: the page-0 query params without page/sort, plus sum/avg/count. */\nexport function buildAggregationQs(basePageQs: string, columns: TableColumn[]): string {\n const p = new URLSearchParams(basePageQs);\n p.delete('page');\n p.delete('sort');\n const groups = buildAggregationParams(columns);\n if (groups?.sum?.length) p.set('sum', groups.sum.join(','));\n if (groups?.avg?.length) p.set('avg', groups.avg.join(','));\n if (groups?.count?.length) p.set('count', groups.count.join(','));\n return p.toString();\n}\n\n/** True when the pending filter actually constrains anything. */\nexport function filterHasValue(f: Partial<ColumnFilter>): boolean {\n if (f.operator === 'isEmpty' || f.operator === 'isNotEmpty') return true;\n if (f.values !== undefined && f.values.length > 0) return true;\n if (f.value != null && f.value !== '') return true;\n if (typeof f.value === 'boolean') return true;\n if (f.from != null && f.from !== '') return true;\n if (f.to != null && f.to !== '') return true;\n return false;\n}\n\n// ── DATETIME filters: the user edits local \"YYYY-MM-DD\" dates, the API stores UTC ISO ──\n\n/** UTC ISO string at the start (midnight) of the given local day. */\nexport function dateLocalToUTCStart(dateStr: string): string {\n if (!dateStr) return dateStr;\n const [year, month, day] = dateStr.split('-').map(Number);\n return new Date(year, month - 1, day).toISOString().replace(/\\.\\d{3}Z$/, 'Z');\n}\n\n/** Start of the day AFTER the given local date (exclusive range end). */\nexport function dateLocalToUTCEndExclusive(dateStr: string): string {\n if (!dateStr) return dateStr;\n const [year, month, day] = dateStr.split('-').map(Number);\n return new Date(year, month - 1, day + 1).toISOString().replace(/\\.\\d{3}Z$/, 'Z');\n}\n\n/** Stored UTC ISO string back to the local \"YYYY-MM-DD\" date. */\nexport function utcISOToLocalDate(utcStr: string): string {\n if (!utcStr) return utcStr;\n const d = new Date(utcStr);\n if (isNaN(d.getTime())) return utcStr;\n return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;\n}\n\n/** The stored \"to\" is the exclusive end (next midnight); subtract a day to recover the entered date. */\nexport function utcISOToLocalDateExclusiveEnd(utcStr: string): string {\n if (!utcStr) return utcStr;\n const d = new Date(utcStr);\n if (isNaN(d.getTime())) return utcStr;\n d.setDate(d.getDate() - 1);\n return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;\n}\n\n/** Applies the local→UTC conversion when a DATETIME filter is submitted.\n * Exact date → range covering the full local day. */\nexport function normalizeDatetimeFilter(f: Partial<ColumnFilter>): Partial<ColumnFilter> {\n const normalized = { ...f };\n if (f.dataType === 'DATETIME' && f.operator !== 'isEmpty' && f.operator !== 'isNotEmpty') {\n if (typeof normalized.value === 'string' && normalized.value) {\n normalized.from = dateLocalToUTCStart(normalized.value);\n normalized.to = dateLocalToUTCEndExclusive(normalized.value);\n normalized.value = undefined;\n } else {\n if (typeof normalized.from === 'string' && normalized.from)\n normalized.from = dateLocalToUTCStart(normalized.from);\n if (typeof normalized.to === 'string' && normalized.to)\n normalized.to = dateLocalToUTCEndExclusive(normalized.to);\n }\n }\n return normalized;\n}\n\n/** Converts a stored DATETIME filter back to local dates for the popup.\n * A range covering a single local day is restored to exact-date mode. */\nexport function datetimeFilterToDisplay(existing: ColumnFilter): Partial<ColumnFilter> {\n const display: Partial<ColumnFilter> = { ...existing };\n if (typeof display.from === 'string' && display.from)\n display.from = utcISOToLocalDate(display.from);\n if (typeof display.to === 'string' && display.to)\n display.to = utcISOToLocalDateExclusiveEnd(display.to);\n if (display.from && display.to && display.from === display.to) {\n return { ...display, value: display.from, from: undefined, to: undefined };\n }\n return display;\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation-B_0Lx9DE.js","sources":["src/utils/validation.ts"],"sourcesContent":["import { ClientLayoutItemFieldDataType } from '../types';\n\nexport function validateRequired(value: unknown): boolean {\n if (value === null || value === undefined) return false;\n if (typeof value === 'string') return value.trim().length > 0;\n if (Array.isArray(value)) return value.length > 0;\n if (typeof value === 'object') {\n // HyperlinkValue check\n const hv = value as { href?: unknown };\n if ('href' in hv) return typeof hv.href === 'string' && hv.href.trim().length > 0;\n // CurrencyValue check\n const cv = value as { amount?: unknown };\n if ('amount' in cv) return cv.amount !== null && cv.amount !== undefined && cv.amount !== '';\n }\n return true;\n}\n\nexport function validateEmail(value: string): boolean {\n if (!value) return true;\n return /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(value);\n}\n\nexport function validateUrl(value: string): boolean {\n if (!value) return true;\n try {\n const url = new URL(value);\n return url.protocol === 'http:' || url.protocol === 'https:';\n } catch {\n return false;\n }\n}\n\nexport function validateNumber(value: unknown, dataType: ClientLayoutItemFieldDataType): boolean {\n if (value === null || value === undefined || value === '') return true;\n const num = Number(value);\n if (isNaN(num)) return false;\n if (dataType === ClientLayoutItemFieldDataType.INTEGER) {\n return Number.isInteger(num);\n }\n if (dataType === ClientLayoutItemFieldDataType.PERCENTAGE) {\n return num >= 0 && num <= 100;\n }\n return true;\n}\n"],"names":[],"mappings":";;;AAEM,SAAU,gBAAgB,CAAC,KAAc,EAAA;AAC7C,IAAA,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;AAAE,QAAA,OAAO,KAAK;IACvD,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC;AAC7D,IAAA,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;AAAE,QAAA,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC;AACjD,IAAA,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;;QAE7B,MAAM,EAAE,GAAG,KAA2B;QACtC,IAAI,MAAM,IAAI,EAAE;AAAE,YAAA,OAAO,OAAO,EAAE,CAAC,IAAI,KAAK,QAAQ,IAAI,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC;;QAEjF,MAAM,EAAE,GAAG,KAA6B;QACxC,IAAI,QAAQ,IAAI,EAAE;AAAE,YAAA,OAAO,EAAE,CAAC,MAAM,KAAK,IAAI,IAAI,EAAE,CAAC,MAAM,KAAK,SAAS,IAAI,EAAE,CAAC,MAAM,KAAK,EAAE;;AAE9F,IAAA,OAAO,IAAI;AACb;AAEM,SAAU,aAAa,CAAC,KAAa,EAAA;AACzC,IAAA,IAAI,CAAC,KAAK;AAAE,QAAA,OAAO,IAAI;AACvB,IAAA,OAAO,4BAA4B,CAAC,IAAI,CAAC,KAAK,CAAC;AACjD;AAEM,SAAU,WAAW,CAAC,KAAa,EAAA;AACvC,IAAA,IAAI,CAAC,KAAK;AAAE,QAAA,OAAO,IAAI;AACvB,IAAA,IAAI;AACF,QAAA,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC;QAC1B,OAAO,GAAG,CAAC,QAAQ,KAAK,OAAO,IAAI,GAAG,CAAC,QAAQ,KAAK,QAAQ;;IAC5D,OAAA,EAAA,EAAM;AACN,QAAA,OAAO,KAAK;;AAEhB;AAEM,SAAU,cAAc,CAAC,KAAc,EAAE,QAAuC,EAAA;IACpF,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE;AAAE,QAAA,OAAO,IAAI;AACtE,IAAA,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC;IACzB,IAAI,KAAK,CAAC,GAAG,CAAC;AAAE,QAAA,OAAO,KAAK;AAC5B,IAAA,IAAI,QAAQ,KAAK,6BAA6B,CAAC,OAAO,EAAE;AACtD,QAAA,OAAO,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC;;AAE9B,IAAA,IAAI,QAAQ,KAAK,6BAA6B,CAAC,UAAU,EAAE;AACzD,QAAA,OAAO,GAAG,IAAI,CAAC,IAAI,GAAG,IAAI,GAAG;;AAE/B,IAAA,OAAO,IAAI;AACb;;;;"}
|
|
@@ -35,9 +35,19 @@ export declare class MrdField {
|
|
|
35
35
|
until: string;
|
|
36
36
|
}>;
|
|
37
37
|
currentValue: unknown;
|
|
38
|
+
multiValues: unknown[];
|
|
39
|
+
multiError: string;
|
|
38
40
|
componentWillLoad(): void;
|
|
39
41
|
valueChanged(): void;
|
|
40
42
|
private initHistoryState;
|
|
43
|
+
/** LIST/FILE/IMAGE already own their multiple-value UI end to end; every
|
|
44
|
+
* other scalar dataType routes through the generic repeater below instead
|
|
45
|
+
* of each leaf field re-implementing add/remove itself (FINDING-0149). */
|
|
46
|
+
private isMultiScalar;
|
|
47
|
+
private initMultiState;
|
|
48
|
+
private emptyRowValue;
|
|
49
|
+
private emitMultiChange;
|
|
50
|
+
private handleMultiRowBlur;
|
|
41
51
|
private handleChange;
|
|
42
52
|
private handleBlur;
|
|
43
53
|
private handleSearch;
|
|
@@ -46,7 +56,13 @@ export declare class MrdField {
|
|
|
46
56
|
private getDisplayValue;
|
|
47
57
|
private historyValueInputType;
|
|
48
58
|
private emitHistoryChange;
|
|
59
|
+
private renderRemoveIcon;
|
|
49
60
|
private renderHistoryEditor;
|
|
50
61
|
private renderLeafField;
|
|
62
|
+
/** Repeatable-row UI for a scalar dataType with multiple: true — mirrors the
|
|
63
|
+
* add/remove pattern already established by renderHistoryEditor(), reusing
|
|
64
|
+
* the single-row renderLeafField() per entry instead of duplicating repeat
|
|
65
|
+
* UI into every leaf field component (FINDING-0149). */
|
|
66
|
+
private renderMultiScalarField;
|
|
51
67
|
render(): any;
|
|
52
68
|
}
|
|
@@ -19,4 +19,8 @@ export interface FieldViewContext {
|
|
|
19
19
|
};
|
|
20
20
|
}
|
|
21
21
|
export declare function renderFieldValue(ctx: FieldViewContext, item: ClientLayoutItem, rawValue: unknown): any;
|
|
22
|
+
/** Whether a FIELD item would render anything at all (value, or a showEmpty
|
|
23
|
+
* placeholder). A `header` field always renders. Used by mrd-layout-section
|
|
24
|
+
* to decide whether a preceding HEADER item's block is entirely empty. */
|
|
25
|
+
export declare function isFieldVisible(ctx: FieldViewContext, item: ClientLayoutItem): boolean;
|
|
22
26
|
export declare function renderField(ctx: FieldViewContext, item: ClientLayoutItem): any;
|
|
@@ -4,6 +4,9 @@ export declare function viewKeyFor(item: ClientLayoutItem): string;
|
|
|
4
4
|
/** Whether a FIELD/RELATION item stays visible on an OBJECT_DASHBOARD when it
|
|
5
5
|
* has no value. Reads the flat API flag, falling back to the nested wrappers. */
|
|
6
6
|
export declare function showsEmpty(item: ClientLayoutItem): boolean;
|
|
7
|
+
/** Whether a RELATION item has a resolvable link value (`_links[item.name]`
|
|
8
|
+
* carries either a multi-value `values[]` or a single `name`). */
|
|
9
|
+
export declare function hasRelationValue(item: ClientLayoutItem, data: Record<string, unknown>): boolean;
|
|
7
10
|
/** Depth-first flatten of the SECTION/GROUP tree. */
|
|
8
11
|
export declare function flattenItems(items: ClientLayoutItem[]): ClientLayoutItem[];
|
|
9
12
|
/** Build the canonical parent href `/{base}/{tenant}/{fromClass}/{parentId}` from
|
|
@@ -172,6 +172,11 @@ export declare class MrdLayoutSection {
|
|
|
172
172
|
* the card list and the flat table, mirroring renderDocumentContainer(). */
|
|
173
173
|
private renderMemoContainer;
|
|
174
174
|
private renderTable;
|
|
175
|
+
/** Whether every FIELD/RELATION item following a HEADER (up to the next
|
|
176
|
+
* HEADER/SECTION/GROUP or the end of `siblings`) would itself render
|
|
177
|
+
* nothing — i.e. the HEADER would introduce an empty block. Other item
|
|
178
|
+
* types (VIEW, NAVIGATE, TEXT, ...) always count as visible. */
|
|
179
|
+
private isHeaderBlockEmpty;
|
|
175
180
|
private renderItem;
|
|
176
181
|
private renderImageModal;
|
|
177
182
|
/** Related VIEW/RELATED_VIEW/SEARCH items to keep rendering below an archetype's
|
|
@@ -28,6 +28,20 @@ export declare class MrdMemoContainer {
|
|
|
28
28
|
/** Canonical parent href — set when this is a RELATED_VIEW embedded under a
|
|
29
29
|
* parent record, which already gives a new memo something to attach to. */
|
|
30
30
|
containerHref: string;
|
|
31
|
+
/** False when this RELATED_VIEW's parent is related via a relation other than
|
|
32
|
+
* the archetype's container slot (e.g. a person's "memos I authored" list,
|
|
33
|
+
* related via `author`) — mrd-layout-section resolves this from the item's
|
|
34
|
+
* `inverseRelation`. In that case the parent is not a valid container for a
|
|
35
|
+
* new memo, and — unlike a top-level VIEW with no context at all — falling
|
|
36
|
+
* back to `me` would be wrong too (creating a memo "on myself" from someone
|
|
37
|
+
* else's authored-memos list makes no sense), so "New memo" is hidden outright. */
|
|
38
|
+
containerRelated: boolean;
|
|
39
|
+
/** True unless this is a container-scoped RELATED_VIEW (a company's own memo
|
|
40
|
+
* tab, say) where every card's container is obviously the page you're
|
|
41
|
+
* already on — forwarded to mrd-memo-list to show/hide its per-card
|
|
42
|
+
* container link. A top-level VIEW or an author-scoped RELATED_VIEW both
|
|
43
|
+
* still need it, since the container isn't implied by the page context. */
|
|
44
|
+
showContainerLink: boolean;
|
|
31
45
|
/** Lookup key used for the embedded `data-view` attribute. */
|
|
32
46
|
viewKey: string;
|
|
33
47
|
locale: string;
|
|
@@ -53,6 +67,12 @@ export declare class MrdMemoContainer {
|
|
|
53
67
|
qs: string;
|
|
54
68
|
aggQs: string;
|
|
55
69
|
}>;
|
|
70
|
+
/** A card's container link was clicked — real navigation, unrelated to the
|
|
71
|
+
* quick-edit dialog (mrdEdit is internal, handled by this component itself). */
|
|
72
|
+
mrdNavigate: EventEmitter<{
|
|
73
|
+
href?: string;
|
|
74
|
+
label: string;
|
|
75
|
+
}>;
|
|
56
76
|
/** Only the embedded table's own toolbar (export, etc.) still routes through this. */
|
|
57
77
|
mrdAction: EventEmitter<{
|
|
58
78
|
action: string;
|
|
@@ -124,7 +144,8 @@ export declare class MrdMemoContainer {
|
|
|
124
144
|
private get hasTitleSlot();
|
|
125
145
|
private get hasImportantSlot();
|
|
126
146
|
/** A parent record already gives a new memo somewhere to attach to (RELATED_VIEW);
|
|
127
|
-
* otherwise fall back to the account's own linked person (top-level VIEW)
|
|
147
|
+
* otherwise fall back to the account's own linked person (top-level VIEW) — but
|
|
148
|
+
* only when containerRelated allows it (see its doc comment). */
|
|
128
149
|
private get effectiveContainerHref();
|
|
129
150
|
/** The author slot is always filled from `me` (there is no author picker in
|
|
130
151
|
* the dialog), so without it there is nothing valid to create — regardless
|
|
@@ -32,6 +32,11 @@ export declare class MrdMemoList {
|
|
|
32
32
|
/** listItems of the FIELD bound to the `labels` slot, resolved by mrd-layout-section
|
|
33
33
|
* from its own items array, same reason mrd-memo-view needs it. */
|
|
34
34
|
labelsListItems: ClientListValue[] | null;
|
|
35
|
+
/** False when the list is already scoped to its own container (a company's own
|
|
36
|
+
* memo tab) — showing "belongs to: <this same company>" on every card there
|
|
37
|
+
* would be redundant. True everywhere else (top-level VIEW, or a RELATED_VIEW
|
|
38
|
+
* scoped by a different relation, e.g. a person's authored-memos list). */
|
|
39
|
+
showContainerLink: boolean;
|
|
35
40
|
/** Fired when a page needs fetching; same shape as mrd-table's mrdLoadPage minus `qs`'s
|
|
36
41
|
* column-filter support (cards have no filter UI) — host calls setPage() with the result. */
|
|
37
42
|
mrdLoadPage: EventEmitter<{
|
|
@@ -45,6 +50,12 @@ export declare class MrdMemoList {
|
|
|
45
50
|
mrdEdit: EventEmitter<{
|
|
46
51
|
row: Record<string, unknown>;
|
|
47
52
|
}>;
|
|
53
|
+
/** The container link on a card was clicked — this is real navigation (to the
|
|
54
|
+
* container record), unrelated to mrdEdit. */
|
|
55
|
+
mrdNavigate: EventEmitter<{
|
|
56
|
+
href?: string;
|
|
57
|
+
label: string;
|
|
58
|
+
}>;
|
|
48
59
|
private rows;
|
|
49
60
|
private loading;
|
|
50
61
|
private exhausted;
|
|
@@ -72,6 +83,7 @@ export declare class MrdMemoList {
|
|
|
72
83
|
private slotLink;
|
|
73
84
|
private plainTextLength;
|
|
74
85
|
private toggleExpanded;
|
|
86
|
+
private renderContainer;
|
|
75
87
|
private renderLabels;
|
|
76
88
|
private renderBody;
|
|
77
89
|
private renderCard;
|
|
@@ -679,6 +679,11 @@ export namespace Components {
|
|
|
679
679
|
* @default ''
|
|
680
680
|
*/
|
|
681
681
|
"containerHref": string;
|
|
682
|
+
/**
|
|
683
|
+
* False when this RELATED_VIEW's parent is related via a relation other than the archetype's container slot (e.g. a person's "memos I authored" list, related via `author`) — mrd-layout-section resolves this from the item's `inverseRelation`. In that case the parent is not a valid container for a new memo, and — unlike a top-level VIEW with no context at all — falling back to `me` would be wrong too (creating a memo "on myself" from someone else's authored-memos list makes no sense), so "New memo" is hidden outright.
|
|
684
|
+
* @default true
|
|
685
|
+
*/
|
|
686
|
+
"containerRelated": boolean;
|
|
682
687
|
/**
|
|
683
688
|
* The VIEW or RELATED_VIEW layout item (dataClass, fromClass, view config).
|
|
684
689
|
* @default null
|
|
@@ -712,6 +717,11 @@ export namespace Components {
|
|
|
712
717
|
* Re-request page 0 of whichever body is currently mounted — called by mrd-layout-section after a successful mrdCreateObject, and by this component itself after an edit to a table row (which has no per-row optimistic-patch method the way mrd-memo-list does).
|
|
713
718
|
*/
|
|
714
719
|
"refresh": () => Promise<void>;
|
|
720
|
+
/**
|
|
721
|
+
* True unless this is a container-scoped RELATED_VIEW (a company's own memo tab, say) where every card's container is obviously the page you're already on — forwarded to mrd-memo-list to show/hide its per-card container link. A top-level VIEW or an author-scoped RELATED_VIEW both still need it, since the container isn't implied by the page context.
|
|
722
|
+
* @default true
|
|
723
|
+
*/
|
|
724
|
+
"showContainerLink": boolean;
|
|
715
725
|
/**
|
|
716
726
|
* Lookup key used for the embedded `data-view` attribute.
|
|
717
727
|
* @default ''
|
|
@@ -782,6 +792,11 @@ export namespace Components {
|
|
|
782
792
|
* Inject the rows for a page (0-based); page 0 replaces, later pages append.
|
|
783
793
|
*/
|
|
784
794
|
"setPage": (pageNumber: number, rows: Record<string, unknown>[], hasNext?: boolean) => Promise<void>;
|
|
795
|
+
/**
|
|
796
|
+
* False when the list is already scoped to its own container (a company's own memo tab) — showing "belongs to: <this same company>" on every card there would be redundant. True everywhere else (top-level VIEW, or a RELATED_VIEW scoped by a different relation, e.g. a person's authored-memos list).
|
|
797
|
+
* @default true
|
|
798
|
+
*/
|
|
799
|
+
"showContainerLink": boolean;
|
|
785
800
|
}
|
|
786
801
|
/**
|
|
787
802
|
* Archetype-driven single-memo view. Given a `commons.memo` binding and a data
|
|
@@ -1681,6 +1696,7 @@ declare global {
|
|
|
1681
1696
|
interface HTMLMrdMemoContainerElementEventMap {
|
|
1682
1697
|
"mrdLoadPage": { page: number; sort: string; path: string; qs: string };
|
|
1683
1698
|
"mrdLoadAggregations": { path: string; qs: string; aggQs: string };
|
|
1699
|
+
"mrdNavigate": { href?: string; label: string };
|
|
1684
1700
|
"mrdAction": { action: string; path?: string; qs?: string; parentPath?: string | null; basicType?: string };
|
|
1685
1701
|
"mrdCreateObject": { path: string; values: Record<string, unknown> };
|
|
1686
1702
|
"mrdUpdateObject": { href: string; values: Record<string, unknown> };
|
|
@@ -1719,6 +1735,7 @@ declare global {
|
|
|
1719
1735
|
interface HTMLMrdMemoListElementEventMap {
|
|
1720
1736
|
"mrdLoadPage": { page: number; sort: string; path: string; qs: string };
|
|
1721
1737
|
"mrdEdit": { row: Record<string, unknown> };
|
|
1738
|
+
"mrdNavigate": { href?: string; label: string };
|
|
1722
1739
|
}
|
|
1723
1740
|
/**
|
|
1724
1741
|
* Card-view body for a `commons.memo` collection — the alternative to the flat
|
|
@@ -2752,6 +2769,11 @@ declare namespace LocalJSX {
|
|
|
2752
2769
|
* @default ''
|
|
2753
2770
|
*/
|
|
2754
2771
|
"containerHref"?: string;
|
|
2772
|
+
/**
|
|
2773
|
+
* False when this RELATED_VIEW's parent is related via a relation other than the archetype's container slot (e.g. a person's "memos I authored" list, related via `author`) — mrd-layout-section resolves this from the item's `inverseRelation`. In that case the parent is not a valid container for a new memo, and — unlike a top-level VIEW with no context at all — falling back to `me` would be wrong too (creating a memo "on myself" from someone else's authored-memos list makes no sense), so "New memo" is hidden outright.
|
|
2774
|
+
* @default true
|
|
2775
|
+
*/
|
|
2776
|
+
"containerRelated"?: boolean;
|
|
2755
2777
|
/**
|
|
2756
2778
|
* The VIEW or RELATED_VIEW layout item (dataClass, fromClass, view config).
|
|
2757
2779
|
* @default null
|
|
@@ -2785,6 +2807,10 @@ declare namespace LocalJSX {
|
|
|
2785
2807
|
"onMrdDeleteObject"?: (event: MrdMemoContainerCustomEvent<{ href: string }>) => void;
|
|
2786
2808
|
"onMrdLoadAggregations"?: (event: MrdMemoContainerCustomEvent<{ path: string; qs: string; aggQs: string }>) => void;
|
|
2787
2809
|
"onMrdLoadPage"?: (event: MrdMemoContainerCustomEvent<{ page: number; sort: string; path: string; qs: string }>) => void;
|
|
2810
|
+
/**
|
|
2811
|
+
* A card's container link was clicked — real navigation, unrelated to the quick-edit dialog (mrdEdit is internal, handled by this component itself).
|
|
2812
|
+
*/
|
|
2813
|
+
"onMrdNavigate"?: (event: MrdMemoContainerCustomEvent<{ href?: string; label: string }>) => void;
|
|
2788
2814
|
/**
|
|
2789
2815
|
* Quick-edit submit. Host PATCHes `href` with `values`, same as mrd-document-list's drag-move.
|
|
2790
2816
|
*/
|
|
@@ -2799,6 +2825,11 @@ declare namespace LocalJSX {
|
|
|
2799
2825
|
* @default false
|
|
2800
2826
|
*/
|
|
2801
2827
|
"readOnly"?: boolean;
|
|
2828
|
+
/**
|
|
2829
|
+
* True unless this is a container-scoped RELATED_VIEW (a company's own memo tab, say) where every card's container is obviously the page you're already on — forwarded to mrd-memo-list to show/hide its per-card container link. A top-level VIEW or an author-scoped RELATED_VIEW both still need it, since the container isn't implied by the page context.
|
|
2830
|
+
* @default true
|
|
2831
|
+
*/
|
|
2832
|
+
"showContainerLink"?: boolean;
|
|
2802
2833
|
/**
|
|
2803
2834
|
* Lookup key used for the embedded `data-view` attribute.
|
|
2804
2835
|
* @default ''
|
|
@@ -2846,6 +2877,10 @@ declare namespace LocalJSX {
|
|
|
2846
2877
|
* Fired when a page needs fetching; same shape as mrd-table's mrdLoadPage minus `qs`'s column-filter support (cards have no filter UI) — host calls setPage() with the result.
|
|
2847
2878
|
*/
|
|
2848
2879
|
"onMrdLoadPage"?: (event: MrdMemoListCustomEvent<{ page: number; sort: string; path: string; qs: string }>) => void;
|
|
2880
|
+
/**
|
|
2881
|
+
* The container link on a card was clicked — this is real navigation (to the container record), unrelated to mrdEdit.
|
|
2882
|
+
*/
|
|
2883
|
+
"onMrdNavigate"?: (event: MrdMemoListCustomEvent<{ href?: string; label: string }>) => void;
|
|
2849
2884
|
/**
|
|
2850
2885
|
* Records per page (must match API page size).
|
|
2851
2886
|
* @default 20
|
|
@@ -2861,6 +2896,11 @@ declare namespace LocalJSX {
|
|
|
2861
2896
|
* @default false
|
|
2862
2897
|
*/
|
|
2863
2898
|
"readOnly"?: boolean;
|
|
2899
|
+
/**
|
|
2900
|
+
* False when the list is already scoped to its own container (a company's own memo tab) — showing "belongs to: <this same company>" on every card there would be redundant. True everywhere else (top-level VIEW, or a RELATED_VIEW scoped by a different relation, e.g. a person's authored-memos list).
|
|
2901
|
+
* @default true
|
|
2902
|
+
*/
|
|
2903
|
+
"showContainerLink"?: boolean;
|
|
2864
2904
|
}
|
|
2865
2905
|
/**
|
|
2866
2906
|
* Archetype-driven single-memo view. Given a `commons.memo` binding and a data
|
|
@@ -3366,6 +3406,8 @@ declare namespace LocalJSX {
|
|
|
3366
3406
|
interface MrdMemoContainerAttributes {
|
|
3367
3407
|
"parentId": string;
|
|
3368
3408
|
"containerHref": string;
|
|
3409
|
+
"containerRelated": boolean;
|
|
3410
|
+
"showContainerLink": boolean;
|
|
3369
3411
|
"viewKey": string;
|
|
3370
3412
|
"locale": string;
|
|
3371
3413
|
"readOnly": boolean;
|
|
@@ -3375,6 +3417,7 @@ declare namespace LocalJSX {
|
|
|
3375
3417
|
"pageSize": number;
|
|
3376
3418
|
"locale": string;
|
|
3377
3419
|
"readOnly": boolean;
|
|
3420
|
+
"showContainerLink": boolean;
|
|
3378
3421
|
}
|
|
3379
3422
|
interface MrdMemoViewAttributes {
|
|
3380
3423
|
"locale": string;
|