@formicoidea/labre-core 0.54.0 → 0.56.0
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/architecture/code.c4 +7547 -0
- package/architecture/likec4.config.json +3 -0
- package/architecture/model.c4 +128 -0
- package/dist/_pkgs/data-view/translations.d.ts +0 -2
- package/dist/_pkgs/data-view/translations.js +0 -6
- package/dist/_pkgs/data-view/view-presets/flat/flat-view-ui.d.ts +3 -1
- package/dist/_pkgs/data-view/view-presets/flat/flat-view-ui.js +5 -1
- package/dist/_pkgs/data-view/view-presets/kanban/mobile/card.d.ts +6 -0
- package/dist/_pkgs/data-view/view-presets/kanban/mobile/card.js +11 -0
- package/dist/_pkgs/data-view/view-presets/kanban/mobile/cell.js +9 -10
- package/dist/_pkgs/data-view/view-presets/kanban/mobile/kanban-view-ui-logic.js +3 -0
- package/dist/_pkgs/data-view/view-presets/table/mobile/cell.js +7 -4
- package/dist/_pkgs/data-view/view-presets/table/mobile/group.js +11 -8
- package/dist/_pkgs/data-view/view-presets/table/mobile/header.d.ts +8 -2
- package/dist/_pkgs/data-view/view-presets/table/mobile/header.js +47 -15
- package/dist/_pkgs/data-view/view-presets/table/mobile/menu.d.ts +3 -1
- package/dist/_pkgs/data-view/view-presets/table/mobile/menu.js +7 -3
- package/dist/_pkgs/data-view/view-presets/table/mobile/row.d.ts +23 -1
- package/dist/_pkgs/data-view/view-presets/table/mobile/row.js +131 -57
- package/dist/_pkgs/data-view/view-presets/table/mobile/table-view-ui-logic.d.ts +5 -1
- package/dist/_pkgs/data-view/view-presets/table/mobile/table-view-ui-logic.js +9 -2
- package/dist/_pkgs/data-view/view-presets/table/pc/row/row.js +5 -1
- package/dist/_pkgs/data-view/widget-presets/quick-setting-bar/filter/index.js +1 -2
- package/dist/_pkgs/data-view/widget-presets/quick-setting-bar/index.js +8 -8
- package/dist/_pkgs/data-view/widget-presets/tools/presets/filter/filter.d.ts +3 -0
- package/dist/_pkgs/data-view/widget-presets/tools/presets/filter/filter.js +125 -60
- package/dist/_pkgs/data-view/widget-presets/tools/presets/sort/sort.d.ts +3 -0
- package/dist/_pkgs/data-view/widget-presets/tools/presets/sort/sort.js +131 -66
- package/dist/_pkgs/data-view/widget-presets/tools/presets/table-add-row/add-row.js +49 -10
- package/dist/_pkgs/store/model/store/query.js +13 -1
- package/package.json +3 -2
|
@@ -33,24 +33,42 @@ var __runInitializers = (this && this.__runInitializers) || function (thisArg, i
|
|
|
33
33
|
return useValue ? value : void 0;
|
|
34
34
|
};
|
|
35
35
|
import { popupTargetFromElement } from '../../../../affine-components/context-menu/index.js';
|
|
36
|
-
import {
|
|
36
|
+
import { OPEN_LABEL } from '../../../../affine-components/translations.js';
|
|
37
37
|
import { SignalWatcher, WithDisposable } from '../../../../global/lit/index.js';
|
|
38
|
-
import {
|
|
39
|
-
import {
|
|
38
|
+
import { ShadowlessElement, stdContext } from '../../../../std/index.js';
|
|
39
|
+
import { consume } from '@lit/context';
|
|
40
40
|
import { cssVarV2 } from '@toeverything/theme/v2';
|
|
41
41
|
import { css, nothing, unsafeCSS } from 'lit';
|
|
42
42
|
import { property } from 'lit/decorators.js';
|
|
43
43
|
import { repeat } from 'lit/directives/repeat.js';
|
|
44
44
|
import { styleMap } from 'lit/directives/style-map.js';
|
|
45
45
|
import { html } from 'lit/static-html.js';
|
|
46
|
+
import { wordingOf } from '../../../core/utils/wording.js';
|
|
46
47
|
import { paintRowColor, ROW_COLOR_PROPERTY, viewRowColor, } from '../../../core/view/color-rules.js';
|
|
47
48
|
import { cellDivider } from '../styles.js';
|
|
48
49
|
import { popMobileRowMenu } from './menu.js';
|
|
49
50
|
import { mobileStickyTitle } from './table-view-style.js';
|
|
50
|
-
/**
|
|
51
|
-
const
|
|
51
|
+
/** The "Open" chip's widest drawing, its 8px inset and 4px of air. */
|
|
52
|
+
export const ROW_OPEN_WIDTH = 60 + 8 + 4;
|
|
53
|
+
/** How long a finger rests on a row before its menu opens. */
|
|
54
|
+
export const ROW_LONG_PRESS_MS = 500;
|
|
55
|
+
/** A finger that travels further is scrolling, not pressing. */
|
|
56
|
+
const LONG_PRESS_SLOP = 8;
|
|
57
|
+
/**
|
|
58
|
+
* A row of the phone table (P7, "Bases éditables sur mobile", after Notion's
|
|
59
|
+
* phone table). A tap on a cell edits it; the title column carries an "Open"
|
|
60
|
+
* chip that opens the row through the root's detail panel, the path of the
|
|
61
|
+
* desktop row's open button; a long press opens the row menu (open, delete).
|
|
62
|
+
*
|
|
63
|
+
* Up to 0.54 the title cell carried two floating ops (open and "...") drawn
|
|
64
|
+
* over the end of the title. The chip reserves its room instead, and the
|
|
65
|
+
* "..." moved to the long press so deleting a row stays possible on a phone.
|
|
66
|
+
*/
|
|
52
67
|
let MobileTableRow = (() => {
|
|
53
68
|
let _classSuper = SignalWatcher(WithDisposable(ShadowlessElement));
|
|
69
|
+
let _std_decorators;
|
|
70
|
+
let _std_initializers = [];
|
|
71
|
+
let _std_extraInitializers = [];
|
|
54
72
|
let _tableViewLogic_decorators;
|
|
55
73
|
let _tableViewLogic_initializers = [];
|
|
56
74
|
let _tableViewLogic_extraInitializers = [];
|
|
@@ -63,16 +81,18 @@ let MobileTableRow = (() => {
|
|
|
63
81
|
return class MobileTableRow extends _classSuper {
|
|
64
82
|
static {
|
|
65
83
|
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
84
|
+
_std_decorators = [consume({ context: stdContext })];
|
|
66
85
|
_tableViewLogic_decorators = [property({ attribute: false })];
|
|
67
86
|
_rowId_decorators = [property({ attribute: false })];
|
|
68
87
|
_rowIndex_decorators = [property({ attribute: false })];
|
|
88
|
+
__esDecorate(this, null, _std_decorators, { kind: "accessor", name: "std", static: false, private: false, access: { has: obj => "std" in obj, get: obj => obj.std, set: (obj, value) => { obj.std = value; } }, metadata: _metadata }, _std_initializers, _std_extraInitializers);
|
|
69
89
|
__esDecorate(this, null, _tableViewLogic_decorators, { kind: "accessor", name: "tableViewLogic", static: false, private: false, access: { has: obj => "tableViewLogic" in obj, get: obj => obj.tableViewLogic, set: (obj, value) => { obj.tableViewLogic = value; } }, metadata: _metadata }, _tableViewLogic_initializers, _tableViewLogic_extraInitializers);
|
|
70
90
|
__esDecorate(this, null, _rowId_decorators, { kind: "accessor", name: "rowId", static: false, private: false, access: { has: obj => "rowId" in obj, get: obj => obj.rowId, set: (obj, value) => { obj.rowId = value; } }, metadata: _metadata }, _rowId_initializers, _rowId_extraInitializers);
|
|
71
91
|
__esDecorate(this, null, _rowIndex_decorators, { kind: "accessor", name: "rowIndex", static: false, private: false, access: { has: obj => "rowIndex" in obj, get: obj => obj.rowIndex, set: (obj, value) => { obj.rowIndex = value; } }, metadata: _metadata }, _rowIndex_initializers, _rowIndex_extraInitializers);
|
|
72
92
|
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
73
93
|
}
|
|
74
|
-
// Touch targets are 44px tall (B5, ADR 0035 §1): the row, and
|
|
75
|
-
// through an invisible hit area, so
|
|
94
|
+
// Touch targets are 44px tall (B5, ADR 0035 §1): the row, and the chip
|
|
95
|
+
// through an invisible hit area, so it keeps its drawn size.
|
|
76
96
|
static { this.styles = css `
|
|
77
97
|
.mobile-table-row {
|
|
78
98
|
width: 100%;
|
|
@@ -82,69 +102,105 @@ let MobileTableRow = (() => {
|
|
|
82
102
|
position: relative;
|
|
83
103
|
min-height: 44px;
|
|
84
104
|
background-color: var(${unsafeCSS(ROW_COLOR_PROPERTY)}, transparent);
|
|
105
|
+
-webkit-touch-callout: none;
|
|
85
106
|
}
|
|
86
107
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
display: flex;
|
|
93
|
-
gap: 20px;
|
|
94
|
-
cursor: pointer;
|
|
95
|
-
justify-content: end;
|
|
96
|
-
right: 8px;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
.affine-database-block-row:has([data-editing='true']) .mobile-row-ops {
|
|
100
|
-
visibility: hidden;
|
|
101
|
-
opacity: 0;
|
|
108
|
+
/* A long press opens the row menu, not a text selection; an edited cell
|
|
109
|
+
keeps its own. */
|
|
110
|
+
.mobile-table-row mobile-table-cell:not([data-editing='true']) {
|
|
111
|
+
-webkit-user-select: none;
|
|
112
|
+
user-select: none;
|
|
102
113
|
}
|
|
103
114
|
|
|
104
|
-
.mobile-row-
|
|
115
|
+
.mobile-row-open {
|
|
116
|
+
position: absolute;
|
|
117
|
+
top: 10px;
|
|
118
|
+
right: 8px;
|
|
105
119
|
display: flex;
|
|
106
|
-
|
|
120
|
+
align-items: center;
|
|
121
|
+
height: 24px;
|
|
122
|
+
max-width: 60px;
|
|
123
|
+
padding: 0 6px;
|
|
124
|
+
box-sizing: border-box;
|
|
125
|
+
border: 1px solid ${unsafeCSS(cssVarV2.layer.insideBorder.border)};
|
|
107
126
|
border-radius: 4px;
|
|
108
|
-
box-shadow: 0px 0px 4px 0px rgba(66, 65, 73, 0.14);
|
|
109
127
|
background-color: var(--affine-background-primary-color);
|
|
110
|
-
|
|
111
|
-
font-size:
|
|
112
|
-
|
|
128
|
+
color: ${unsafeCSS(cssVarV2.text.secondary)};
|
|
129
|
+
font-size: 12px;
|
|
130
|
+
font-weight: 500;
|
|
131
|
+
line-height: 20px;
|
|
132
|
+
white-space: nowrap;
|
|
133
|
+
overflow: hidden;
|
|
134
|
+
text-overflow: ellipsis;
|
|
135
|
+
cursor: pointer;
|
|
113
136
|
}
|
|
114
137
|
|
|
115
|
-
.mobile-row-
|
|
138
|
+
.mobile-row-open::after {
|
|
116
139
|
content: '';
|
|
117
140
|
position: absolute;
|
|
118
|
-
inset: -10px;
|
|
141
|
+
inset: -10px -4px;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
.mobile-row-title:has(mobile-table-cell[data-editing='true'])
|
|
145
|
+
.mobile-row-open {
|
|
146
|
+
display: none;
|
|
119
147
|
}
|
|
120
148
|
`; }
|
|
149
|
+
#std_accessor_storage;
|
|
150
|
+
/** Absent outside an editor host: the wordings read English. */
|
|
151
|
+
get std() { return this.#std_accessor_storage; }
|
|
152
|
+
set std(value) { this.#std_accessor_storage = value; }
|
|
121
153
|
get groupKey() {
|
|
122
154
|
return this.closest('affine-data-view-table-group')?.group?.key;
|
|
123
155
|
}
|
|
124
156
|
connectedCallback() {
|
|
125
157
|
super.connectedCallback();
|
|
126
158
|
this.classList.add('mobile-table-row');
|
|
159
|
+
this.disposables.add(this.cancelPress);
|
|
160
|
+
this.disposables.addFromEvent(this, 'pointerdown', (e) => {
|
|
161
|
+
this.pressFired = false;
|
|
162
|
+
this.cancelPress();
|
|
163
|
+
if (this.view.readonly$.value)
|
|
164
|
+
return;
|
|
165
|
+
this.pressOrigin = { x: e.clientX, y: e.clientY };
|
|
166
|
+
this.pressTimer = setTimeout(() => {
|
|
167
|
+
this.cancelPress();
|
|
168
|
+
this.pressFired = true;
|
|
169
|
+
popMobileRowMenu(popupTargetFromElement(this), this.rowId, this.tableViewLogic, this.view, wordingOf(this.std));
|
|
170
|
+
}, ROW_LONG_PRESS_MS);
|
|
171
|
+
});
|
|
172
|
+
this.disposables.addFromEvent(this, 'pointermove', (e) => {
|
|
173
|
+
const origin = this.pressOrigin;
|
|
174
|
+
if (!origin)
|
|
175
|
+
return;
|
|
176
|
+
const moved = Math.hypot(e.clientX - origin.x, e.clientY - origin.y);
|
|
177
|
+
if (moved > LONG_PRESS_SLOP)
|
|
178
|
+
this.cancelPress();
|
|
179
|
+
});
|
|
180
|
+
this.disposables.addFromEvent(this, 'pointerup', this.cancelPress);
|
|
181
|
+
this.disposables.addFromEvent(this, 'pointercancel', this.cancelPress);
|
|
182
|
+
// Android opens its own menu on a long press; the row's is the one.
|
|
183
|
+
this.disposables.addFromEvent(this, 'contextmenu', (e) => {
|
|
184
|
+
e.preventDefault();
|
|
185
|
+
});
|
|
186
|
+
this.disposables.addFromEvent(this, 'click', (e) => {
|
|
187
|
+
if (!this.pressFired)
|
|
188
|
+
return;
|
|
189
|
+
this.pressFired = false;
|
|
190
|
+
e.stopPropagation();
|
|
191
|
+
e.preventDefault();
|
|
192
|
+
}, { capture: true });
|
|
127
193
|
}
|
|
128
194
|
render() {
|
|
129
195
|
const view = this.view;
|
|
130
196
|
paintRowColor(this, viewRowColor(view, this.rowId));
|
|
197
|
+
const openLabel = wordingOf(this.std)(OPEN_LABEL);
|
|
131
198
|
return html `
|
|
132
199
|
${repeat(view.properties$.value, v => v.id, (column, i) => {
|
|
133
|
-
const clickDetail = () => {
|
|
134
|
-
this.tableViewLogic.root.openDetailPanel({
|
|
135
|
-
view: this.view,
|
|
136
|
-
rowId: this.rowId,
|
|
137
|
-
});
|
|
138
|
-
};
|
|
139
|
-
const openMenu = (e) => {
|
|
140
|
-
const ele = e.currentTarget;
|
|
141
|
-
popMobileRowMenu(popupTargetFromElement(ele), this.rowId, this.tableViewLogic, this.view);
|
|
142
|
-
};
|
|
143
200
|
const isTitle = column.view.mainProperties$.value.titleColumn === column.id;
|
|
144
|
-
const hasOps = isTitle && !column.readonly$.value;
|
|
145
201
|
return html `
|
|
146
202
|
<div
|
|
147
|
-
class="${isTitle ? mobileStickyTitle : ''}"
|
|
203
|
+
class="${isTitle ? `${mobileStickyTitle} mobile-row-title` : ''}"
|
|
148
204
|
style="display: flex;"
|
|
149
205
|
>
|
|
150
206
|
<mobile-table-cell
|
|
@@ -152,8 +208,8 @@ let MobileTableRow = (() => {
|
|
|
152
208
|
style=${styleMap({
|
|
153
209
|
width: `${column.width$.value}px`,
|
|
154
210
|
border: i === 0 ? 'none' : undefined,
|
|
155
|
-
// Room for the
|
|
156
|
-
paddingRight:
|
|
211
|
+
// Room for the "Open" chip drawn over its right end.
|
|
212
|
+
paddingRight: isTitle ? `${ROW_OPEN_WIDTH}px` : undefined,
|
|
157
213
|
})}
|
|
158
214
|
.tableViewLogic="${this.tableViewLogic}"
|
|
159
215
|
.column="${column}"
|
|
@@ -168,16 +224,15 @@ let MobileTableRow = (() => {
|
|
|
168
224
|
>
|
|
169
225
|
</mobile-table-cell>
|
|
170
226
|
<div class="${cellDivider}"></div>
|
|
171
|
-
${
|
|
172
|
-
? html
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
${
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
: nothing}
|
|
227
|
+
${isTitle
|
|
228
|
+
? html `<div
|
|
229
|
+
class="mobile-row-open"
|
|
230
|
+
data-testid="dv-row-open"
|
|
231
|
+
role="button"
|
|
232
|
+
aria-label="${openLabel}"
|
|
233
|
+
@click="${this.openRow}"
|
|
234
|
+
>
|
|
235
|
+
${openLabel}
|
|
181
236
|
</div>`
|
|
182
237
|
: nothing}
|
|
183
238
|
</div>
|
|
@@ -186,13 +241,13 @@ let MobileTableRow = (() => {
|
|
|
186
241
|
<div class="database-cell add-column-button"></div>
|
|
187
242
|
`;
|
|
188
243
|
}
|
|
189
|
-
#tableViewLogic_accessor_storage
|
|
244
|
+
#tableViewLogic_accessor_storage;
|
|
190
245
|
get tableViewLogic() { return this.#tableViewLogic_accessor_storage; }
|
|
191
246
|
set tableViewLogic(value) { this.#tableViewLogic_accessor_storage = value; }
|
|
192
|
-
#rowId_accessor_storage
|
|
247
|
+
#rowId_accessor_storage;
|
|
193
248
|
get rowId() { return this.#rowId_accessor_storage; }
|
|
194
249
|
set rowId(value) { this.#rowId_accessor_storage = value; }
|
|
195
|
-
#rowIndex_accessor_storage
|
|
250
|
+
#rowIndex_accessor_storage;
|
|
196
251
|
get rowIndex() { return this.#rowIndex_accessor_storage; }
|
|
197
252
|
set rowIndex(value) { this.#rowIndex_accessor_storage = value; }
|
|
198
253
|
get view() {
|
|
@@ -200,6 +255,25 @@ let MobileTableRow = (() => {
|
|
|
200
255
|
}
|
|
201
256
|
constructor() {
|
|
202
257
|
super(...arguments);
|
|
258
|
+
this.#std_accessor_storage = __runInitializers(this, _std_initializers, void 0);
|
|
259
|
+
this.pressTimer = __runInitializers(this, _std_extraInitializers);
|
|
260
|
+
/** A long press fired: the click the finger's release makes is eaten. */
|
|
261
|
+
this.pressFired = false;
|
|
262
|
+
this.cancelPress = () => {
|
|
263
|
+
clearTimeout(this.pressTimer);
|
|
264
|
+
this.pressTimer = undefined;
|
|
265
|
+
this.pressOrigin = undefined;
|
|
266
|
+
};
|
|
267
|
+
this.openRow = (e) => {
|
|
268
|
+
e.stopPropagation();
|
|
269
|
+
this.tableViewLogic.root.openDetailPanel({
|
|
270
|
+
view: this.view,
|
|
271
|
+
rowId: this.rowId,
|
|
272
|
+
});
|
|
273
|
+
};
|
|
274
|
+
this.#tableViewLogic_accessor_storage = __runInitializers(this, _tableViewLogic_initializers, void 0);
|
|
275
|
+
this.#rowId_accessor_storage = (__runInitializers(this, _tableViewLogic_extraInitializers), __runInitializers(this, _rowId_initializers, void 0));
|
|
276
|
+
this.#rowIndex_accessor_storage = (__runInitializers(this, _rowId_extraInitializers), __runInitializers(this, _rowIndex_initializers, void 0));
|
|
203
277
|
__runInitializers(this, _rowIndex_extraInitializers);
|
|
204
278
|
}
|
|
205
279
|
};
|
|
@@ -8,7 +8,11 @@ export declare class MobileTableViewUILogic extends DataViewUILogicBase<TableSin
|
|
|
8
8
|
ui$: import("@preact/signals-core").Signal<MobileTableViewUI | undefined>;
|
|
9
9
|
private get readonly();
|
|
10
10
|
clearSelection: () => void;
|
|
11
|
-
|
|
11
|
+
/**
|
|
12
|
+
* A new row opens at once, as on the desktop table and the flat views: on a
|
|
13
|
+
* phone its title and properties are typed in the row page.
|
|
14
|
+
*/
|
|
15
|
+
addRow: (position: InsertToPosition, groupKey?: string) => string | undefined;
|
|
12
16
|
focusFirstCell: () => void;
|
|
13
17
|
showIndicator: (_evt: MouseEvent) => boolean;
|
|
14
18
|
hideIndicator: () => void;
|
|
@@ -13,10 +13,17 @@ export class MobileTableViewUILogic extends DataViewUILogicBase {
|
|
|
13
13
|
super(...arguments);
|
|
14
14
|
this.ui$ = signal(undefined);
|
|
15
15
|
this.clearSelection = () => { };
|
|
16
|
-
|
|
16
|
+
/**
|
|
17
|
+
* A new row opens at once, as on the desktop table and the flat views: on a
|
|
18
|
+
* phone its title and properties are typed in the row page.
|
|
19
|
+
*/
|
|
20
|
+
this.addRow = (position, groupKey) => {
|
|
17
21
|
if (this.readonly)
|
|
18
22
|
return;
|
|
19
|
-
|
|
23
|
+
const rowId = this.view.rowAdd(position, groupKey);
|
|
24
|
+
if (rowId)
|
|
25
|
+
this.root.openDetailPanel({ view: this.view, rowId });
|
|
26
|
+
return rowId;
|
|
20
27
|
};
|
|
21
28
|
this.focusFirstCell = () => { };
|
|
22
29
|
this.showIndicator = (_evt) => {
|
|
@@ -259,7 +259,11 @@ let TableRowView = (() => {
|
|
|
259
259
|
${!column.readonly$.value &&
|
|
260
260
|
column.view.mainProperties$.value.titleColumn === column.id
|
|
261
261
|
? html `<div class="row-ops show-on-hover-row">
|
|
262
|
-
<div
|
|
262
|
+
<div
|
|
263
|
+
class="row-op"
|
|
264
|
+
data-testid="dv-row-open"
|
|
265
|
+
@click="${clickDetail}"
|
|
266
|
+
>
|
|
263
267
|
${CenterPeekIcon()}
|
|
264
268
|
</div>
|
|
265
269
|
${!view.readonly$.value
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { IS_MOBILE } from '../../../../global/env/index.js';
|
|
2
1
|
import { html } from 'lit';
|
|
3
2
|
import { filterTraitKey } from '../../../core/filter/trait.js';
|
|
4
3
|
export const renderFilterBar = (props) => {
|
|
@@ -6,7 +5,7 @@ export const renderFilterBar = (props) => {
|
|
|
6
5
|
if (!filterTrait) {
|
|
7
6
|
return;
|
|
8
7
|
}
|
|
9
|
-
if (!
|
|
8
|
+
if (!filterTrait.hasFilter$.value) {
|
|
10
9
|
return;
|
|
11
10
|
}
|
|
12
11
|
return html ` <filter-bar
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { unsafeCSSVarV2 } from '../../../affine-shared/theme/index.js';
|
|
2
|
-
import { IS_MOBILE } from '../../../global/env/index.js';
|
|
3
2
|
import { html, nothing } from 'lit';
|
|
4
3
|
import { defineUniComponent, } from '../../core/index.js';
|
|
5
4
|
import { createDefaultShowQuickSettingBar, ShowQuickSettingBarKey, } from './context.js';
|
|
@@ -8,13 +7,14 @@ import { renderSortBar } from './sort/index.js';
|
|
|
8
7
|
export const widgetQuickSettingBar = defineUniComponent((props) => {
|
|
9
8
|
const view = props.dataViewLogic.view;
|
|
10
9
|
const barList = [renderSortBar(props), renderFilterBar(props)].filter(Boolean);
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
10
|
+
// The same rule on a phone since its toolbar has the filter and sort
|
|
11
|
+
// buttons (P7): up to 0.54 the bar stood there on every phone, empty but
|
|
12
|
+
// for "+ Add filter", as the only way to filter.
|
|
13
|
+
if (!view.serviceGetOrCreate(ShowQuickSettingBarKey, createDefaultShowQuickSettingBar).value[view.id]) {
|
|
14
|
+
return html ``;
|
|
15
|
+
}
|
|
16
|
+
if (!barList.length) {
|
|
17
|
+
return html ``;
|
|
18
18
|
}
|
|
19
19
|
return html ` <div
|
|
20
20
|
style="display: flex;margin-top: 8px;align-items: center;width: 100%;gap:8px"
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type BlockStdScope } from '../../../../../std/index.js';
|
|
1
2
|
import { nothing } from 'lit';
|
|
2
3
|
import { WidgetBase } from '../../../../core/widget/widget-base.js';
|
|
3
4
|
export declare class DataViewHeaderToolsFilter extends WidgetBase {
|
|
@@ -8,6 +9,8 @@ export declare class DataViewHeaderToolsFilter extends WidgetBase {
|
|
|
8
9
|
get filterTrait(): import("../../../../core/filter/trait.js").FilterTrait | undefined;
|
|
9
10
|
private get readonly();
|
|
10
11
|
private clickFilter;
|
|
12
|
+
/** Absent outside an editor host: the wordings read English. */
|
|
13
|
+
accessor std: BlockStdScope;
|
|
11
14
|
connectedCallback(): void;
|
|
12
15
|
render(): import("lit-html").TemplateResult<1> | typeof nothing;
|
|
13
16
|
toggleShowFilter(show?: boolean): void;
|
|
@@ -1,14 +1,51 @@
|
|
|
1
|
+
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
2
|
+
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
3
|
+
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
4
|
+
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
|
5
|
+
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
|
6
|
+
var _, done = false;
|
|
7
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
8
|
+
var context = {};
|
|
9
|
+
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
|
10
|
+
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
|
11
|
+
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
|
12
|
+
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
|
13
|
+
if (kind === "accessor") {
|
|
14
|
+
if (result === void 0) continue;
|
|
15
|
+
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
|
16
|
+
if (_ = accept(result.get)) descriptor.get = _;
|
|
17
|
+
if (_ = accept(result.set)) descriptor.set = _;
|
|
18
|
+
if (_ = accept(result.init)) initializers.unshift(_);
|
|
19
|
+
}
|
|
20
|
+
else if (_ = accept(result)) {
|
|
21
|
+
if (kind === "field") initializers.unshift(_);
|
|
22
|
+
else descriptor[key] = _;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
26
|
+
done = true;
|
|
27
|
+
};
|
|
28
|
+
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
29
|
+
var useValue = arguments.length > 2;
|
|
30
|
+
for (var i = 0; i < initializers.length; i++) {
|
|
31
|
+
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
32
|
+
}
|
|
33
|
+
return useValue ? value : void 0;
|
|
34
|
+
};
|
|
1
35
|
import { popupTargetFromElement } from '../../../../../affine-components/context-menu/index.js';
|
|
2
|
-
import { IS_MOBILE } from '../../../../../global/env/index.js';
|
|
3
36
|
import { FilterIcon } from '@blocksuite/icons/lit';
|
|
4
37
|
import { computed } from '@preact/signals-core';
|
|
5
38
|
import { cssVarV2 } from '@toeverything/theme/v2';
|
|
39
|
+
import { stdContext } from '../../../../../std/index.js';
|
|
40
|
+
import { consume } from '@lit/context';
|
|
6
41
|
import { css, html, nothing } from 'lit';
|
|
7
42
|
import { styleMap } from 'lit/directives/style-map.js';
|
|
8
43
|
import { popCreateFilter } from '../../../../core/filter/add-filter.js';
|
|
9
44
|
import { filterTraitKey } from '../../../../core/filter/trait.js';
|
|
10
45
|
import { emptyFilterGroup } from '../../../../core/filter/utils.js';
|
|
46
|
+
import { wordingOf } from '../../../../core/utils/wording.js';
|
|
11
47
|
import { WidgetBase } from '../../../../core/widget/widget-base.js';
|
|
48
|
+
import { DATA_VIEW_FILTER } from '../../../../translations.js';
|
|
12
49
|
import { createDefaultShowQuickSettingBar, ShowQuickSettingBarKey, } from '../../../quick-setting-bar/context.js';
|
|
13
50
|
const styles = css `
|
|
14
51
|
.affine-database-filter-button {
|
|
@@ -27,72 +64,100 @@ const styles = css `
|
|
|
27
64
|
background-color: var(--affine-hover-color);
|
|
28
65
|
}
|
|
29
66
|
|
|
30
|
-
.
|
|
67
|
+
/* Shown on a phone too, its menus as sheets: 44px for a finger (P7). */
|
|
68
|
+
@media (pointer: coarse) {
|
|
69
|
+
.affine-database-filter-button {
|
|
70
|
+
min-width: 44px;
|
|
71
|
+
min-height: 44px;
|
|
72
|
+
justify-content: center;
|
|
73
|
+
}
|
|
31
74
|
}
|
|
32
75
|
`;
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
this.
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
76
|
+
let DataViewHeaderToolsFilter = (() => {
|
|
77
|
+
let _classSuper = WidgetBase;
|
|
78
|
+
let _std_decorators;
|
|
79
|
+
let _std_initializers = [];
|
|
80
|
+
let _std_extraInitializers = [];
|
|
81
|
+
return class DataViewHeaderToolsFilter extends _classSuper {
|
|
82
|
+
static {
|
|
83
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
84
|
+
_std_decorators = [consume({ context: stdContext })];
|
|
85
|
+
__esDecorate(this, null, _std_decorators, { kind: "accessor", name: "std", static: false, private: false, access: { has: obj => "std" in obj, get: obj => obj.std, set: (obj, value) => { obj.std = value; } }, metadata: _metadata }, _std_initializers, _std_extraInitializers);
|
|
86
|
+
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
87
|
+
}
|
|
88
|
+
static { this.styles = styles; }
|
|
89
|
+
get _filter() {
|
|
90
|
+
return this.filterTrait?.filter$.value ?? emptyFilterGroup;
|
|
91
|
+
}
|
|
92
|
+
set _filter(filter) {
|
|
93
|
+
this.filterTrait?.filterSet(filter);
|
|
94
|
+
}
|
|
95
|
+
get filterTrait() {
|
|
96
|
+
return this.view.traitGet(filterTraitKey);
|
|
97
|
+
}
|
|
98
|
+
get readonly() {
|
|
99
|
+
return this.view.readonly$.value;
|
|
100
|
+
}
|
|
101
|
+
clickFilter(event) {
|
|
102
|
+
if (this.hasFilter.value) {
|
|
103
|
+
this.toggleShowFilter();
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
popCreateFilter(popupTargetFromElement(event.currentTarget), {
|
|
107
|
+
vars: this.view.vars$,
|
|
108
|
+
onSelect: filter => {
|
|
109
|
+
this._filter = {
|
|
110
|
+
...this._filter,
|
|
111
|
+
conditions: [filter],
|
|
112
|
+
};
|
|
113
|
+
this.toggleShowFilter(true);
|
|
114
|
+
this.dataViewLogic.eventTrace('CreateDatabaseFilter', {});
|
|
115
|
+
},
|
|
116
|
+
});
|
|
56
117
|
return;
|
|
57
118
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
render() {
|
|
76
|
-
if (this.readonly)
|
|
77
|
-
return nothing;
|
|
78
|
-
const style = styleMap({
|
|
79
|
-
color: this.hasFilter.value
|
|
80
|
-
? cssVarV2('text/emphasis')
|
|
81
|
-
: cssVarV2('icon/primary'),
|
|
82
|
-
});
|
|
83
|
-
return html ` <div
|
|
119
|
+
#std_accessor_storage;
|
|
120
|
+
/** Absent outside an editor host: the wordings read English. */
|
|
121
|
+
get std() { return this.#std_accessor_storage; }
|
|
122
|
+
set std(value) { this.#std_accessor_storage = value; }
|
|
123
|
+
connectedCallback() {
|
|
124
|
+
super.connectedCallback();
|
|
125
|
+
this.style.display = 'flex';
|
|
126
|
+
}
|
|
127
|
+
render() {
|
|
128
|
+
if (this.readonly)
|
|
129
|
+
return nothing;
|
|
130
|
+
const style = styleMap({
|
|
131
|
+
color: this.hasFilter.value
|
|
132
|
+
? cssVarV2('text/emphasis')
|
|
133
|
+
: cssVarV2('icon/primary'),
|
|
134
|
+
});
|
|
135
|
+
return html ` <div
|
|
84
136
|
@click="${this.clickFilter}"
|
|
85
137
|
style="${style}"
|
|
86
138
|
class="affine-database-filter-button"
|
|
139
|
+
data-testid="dv-tools-filter"
|
|
140
|
+
role="button"
|
|
141
|
+
aria-label="${wordingOf(this.std)(DATA_VIEW_FILTER)}"
|
|
87
142
|
>
|
|
88
143
|
${FilterIcon()}
|
|
89
144
|
</div>`;
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
145
|
+
}
|
|
146
|
+
toggleShowFilter(show) {
|
|
147
|
+
const map = this.view.serviceGetOrCreate(ShowQuickSettingBarKey, createDefaultShowQuickSettingBar);
|
|
148
|
+
map.value = {
|
|
149
|
+
...map.value,
|
|
150
|
+
[this.view.id]: show ?? !map.value[this.view.id],
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
constructor() {
|
|
154
|
+
super(...arguments);
|
|
155
|
+
this.hasFilter = computed(() => {
|
|
156
|
+
return this.filterTrait?.hasFilter$.value ?? false;
|
|
157
|
+
});
|
|
158
|
+
this.#std_accessor_storage = __runInitializers(this, _std_initializers, void 0);
|
|
159
|
+
__runInitializers(this, _std_extraInitializers);
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
})();
|
|
163
|
+
export { DataViewHeaderToolsFilter };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type BlockStdScope } from '../../../../../std/index.js';
|
|
1
2
|
import { nothing } from 'lit';
|
|
2
3
|
import { WidgetBase } from '../../../../core/widget/widget-base.js';
|
|
3
4
|
export declare class DataViewHeaderToolsSort extends WidgetBase {
|
|
@@ -6,6 +7,8 @@ export declare class DataViewHeaderToolsSort extends WidgetBase {
|
|
|
6
7
|
hasSort: import("@preact/signals-core").ReadonlySignal<boolean>;
|
|
7
8
|
private get readonly();
|
|
8
9
|
private clickSort;
|
|
10
|
+
/** Absent outside an editor host: the wordings read English. */
|
|
11
|
+
accessor std: BlockStdScope;
|
|
9
12
|
connectedCallback(): void;
|
|
10
13
|
render(): import("lit-html").TemplateResult<1> | typeof nothing;
|
|
11
14
|
toggleShowQuickSettingBar(show?: boolean): void;
|