@operato/form 2.0.0-alpha.130 → 2.0.0-alpha.134
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/CHANGELOG.md +24 -0
- package/dist/src/filters/filter-styles.js +21 -7
- package/dist/src/filters/filter-styles.js.map +1 -1
- package/dist/src/filters/ox-filter-personalizer.d.ts +8 -0
- package/dist/src/filters/ox-filter-personalizer.js +175 -0
- package/dist/src/filters/ox-filter-personalizer.js.map +1 -0
- package/dist/src/filters/ox-filters-form-base.d.ts +7 -2
- package/dist/src/filters/ox-filters-form-base.js +77 -26
- package/dist/src/filters/ox-filters-form-base.js.map +1 -1
- package/dist/src/types.d.ts +4 -0
- package/dist/src/types.js.map +1 -1
- package/dist/stories/ox-filters-form-base-page-preference.stories.d.ts +31 -0
- package/dist/stories/ox-filters-form-base-page-preference.stories.js +173 -0
- package/dist/stories/ox-filters-form-base-page-preference.stories.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -2
- package/src/filters/filter-styles.ts +21 -7
- package/src/filters/ox-filter-personalizer.ts +188 -0
- package/src/filters/ox-filters-form-base.ts +104 -50
- package/src/types.ts +5 -0
- package/stories/ox-filters-form-base-page-preference.stories.ts +192 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,30 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [2.0.0-alpha.134](https://github.com/hatiolab/operato/compare/v2.0.0-alpha.133...v2.0.0-alpha.134) (2024-05-13)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### :bug: Bug Fix
|
|
10
|
+
|
|
11
|
+
* ox-filter-personalizer bug on sorting ([4527ba5](https://github.com/hatiolab/operato/commit/4527ba598605d54380e81c8a00f2d5188197f757))
|
|
12
|
+
* page preference load 시에 해당 페이지의 모든 preference를 모두 로딩하도록 함 ([4f8039e](https://github.com/hatiolab/operato/commit/4f8039e6a95bdb03153a9d7b8e3e86c83b02cb47))
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
## [2.0.0-alpha.133](https://github.com/hatiolab/operato/compare/v2.0.0-alpha.132...v2.0.0-alpha.133) (2024-05-12)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
### :bug: Bug Fix
|
|
20
|
+
|
|
21
|
+
* missing dependencies ([6065a94](https://github.com/hatiolab/operato/commit/6065a94c852c3518322ec25980c4883ca6e31d93))
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
### :rocket: New Features
|
|
25
|
+
|
|
26
|
+
* add personalization for ox-filter-form-base ([c60874c](https://github.com/hatiolab/operato/commit/c60874c9f3f6ca2ef68f81d62cd3781fd62074fe))
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
6
30
|
## [2.0.0-alpha.130](https://github.com/hatiolab/operato/compare/v2.0.0-alpha.129...v2.0.0-alpha.130) (2024-05-10)
|
|
7
31
|
|
|
8
32
|
|
|
@@ -79,15 +79,29 @@ export const FilterStyles = css `
|
|
|
79
79
|
--ox-filters-input-font: normal 16px var(--theme-font);
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
-
input
|
|
83
|
-
|
|
84
|
-
|
|
82
|
+
ox-input-barcode {
|
|
83
|
+
max-width: unset;
|
|
84
|
+
flex: 1;
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
-
input
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
87
|
+
ox-input-search {
|
|
88
|
+
max-width: unset;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
ox-select {
|
|
92
|
+
max-width: unset;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
ox-checkbox {
|
|
96
|
+
max-width: unset;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
input[type='number'] {
|
|
100
|
+
max-width: unset;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
input {
|
|
104
|
+
flex: 1;
|
|
91
105
|
}
|
|
92
106
|
}
|
|
93
107
|
`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filter-styles.js","sourceRoot":"","sources":["../../../src/filters/filter-styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAA;AAEzB,MAAM,CAAC,MAAM,YAAY,GAAG,GAAG,CAAA
|
|
1
|
+
{"version":3,"file":"filter-styles.js","sourceRoot":"","sources":["../../../src/filters/filter-styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAA;AAEzB,MAAM,CAAC,MAAM,YAAY,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyG9B,CAAA","sourcesContent":["import { css } from 'lit'\n\nexport const FilterStyles = css`\n :host {\n --ox-filters-input-placeholder-color: var(--input-placeholder-color, var(--primary-color));\n\n --ox-filters-input-border: var(--input-border, 1px solid rgba(0, 0, 0, 0.2));\n --ox-filters-input-focus-border: var(--input-focus-border, 1px solid var(--primary-color));\n --ox-filters-input-font: var(--input-font, normal 14px var(--theme-font));\n --ox-filters-input-color: var(--input-color, var(--primary-text-color));\n --ox-filters-input-focus-color: var(--input-focus-color, var(--primary-color));\n --ox-filters-label-font: var(--label-font, normal 14px var(--theme-font));\n --ox-filters-label-color: var(--label-color, var(--primary-text-color));\n --ox-filters-input-background-color: transparent;\n\n --ox-filters-form-gap: var(--input-gap-vertical, 8px) var(--input-gap-horizontal, 16px);\n --ox-filters-input-padding: var(--input-padding, 6px 2px);\n\n --ox-select-padding: var(--ox-filters-input-padding);\n --ox-checkbox-background-color: var(--ox-filters-input-background-color, transparent);\n }\n\n label {\n font: var(--ox-filters-label-font);\n color: var(--ox-filters-label-color);\n }\n\n span {\n text-transform: capitalize;\n }\n\n input::placeholder {\n color: var(--ox-filters-input-placeholder-color);\n opacity: 0.6;\n }\n\n input {\n padding: var(--ox-filters-input-padding);\n }\n\n ox-select,\n input {\n border: none;\n border-bottom: var(--ox-filters-input-border);\n font: var(--ox-filters-input-font);\n color: var(--ox-filters-input-color);\n background-color: var(--ox-filters-input-background-color, transparent);\n }\n\n ox-select:focus,\n input:focus {\n outline: none;\n border-bottom: var(--ox-filters-input-focus-border);\n color: var(--ox-filters-input-focus-color);\n }\n\n ox-select {\n min-width: 90px;\n max-width: 170px;\n }\n\n ox-input-search {\n max-width: 150px;\n }\n\n input[type='number'] {\n max-width: 90px;\n }\n\n input[type*='date'],\n input[type*='time'],\n input[type='week'],\n input[type='month'] {\n max-width: 170px;\n }\n\n @media only screen and (max-width: 460px) {\n :host {\n --ox-filters-form-label-font: bold 13px var(--theme-font);\n --ox-filters-input-font: normal 16px var(--theme-font);\n }\n\n ox-input-barcode {\n max-width: unset;\n flex: 1;\n }\n\n ox-input-search {\n max-width: unset;\n }\n\n ox-select {\n max-width: unset;\n }\n\n ox-checkbox {\n max-width: unset;\n }\n\n input[type='number'] {\n max-width: unset;\n }\n\n input {\n flex: 1;\n }\n }\n`\n"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import '@material/web/button/outlined-button.js';
|
|
2
|
+
import { LitElement } from 'lit';
|
|
3
|
+
export declare class OxFilterPersonalizer extends LitElement {
|
|
4
|
+
static styles: import("lit").CSSResult[];
|
|
5
|
+
debug: boolean;
|
|
6
|
+
private preference?;
|
|
7
|
+
render(): import("lit-html").TemplateResult<1>;
|
|
8
|
+
}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { __decorate } from "tslib";
|
|
2
|
+
import '@material/web/button/outlined-button.js';
|
|
3
|
+
import { css, html, LitElement } from 'lit';
|
|
4
|
+
import { customElement, property, state } from 'lit/decorators.js';
|
|
5
|
+
import { ifDefined } from 'lit/directives/if-defined.js';
|
|
6
|
+
import { i18next } from '@operato/i18n';
|
|
7
|
+
import { OxPopupList } from '@operato/popup';
|
|
8
|
+
let OxFilterPersonalizer = class OxFilterPersonalizer extends LitElement {
|
|
9
|
+
constructor() {
|
|
10
|
+
super(...arguments);
|
|
11
|
+
this.debug = false;
|
|
12
|
+
}
|
|
13
|
+
render() {
|
|
14
|
+
return html `
|
|
15
|
+
<md-icon
|
|
16
|
+
@click=${async (e) => {
|
|
17
|
+
var _a;
|
|
18
|
+
const form = this.closest('ox-filters-form-base');
|
|
19
|
+
const { filters, personalFilters = [] } = form;
|
|
20
|
+
const queryFilters = await form.getQueryFilters();
|
|
21
|
+
this.preference = {
|
|
22
|
+
filters: (personalFilters.map(filter => {
|
|
23
|
+
var _a, _b;
|
|
24
|
+
const originFilter = filters.find(f => f.name == filter.name);
|
|
25
|
+
if (!originFilter) {
|
|
26
|
+
/* 원래 filters 설정에 있는 것들 만을 유지한다. */
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
return {
|
|
30
|
+
name: filter.name,
|
|
31
|
+
hidden: filter.hidden,
|
|
32
|
+
/* 만약, filters에 기본값이 이미 설정되어 있다면, 그대로 유지한다. */
|
|
33
|
+
value: (_a = originFilter.value) !== null && _a !== void 0 ? _a : (_b = queryFilters.find(f => f.name == filter.name)) === null || _b === void 0 ? void 0 : _b.value
|
|
34
|
+
};
|
|
35
|
+
}) || []).filter(Boolean)
|
|
36
|
+
};
|
|
37
|
+
const template = html `
|
|
38
|
+
<div class="personalizer-header" slot="header">
|
|
39
|
+
<md-icon
|
|
40
|
+
style="margin-left: auto;"
|
|
41
|
+
@click=${async (e) => {
|
|
42
|
+
if (form.personalConfigProvider) {
|
|
43
|
+
form.personalConfig = await form.personalConfigProvider.save(this.preference);
|
|
44
|
+
}
|
|
45
|
+
popup.close();
|
|
46
|
+
}}
|
|
47
|
+
title=${String(i18next.t('button.save'))}
|
|
48
|
+
>keep</md-icon
|
|
49
|
+
><md-icon
|
|
50
|
+
@click=${async (e) => {
|
|
51
|
+
if (form.personalConfigProvider) {
|
|
52
|
+
form.personalConfig = this.preference = {};
|
|
53
|
+
await form.personalConfigProvider.reset();
|
|
54
|
+
}
|
|
55
|
+
popup.close();
|
|
56
|
+
}}
|
|
57
|
+
title=${String(i18next.t('button.delete'))}
|
|
58
|
+
>keep_off</md-icon
|
|
59
|
+
><md-icon @click=${async (e) => popup.close()} title=${String(i18next.t('button.close'))}
|
|
60
|
+
>close</md-icon
|
|
61
|
+
>
|
|
62
|
+
</div>
|
|
63
|
+
|
|
64
|
+
${(_a = this.preference) === null || _a === void 0 ? void 0 : _a.filters.map(filter => html `
|
|
65
|
+
<ox-checkbox label="checkbox" ?checked=${!filter.hidden} value=${ifDefined(filter.name)} option
|
|
66
|
+
>${filter.name}<span style="position: absolute; right: 10px; cursor: move;" handle
|
|
67
|
+
>☰</span
|
|
68
|
+
></ox-checkbox
|
|
69
|
+
>
|
|
70
|
+
`)}
|
|
71
|
+
`;
|
|
72
|
+
const popup = OxPopupList.open({
|
|
73
|
+
template,
|
|
74
|
+
multiple: true,
|
|
75
|
+
sortable: true,
|
|
76
|
+
debug: this.debug,
|
|
77
|
+
attrSelected: 'checked',
|
|
78
|
+
top: e.pageY,
|
|
79
|
+
left: e.pageX,
|
|
80
|
+
styles: css `
|
|
81
|
+
:host {
|
|
82
|
+
width: 240px;
|
|
83
|
+
max-height: 300px;
|
|
84
|
+
overflow: auto;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
::slotted(.personalizer-header) {
|
|
88
|
+
--md-icon-size: 1.4em;
|
|
89
|
+
|
|
90
|
+
display: flex;
|
|
91
|
+
flex-direction: row;
|
|
92
|
+
align-items: center;
|
|
93
|
+
text-transform: capitalize;
|
|
94
|
+
box-shadow: 0 3px 3px rgba(0, 0, 0, 0.3);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
::slotted([option]) {
|
|
98
|
+
position: relative;
|
|
99
|
+
user-select: none;
|
|
100
|
+
}
|
|
101
|
+
`
|
|
102
|
+
});
|
|
103
|
+
popup.onselect = (e) => {
|
|
104
|
+
var _a;
|
|
105
|
+
const selected = e.detail;
|
|
106
|
+
const pconfig = { ...form.personalConfig };
|
|
107
|
+
const pfilters = ((_a = this.preference) === null || _a === void 0 ? void 0 : _a.filters) || form.filters;
|
|
108
|
+
pconfig.filters = pfilters.map(filter => {
|
|
109
|
+
return {
|
|
110
|
+
name: filter.name,
|
|
111
|
+
hidden: selected.indexOf(filter.name) == -1,
|
|
112
|
+
value: filter.value
|
|
113
|
+
};
|
|
114
|
+
});
|
|
115
|
+
form.personalConfig = this.preference = pconfig;
|
|
116
|
+
form.applyUpdatedConfiguration();
|
|
117
|
+
};
|
|
118
|
+
popup.addEventListener('sorted', (e) => {
|
|
119
|
+
var _a;
|
|
120
|
+
const sorted = e.detail;
|
|
121
|
+
const pconfig = { ...form.personalConfig };
|
|
122
|
+
const pfilters = ((_a = this.preference) === null || _a === void 0 ? void 0 : _a.filters) || form.filters;
|
|
123
|
+
pconfig.filters = sorted
|
|
124
|
+
.map(element => {
|
|
125
|
+
const name = element.value;
|
|
126
|
+
return pfilters.find(filter => filter.name == name);
|
|
127
|
+
})
|
|
128
|
+
.filter(Boolean);
|
|
129
|
+
form.personalConfig = this.preference = pconfig;
|
|
130
|
+
form.applyUpdatedConfiguration();
|
|
131
|
+
});
|
|
132
|
+
}}
|
|
133
|
+
>settings<md-ripple></md-ripple
|
|
134
|
+
></md-icon>
|
|
135
|
+
`;
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
OxFilterPersonalizer.styles = [
|
|
139
|
+
css `
|
|
140
|
+
md-icon {
|
|
141
|
+
--md-icon-size: 16px;
|
|
142
|
+
width: 36px;
|
|
143
|
+
height: 36px;
|
|
144
|
+
color: var(--md-sys-color-secondary-container);
|
|
145
|
+
cursor: pointer;
|
|
146
|
+
|
|
147
|
+
display: flex;
|
|
148
|
+
place-content: center;
|
|
149
|
+
place-items: center;
|
|
150
|
+
position: relative;
|
|
151
|
+
|
|
152
|
+
&:hover {
|
|
153
|
+
color: var(--md-sys-color-primary-container);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
md-ripple {
|
|
158
|
+
border-radius: 50%;
|
|
159
|
+
inset: unset;
|
|
160
|
+
height: 36px;
|
|
161
|
+
width: 36px;
|
|
162
|
+
}
|
|
163
|
+
`
|
|
164
|
+
];
|
|
165
|
+
__decorate([
|
|
166
|
+
property({ type: Boolean, attribute: true })
|
|
167
|
+
], OxFilterPersonalizer.prototype, "debug", void 0);
|
|
168
|
+
__decorate([
|
|
169
|
+
state()
|
|
170
|
+
], OxFilterPersonalizer.prototype, "preference", void 0);
|
|
171
|
+
OxFilterPersonalizer = __decorate([
|
|
172
|
+
customElement('ox-filter-personalizer')
|
|
173
|
+
], OxFilterPersonalizer);
|
|
174
|
+
export { OxFilterPersonalizer };
|
|
175
|
+
//# sourceMappingURL=ox-filter-personalizer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ox-filter-personalizer.js","sourceRoot":"","sources":["../../../src/filters/ox-filter-personalizer.ts"],"names":[],"mappings":";AAAA,OAAO,yCAAyC,CAAA;AAEhD,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,KAAK,CAAA;AAC3C,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAClE,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAA;AAExD,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAQrC,IAAM,oBAAoB,GAA1B,MAAM,oBAAqB,SAAQ,UAAU;IAA7C;;QA6ByC,UAAK,GAAY,KAAK,CAAA;IA+ItE,CAAC;IA3IC,MAAM;QACJ,OAAO,IAAI,CAAA;;iBAEE,KAAK,EAAE,CAAa,EAAE,EAAE;;YAC/B,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,sBAAsB,CAAsB,CAAA;YACtE,MAAM,EAAE,OAAO,EAAE,eAAe,GAAG,EAAE,EAAE,GAAG,IAAI,CAAA;YAC9C,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,eAAe,EAAE,CAAA;YAEjD,IAAI,CAAC,UAAU,GAAG;gBAChB,OAAO,EAAE,CACP,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE;;oBAC3B,MAAM,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,CAAA;oBAE7D,IAAI,CAAC,YAAY,EAAE,CAAC;wBAClB,mCAAmC;wBACnC,OAAM;oBACR,CAAC;oBAED,OAAO;wBACL,IAAI,EAAE,MAAM,CAAC,IAAI;wBACjB,MAAM,EAAE,MAAM,CAAC,MAAM;wBACrB,8CAA8C;wBAC9C,KAAK,EAAE,MAAA,YAAa,CAAC,KAAK,mCAAI,MAAA,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,0CAAE,KAAK;qBACnF,CAAA;gBACH,CAAC,CAAC,IAAI,EAAE,CACT,CAAC,MAAM,CAAC,OAAO,CAA4B;aAC7C,CAAA;YAED,MAAM,QAAQ,GAAG,IAAI,CAAA;;;;yBAIN,KAAK,EAAE,CAAa,EAAE,EAAE;gBAC/B,IAAI,IAAI,CAAC,sBAAsB,EAAE,CAAC;oBAChC,IAAI,CAAC,cAAc,GAAG,MAAM,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;gBAC/E,CAAC;gBACD,KAAK,CAAC,KAAK,EAAE,CAAA;YACf,CAAC;wBACO,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC;;;yBAG/B,KAAK,EAAE,CAAa,EAAE,EAAE;gBAC/B,IAAI,IAAI,CAAC,sBAAsB,EAAE,CAAC;oBAChC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,UAAU,GAAG,EAAE,CAAA;oBAC1C,MAAM,IAAI,CAAC,sBAAsB,CAAC,KAAK,EAAE,CAAA;gBAC3C,CAAC;gBACD,KAAK,CAAC,KAAK,EAAE,CAAA;YACf,CAAC;wBACO,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC;;iCAEzB,KAAK,EAAE,CAAa,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,UAAU,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC;;;;;cAKpG,MAAA,IAAI,CAAC,UAAU,0CAAE,OAAO,CAAE,GAAG,CAC7B,MAAM,CAAC,EAAE,CAAC,IAAI,CAAA;yDAC6B,CAAC,MAAM,CAAC,MAAM,UAAU,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC;qBAClF,MAAM,CAAC,IAAI;;;;eAIjB,CACF;WACF,CAAA;YAED,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC;gBAC7B,QAAQ;gBACR,QAAQ,EAAE,IAAI;gBACd,QAAQ,EAAE,IAAI;gBACd,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,YAAY,EAAE,SAAS;gBACvB,GAAG,EAAE,CAAC,CAAC,KAAK;gBACZ,IAAI,EAAE,CAAC,CAAC,KAAK;gBACb,MAAM,EAAE,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;aAqBV;aACF,CAAC,CAAA;YAEF,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAQ,EAAE,EAAE;;gBAC5B,MAAM,QAAQ,GAAI,CAAiB,CAAC,MAAM,CAAA;gBAE1C,MAAM,OAAO,GAA6B,EAAE,GAAG,IAAI,CAAC,cAAc,EAAE,CAAA;gBACpE,MAAM,QAAQ,GAAG,CAAA,MAAA,IAAI,CAAC,UAAU,0CAAE,OAAO,KAAI,IAAI,CAAC,OAAO,CAAA;gBAEzD,OAAO,CAAC,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE;oBACtC,OAAO;wBACL,IAAI,EAAE,MAAM,CAAC,IAAI;wBACjB,MAAM,EAAE,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;wBAC3C,KAAK,EAAE,MAAM,CAAC,KAAK;qBACpB,CAAA;gBACH,CAAC,CAAC,CAAA;gBAEF,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,UAAU,GAAG,OAAO,CAAA;gBAE/C,IAAI,CAAC,yBAAyB,EAAE,CAAA;YAClC,CAAC,CAAA;YAED,KAAK,CAAC,gBAAgB,CAAC,QAAQ,EAAE,CAAC,CAAQ,EAAE,EAAE;;gBAC5C,MAAM,MAAM,GAAI,CAAiB,CAAC,MAAuB,CAAA;gBAEzD,MAAM,OAAO,GAA6B,EAAE,GAAG,IAAI,CAAC,cAAc,EAAE,CAAA;gBACpE,MAAM,QAAQ,GAAG,CAAA,MAAA,IAAI,CAAC,UAAU,0CAAE,OAAO,KAAI,IAAI,CAAC,OAAO,CAAA;gBAEzD,OAAO,CAAC,OAAO,GAAG,MAAM;qBACrB,GAAG,CAAC,OAAO,CAAC,EAAE;oBACb,MAAM,IAAI,GAAI,OAAsB,CAAC,KAAK,CAAA;oBAC1C,OAAO,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,IAAI,IAAI,CAAE,CAAA;gBACtD,CAAC,CAAC;qBACD,MAAM,CAAC,OAAO,CAAC,CAAA;gBAElB,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,UAAU,GAAG,OAAO,CAAA;gBAE/C,IAAI,CAAC,yBAAyB,EAAE,CAAA;YAClC,CAAC,CAAC,CAAA;QACJ,CAAC;;;KAGJ,CAAA;IACH,CAAC;;AA1KM,2BAAM,GAAG;IACd,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;KAwBF;CACF,AA1BY,CA0BZ;AAE6C;IAA7C,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;mDAAuB;AAEnD;IAAhB,KAAK,EAAE;wDAA8C;AA/B3C,oBAAoB;IADhC,aAAa,CAAC,wBAAwB,CAAC;GAC3B,oBAAoB,CA4KhC","sourcesContent":["import '@material/web/button/outlined-button.js'\n\nimport { css, html, LitElement } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { ifDefined } from 'lit/directives/if-defined.js'\n\nimport { i18next } from '@operato/i18n'\nimport { OxPopupList } from '@operato/popup'\n\nimport { FilterConfig, PersonalFilterPreference } from '../types.js'\n\nimport { OxFiltersFormBase } from './ox-filters-form-base'\nimport { OxCheckbox } from '@operato/input'\n\n@customElement('ox-filter-personalizer')\nexport class OxFilterPersonalizer extends LitElement {\n static styles = [\n css`\n md-icon {\n --md-icon-size: 16px;\n width: 36px;\n height: 36px;\n color: var(--md-sys-color-secondary-container);\n cursor: pointer;\n\n display: flex;\n place-content: center;\n place-items: center;\n position: relative;\n\n &:hover {\n color: var(--md-sys-color-primary-container);\n }\n }\n\n md-ripple {\n border-radius: 50%;\n inset: unset;\n height: 36px;\n width: 36px;\n }\n `\n ]\n\n @property({ type: Boolean, attribute: true }) debug: boolean = false\n\n @state() private preference?: PersonalFilterPreference\n\n render() {\n return html`\n <md-icon\n @click=${async (e: MouseEvent) => {\n const form = this.closest('ox-filters-form-base') as OxFiltersFormBase\n const { filters, personalFilters = [] } = form\n const queryFilters = await form.getQueryFilters()\n\n this.preference = {\n filters: (\n personalFilters.map(filter => {\n const originFilter = filters.find(f => f.name == filter.name)\n\n if (!originFilter) {\n /* 원래 filters 설정에 있는 것들 만을 유지한다. */\n return\n }\n\n return {\n name: filter.name,\n hidden: filter.hidden,\n /* 만약, filters에 기본값이 이미 설정되어 있다면, 그대로 유지한다. */\n value: originFilter!.value ?? queryFilters.find(f => f.name == filter.name)?.value\n }\n }) || []\n ).filter(Boolean) as Partial<FilterConfig>[]\n }\n\n const template = html`\n <div class=\"personalizer-header\" slot=\"header\">\n <md-icon\n style=\"margin-left: auto;\"\n @click=${async (e: MouseEvent) => {\n if (form.personalConfigProvider) {\n form.personalConfig = await form.personalConfigProvider.save(this.preference)\n }\n popup.close()\n }}\n title=${String(i18next.t('button.save'))}\n >keep</md-icon\n ><md-icon\n @click=${async (e: MouseEvent) => {\n if (form.personalConfigProvider) {\n form.personalConfig = this.preference = {}\n await form.personalConfigProvider.reset()\n }\n popup.close()\n }}\n title=${String(i18next.t('button.delete'))}\n >keep_off</md-icon\n ><md-icon @click=${async (e: MouseEvent) => popup.close()} title=${String(i18next.t('button.close'))}\n >close</md-icon\n >\n </div>\n\n ${this.preference?.filters!.map(\n filter => html`\n <ox-checkbox label=\"checkbox\" ?checked=${!filter.hidden} value=${ifDefined(filter.name)} option\n >${filter.name}<span style=\"position: absolute; right: 10px; cursor: move;\" handle\n >☰</span\n ></ox-checkbox\n >\n `\n )}\n `\n\n const popup = OxPopupList.open({\n template,\n multiple: true,\n sortable: true,\n debug: this.debug,\n attrSelected: 'checked',\n top: e.pageY,\n left: e.pageX,\n styles: css`\n :host {\n width: 240px;\n max-height: 300px;\n overflow: auto;\n }\n\n ::slotted(.personalizer-header) {\n --md-icon-size: 1.4em;\n\n display: flex;\n flex-direction: row;\n align-items: center;\n text-transform: capitalize;\n box-shadow: 0 3px 3px rgba(0, 0, 0, 0.3);\n }\n\n ::slotted([option]) {\n position: relative;\n user-select: none;\n }\n `\n })\n\n popup.onselect = (e: Event) => {\n const selected = (e as CustomEvent).detail\n\n const pconfig: PersonalFilterPreference = { ...form.personalConfig }\n const pfilters = this.preference?.filters || form.filters\n\n pconfig.filters = pfilters.map(filter => {\n return {\n name: filter.name,\n hidden: selected.indexOf(filter.name) == -1,\n value: filter.value\n }\n })\n\n form.personalConfig = this.preference = pconfig\n\n form.applyUpdatedConfiguration()\n }\n\n popup.addEventListener('sorted', (e: Event) => {\n const sorted = (e as CustomEvent).detail as HTMLElement[]\n\n const pconfig: PersonalFilterPreference = { ...form.personalConfig }\n const pfilters = this.preference?.filters || form.filters\n\n pconfig.filters = sorted\n .map(element => {\n const name = (element as OxCheckbox).value\n return pfilters.find(filter => filter.name == name)!\n })\n .filter(Boolean)\n\n form.personalConfig = this.preference = pconfig\n\n form.applyUpdatedConfiguration()\n })\n }}\n >settings<md-ripple></md-ripple\n ></md-icon>\n `\n }\n}\n"]}
|
|
@@ -3,7 +3,8 @@ import '@operato/input/ox-select.js';
|
|
|
3
3
|
import '@operato/popup/ox-popup-list.js';
|
|
4
4
|
import '@operato/input/ox-input-search.js';
|
|
5
5
|
import { LitElement, PropertyValues, TemplateResult } from 'lit';
|
|
6
|
-
import {
|
|
6
|
+
import { PagePreferenceProvider } from '@operato/p13n';
|
|
7
|
+
import { FilterConfig, FilterOperator, FilterSelectRenderer, FilterValue, PersonalFilterPreference } from '../types.js';
|
|
7
8
|
export type QueryFilterRangeValue = [from: number, to: number];
|
|
8
9
|
export declare class OxFiltersFormBase extends LitElement {
|
|
9
10
|
static styles: import("lit").CSSResult[];
|
|
@@ -11,6 +12,9 @@ export declare class OxFiltersFormBase extends LitElement {
|
|
|
11
12
|
filters: FilterConfig[];
|
|
12
13
|
urlParamsSensitive?: boolean;
|
|
13
14
|
autofocus: boolean;
|
|
15
|
+
personalConfigProvider?: PagePreferenceProvider;
|
|
16
|
+
personalConfig?: PersonalFilterPreference;
|
|
17
|
+
personalFilters?: FilterConfig[];
|
|
14
18
|
form: HTMLFormElement;
|
|
15
19
|
private _popstateEventHandler?;
|
|
16
20
|
private _filtersChangeHandler?;
|
|
@@ -19,8 +23,9 @@ export declare class OxFiltersFormBase extends LitElement {
|
|
|
19
23
|
buildDefaultValue(operator: FilterOperator, defaultValue: any): any;
|
|
20
24
|
render(): TemplateResult;
|
|
21
25
|
renderSelect(filter: FilterConfig, value: any, renderer: FilterSelectRenderer): TemplateResult<1>;
|
|
22
|
-
getFieldByName(name: string): Element | null;
|
|
23
26
|
updated(changes: PropertyValues<this>): Promise<void>;
|
|
27
|
+
applyUpdatedConfiguration(): Promise<void>;
|
|
28
|
+
getFieldByName(name: string): Element | null;
|
|
24
29
|
getQueryFilters(): Promise<FilterValue[]>;
|
|
25
30
|
reset(): void;
|
|
26
31
|
}
|
|
@@ -5,7 +5,7 @@ import '@operato/popup/ox-popup-list.js';
|
|
|
5
5
|
import '@operato/input/ox-input-search.js';
|
|
6
6
|
import json5 from 'json5';
|
|
7
7
|
import { css, html, LitElement, nothing } from 'lit';
|
|
8
|
-
import { customElement, property, queryAsync } from 'lit/decorators.js';
|
|
8
|
+
import { customElement, property, queryAsync, state } from 'lit/decorators.js';
|
|
9
9
|
import { getDefaultValue } from '@operato/time-calculator';
|
|
10
10
|
import { FilterStyles } from './filter-styles.js';
|
|
11
11
|
import { getFilterRenderer } from './registry.js';
|
|
@@ -22,7 +22,7 @@ let OxFiltersFormBase = class OxFiltersFormBase extends LitElement {
|
|
|
22
22
|
this.renderRoot.addEventListener('change', async (e) => {
|
|
23
23
|
const { target, detail: value } = e;
|
|
24
24
|
const name = target.name;
|
|
25
|
-
const { label, type, operator, value: defaultValue, onchange } = this.
|
|
25
|
+
const { label, type, operator, value: defaultValue, onchange } = (this.personalFilters || []).find(filter => filter.name == name) || {};
|
|
26
26
|
if (this.autoUpdateTargetsOnChange[name]) {
|
|
27
27
|
/*
|
|
28
28
|
일단은 심플하게, boundTo로 연결된 필터값이 바뀌면, 폼 전체를 update하도록 함.
|
|
@@ -55,7 +55,7 @@ let OxFiltersFormBase = class OxFiltersFormBase extends LitElement {
|
|
|
55
55
|
return;
|
|
56
56
|
}
|
|
57
57
|
if (operator == 'between') {
|
|
58
|
-
return defaultValue.map(v => getDefaultValue(v, this));
|
|
58
|
+
return defaultValue instanceof Array && defaultValue.map(v => getDefaultValue(v, this));
|
|
59
59
|
}
|
|
60
60
|
else {
|
|
61
61
|
return getDefaultValue(defaultValue, this);
|
|
@@ -68,7 +68,9 @@ let OxFiltersFormBase = class OxFiltersFormBase extends LitElement {
|
|
|
68
68
|
e.preventDefault();
|
|
69
69
|
}}
|
|
70
70
|
>
|
|
71
|
-
${this.
|
|
71
|
+
${(this.personalFilters || [])
|
|
72
|
+
.filter(filter => !filter.hidden)
|
|
73
|
+
.map((filter) => {
|
|
72
74
|
var _a, _b, _c;
|
|
73
75
|
const { name, label, type, operator, value: defaultValue } = filter;
|
|
74
76
|
const idx = operator === 'between' ? 1 : 0;
|
|
@@ -85,13 +87,15 @@ let OxFiltersFormBase = class OxFiltersFormBase extends LitElement {
|
|
|
85
87
|
? renderer(filter, value, this)
|
|
86
88
|
: type !== 'select'
|
|
87
89
|
? html `
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
90
|
+
<label filter-title ?between=${operator == 'between'}
|
|
91
|
+
><span>${label}</span> ${renderer(filter, value, this)}
|
|
92
|
+
</label>
|
|
93
|
+
`
|
|
92
94
|
: this.renderSelect(filter, value, renderer);
|
|
93
95
|
})}
|
|
94
96
|
</form>
|
|
97
|
+
|
|
98
|
+
<slot name="setting"></slot>
|
|
95
99
|
`;
|
|
96
100
|
}
|
|
97
101
|
renderSelect(filter, value, renderer) {
|
|
@@ -138,11 +142,7 @@ let OxFiltersFormBase = class OxFiltersFormBase extends LitElement {
|
|
|
138
142
|
</ox-select>
|
|
139
143
|
`;
|
|
140
144
|
}
|
|
141
|
-
getFieldByName(name) {
|
|
142
|
-
return this.renderRoot.querySelector(`[name=${name}]`);
|
|
143
|
-
}
|
|
144
145
|
async updated(changes) {
|
|
145
|
-
var _a;
|
|
146
146
|
if (changes.has('urlParamsSensitive')) {
|
|
147
147
|
if (this.urlParamsSensitive) {
|
|
148
148
|
this._popstateEventHandler = () => {
|
|
@@ -196,24 +196,65 @@ let OxFiltersFormBase = class OxFiltersFormBase extends LitElement {
|
|
|
196
196
|
}
|
|
197
197
|
}
|
|
198
198
|
}
|
|
199
|
-
if (changes.has('
|
|
200
|
-
this.
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
199
|
+
if (changes.has('personalConfigProvider') && this.personalConfigProvider) {
|
|
200
|
+
this.personalConfig = await this.personalConfigProvider.load();
|
|
201
|
+
}
|
|
202
|
+
else if (changes.has('filters') || changes.has('personalConfig')) {
|
|
203
|
+
this.applyUpdatedConfiguration();
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
async applyUpdatedConfiguration() {
|
|
207
|
+
var _a;
|
|
208
|
+
if (!this.personalConfig) {
|
|
209
|
+
this.personalFilters = [...this.filters];
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
const { filters: personalFilters } = this.personalConfig;
|
|
213
|
+
if (personalFilters) {
|
|
214
|
+
const xfilters = this.filters.map((filter) => {
|
|
215
|
+
const personalFilter = personalFilters.find(pFilter => pFilter.name == filter.name);
|
|
216
|
+
return personalFilter ? { ...filter, ...personalFilter } : filter;
|
|
207
217
|
});
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
218
|
+
function reorderList(a, b) {
|
|
219
|
+
// 결과 배열 초기화, a 배열 길이만큼 undefined로 채움
|
|
220
|
+
const result = new Array(a.length);
|
|
221
|
+
// b 배열에 없는 아이템은 원래 위치로 채움
|
|
222
|
+
a.forEach((item, index) => {
|
|
223
|
+
if (!item.name || !b.find(bi => bi.name == item.name)) {
|
|
224
|
+
result[index] = item;
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
b.forEach(item => {
|
|
228
|
+
const ai = a.find(ai => ai.name == item.name);
|
|
229
|
+
if (ai) {
|
|
230
|
+
result[result.findIndex(slot => slot === undefined)] = ai;
|
|
231
|
+
}
|
|
232
|
+
});
|
|
233
|
+
return result;
|
|
234
|
+
}
|
|
235
|
+
// 배열 재정렬 실행
|
|
236
|
+
this.personalFilters = reorderList(xfilters, personalFilters);
|
|
211
237
|
}
|
|
212
238
|
}
|
|
239
|
+
this.autoUpdateTargetsOnChange = {};
|
|
240
|
+
(_a = this.personalFilters) === null || _a === void 0 ? void 0 : _a.filter(filter => filter.boundTo && filter.boundTo.length > 0).map(({ name, boundTo }) => {
|
|
241
|
+
boundTo.forEach(to => {
|
|
242
|
+
const origin = this.autoUpdateTargetsOnChange[to] || [];
|
|
243
|
+
if (name && !origin.includes(name)) {
|
|
244
|
+
this.autoUpdateTargetsOnChange[to] = [...origin, name];
|
|
245
|
+
}
|
|
246
|
+
});
|
|
247
|
+
});
|
|
248
|
+
if (!this.urlParamsSensitive) {
|
|
249
|
+
this.value = await this.getQueryFilters();
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
getFieldByName(name) {
|
|
253
|
+
return this.renderRoot.querySelector(`[name=${name}]`);
|
|
213
254
|
}
|
|
214
255
|
async getQueryFilters() {
|
|
215
256
|
const formData = new FormData(await this.form);
|
|
216
|
-
var filters = this.
|
|
257
|
+
var filters = (this.personalFilters || [])
|
|
217
258
|
.map((filter) => {
|
|
218
259
|
const { name, type, operator } = filter;
|
|
219
260
|
var value = formData.getAll(name);
|
|
@@ -283,8 +324,9 @@ OxFiltersFormBase.styles = [
|
|
|
283
324
|
}
|
|
284
325
|
|
|
285
326
|
@media only screen and (max-width: 460px) {
|
|
286
|
-
|
|
287
|
-
|
|
327
|
+
form {
|
|
328
|
+
flex-direction: column;
|
|
329
|
+
flex-flow: column;
|
|
288
330
|
}
|
|
289
331
|
}
|
|
290
332
|
`
|
|
@@ -301,6 +343,15 @@ __decorate([
|
|
|
301
343
|
__decorate([
|
|
302
344
|
property({ type: Boolean, attribute: 'autofocus' })
|
|
303
345
|
], OxFiltersFormBase.prototype, "autofocus", void 0);
|
|
346
|
+
__decorate([
|
|
347
|
+
property({ type: Object })
|
|
348
|
+
], OxFiltersFormBase.prototype, "personalConfigProvider", void 0);
|
|
349
|
+
__decorate([
|
|
350
|
+
state()
|
|
351
|
+
], OxFiltersFormBase.prototype, "personalConfig", void 0);
|
|
352
|
+
__decorate([
|
|
353
|
+
state()
|
|
354
|
+
], OxFiltersFormBase.prototype, "personalFilters", void 0);
|
|
304
355
|
__decorate([
|
|
305
356
|
queryAsync('form')
|
|
306
357
|
], OxFiltersFormBase.prototype, "form", void 0);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ox-filters-form-base.js","sourceRoot":"","sources":["../../../src/filters/ox-filters-form-base.ts"],"names":[],"mappings":"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","sourcesContent":["import '@operato/input/ox-checkbox.js'\nimport '@operato/input/ox-select.js'\nimport '@operato/popup/ox-popup-list.js'\nimport '@operato/input/ox-input-search.js'\n\nimport json5 from 'json5'\nimport { css, html, LitElement, nothing, PropertyValues, TemplateResult } from 'lit'\nimport { customElement, property, queryAsync } from 'lit/decorators.js'\n\nimport { getDefaultValue } from '@operato/time-calculator'\n\nimport { FilterStyles } from './filter-styles.js'\nimport { getFilterRenderer } from './registry.js'\nimport { FilterConfig, FilterOperator, FilterSelectRenderer, FilterValue } from '../types.js'\n\nexport type QueryFilterRangeValue = [from: number, to: number]\n\n@customElement('ox-filters-form-base')\nexport class OxFiltersFormBase extends LitElement {\n static styles = [\n FilterStyles,\n css`\n :host {\n display: flex;\n }\n\n form {\n flex: 1;\n\n display: flex;\n flex-flow: row wrap;\n gap: var(--ox-filters-form-gap);\n }\n\n form > * {\n display: flex;\n align-items: center;\n gap: var(--input-intra-gap, 7px);\n }\n\n label span {\n display: block;\n }\n\n @media only screen and (max-width: 460px) {\n label[between] {\n display: block;\n }\n }\n `\n ]\n\n @property({ type: Array }) value: FilterValue[] = []\n @property({ type: Array }) filters: FilterConfig[] = []\n @property({ type: Boolean, attribute: 'url-params-sensitive' }) urlParamsSensitive?: boolean\n @property({ type: Boolean, attribute: 'autofocus' }) autofocus: boolean = true\n\n @queryAsync('form') form!: HTMLFormElement\n\n private _popstateEventHandler?: EventListener\n private _filtersChangeHandler?: EventListener\n private autoUpdateTargetsOnChange: { [name: string]: string[] } = {}\n\n connectedCallback(): void {\n super.connectedCallback()\n\n this.renderRoot.addEventListener('change', async (e: Event) => {\n const { target, detail: value } = e as CustomEvent\n const name = (target as HTMLInputElement).name\n const {\n label,\n type,\n operator,\n value: defaultValue,\n onchange\n } = this.filters.find(filter => filter.name == name) || {}\n\n if (this.autoUpdateTargetsOnChange[name]) {\n /* \n 일단은 심플하게, boundTo로 연결된 필터값이 바뀌면, 폼 전체를 update하도록 함.\n */\n ;(this.autoUpdateTargetsOnChange[name] || []).forEach(name => {\n const target = this.renderRoot.querySelector(`[name='${name}']`)\n if (target) {\n ;(target as HTMLInputElement).value = ''\n }\n })\n\n this.requestUpdate()\n }\n\n const keepGoing = onchange ? await onchange.call(null, value ?? (target as HTMLInputElement).value, this) : true\n\n this.value = await this.getQueryFilters()\n\n keepGoing &&\n this.dispatchEvent(\n new CustomEvent('filters-change', {\n bubbles: true,\n composed: true,\n detail: {\n filters: this.value,\n from: 'filters-form'\n }\n })\n )\n })\n }\n\n buildDefaultValue(operator: FilterOperator, defaultValue: any) {\n if (defaultValue === undefined) {\n return\n }\n if (operator == 'between') {\n return (defaultValue as Array<any>).map(v => getDefaultValue(v, this))\n } else {\n return getDefaultValue(defaultValue, this)\n }\n }\n\n render(): TemplateResult {\n return html`\n <form\n @submit=${(e: Event) => {\n e.preventDefault()\n }}\n >\n ${this.filters.map((filter: FilterConfig) => {\n const { name, label, type, operator, value: defaultValue } = filter\n const idx = operator === 'between' ? 1 : 0\n const renderer = getFilterRenderer(\n operator === 'like' || operator === 'i_like' || operator === 'i_nlike' || operator === 'nlike'\n ? 'text'\n : type\n )[idx]\n\n const value =\n this.value?.find(filter => filter.name == name)?.value ?? this.buildDefaultValue(operator!, defaultValue)\n\n if (!renderer) {\n return nothing\n }\n\n return type === 'search'\n ? html`<ox-input-search name=\"search\" .value=${value} ?autofocus=${this.autofocus}></ox-input-search>`\n : type === 'boolean' || type === 'checkbox'\n ? renderer(filter, value, this)\n : type !== 'select'\n ? html`\n <label filter-title ?between=${operator == 'between'}\n ><span>${label}</span> ${renderer(filter, value, this)}\n </label>\n `\n : this.renderSelect(filter, value, renderer)\n })}\n </form>\n `\n }\n\n renderSelect(filter: FilterConfig, value: any, renderer: FilterSelectRenderer) {\n const { name, label, operator, value: defaultValue } = filter\n\n return operator === 'in'\n ? html`\n <ox-select\n name=${name}\n placeholder=${label}\n .value=${value ?? defaultValue}\n @change=${(e: CustomEvent) =>\n e.target?.dispatchEvent(\n new CustomEvent('filter-change', {\n detail: {\n name,\n operator,\n value: e.detail\n }\n })\n )}\n >\n <ox-popup-list multiple attr-selected=\"checked\" with-search>\n ${renderer(filter, value, this)}\n </ox-popup-list>\n </ox-select>\n `\n : html`\n <ox-select\n name=${name}\n placeholder=${label}\n .value=${value ?? defaultValue}\n @change=${(e: CustomEvent) =>\n e.target?.dispatchEvent(\n new CustomEvent('filter-change', {\n detail: {\n name,\n operator,\n value: e.detail\n }\n })\n )}\n >\n <ox-popup-list with-search> ${renderer(filter, value, this)} </ox-popup-list>\n </ox-select>\n `\n }\n\n getFieldByName(name: string) {\n return this.renderRoot.querySelector(`[name=${name}]`)\n }\n\n async updated(changes: PropertyValues<this>) {\n if (changes.has('urlParamsSensitive')) {\n if (this.urlParamsSensitive) {\n this._popstateEventHandler = () => {\n const queryString = window.location.search\n const urlParams = new URLSearchParams(queryString)\n var filters = urlParams.get('filters')\n\n if (filters) {\n try {\n this.value = json5.parse(filters)\n this.dispatchEvent(\n new CustomEvent('filters-change', {\n bubbles: true,\n composed: true,\n detail: {\n filters: json5.parse(filters),\n from: 'url-parameter'\n }\n })\n )\n } catch (e) {\n console.error(`invalid filters params on URL query string : ${e}`)\n }\n }\n }\n\n //@ts-ignore\n this._popstateEventHandler() // call for the first time\n\n window.addEventListener('popstate', this._popstateEventHandler)\n\n this._filtersChangeHandler = (e: Event) => {\n const urlParams = new URLSearchParams(window.location.search)\n const { filters, from } = (e as CustomEvent).detail || {}\n\n if (from === 'url-parameter') {\n return\n }\n\n if (filters.length > 0) {\n urlParams.set('filters', json5.stringify(filters))\n } else {\n urlParams.delete('filters')\n }\n const queryString = String(urlParams)\n const url = `${window.location.pathname}${queryString ? `?${queryString}` : ''}`\n\n history.pushState({}, document.title, url)\n }\n\n this.addEventListener('filters-change', this._filtersChangeHandler)\n } else {\n if (this._popstateEventHandler) {\n window.removeEventListener('popstate', this._popstateEventHandler)\n }\n if (this._filtersChangeHandler) {\n this.removeEventListener('popstate', this._filtersChangeHandler)\n }\n }\n }\n\n if (changes.has('filters')) {\n this.autoUpdateTargetsOnChange = {}\n this.filters\n ?.filter(filter => filter.boundTo && filter.boundTo.length > 0)\n .map(({ name, boundTo }) => {\n boundTo!.forEach(to => {\n const origin = this.autoUpdateTargetsOnChange[to] || []\n if (name && !origin.includes(name)) {\n this.autoUpdateTargetsOnChange[to] = [...origin, name]\n }\n })\n })\n\n if (!this.urlParamsSensitive) {\n this.value = await this.getQueryFilters()\n }\n }\n }\n\n async getQueryFilters(): Promise<FilterValue[]> {\n const formData = new FormData(await this.form)\n\n var filters = this.filters\n .map((filter: FilterConfig) => {\n const { name, type, operator } = filter\n\n var value = formData.getAll(name)\n if (value.length == 0) {\n return\n }\n\n if (-1 === value.findIndex(v => v !== '')) {\n return\n }\n\n const filterValue = value.map(v => {\n const value = v.toString()\n\n /* TODO registry에서 타입별로 parsing 방법을 지정할 수 있도록 해야한다. */\n switch (type) {\n case 'integer':\n case 'float':\n case 'number':\n case 'progress':\n case 'checkbox':\n case 'boolean':\n return !value ? undefined : JSON.parse(value)\n default:\n return value\n }\n })\n\n return {\n name,\n operator,\n value: filterValue.length === 1 ? filterValue[0] : filterValue\n }\n })\n .filter(result => result !== undefined) as FilterValue[]\n\n return filters\n }\n\n reset() {\n this.form\n .then((form: HTMLFormElement) => {\n form.reset()\n })\n .catch((error: any) => {\n console.error('Error resetting the form:', error)\n })\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ox-filters-form-base.js","sourceRoot":"","sources":["../../../src/filters/ox-filters-form-base.ts"],"names":[],"mappings":"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","sourcesContent":["import '@operato/input/ox-checkbox.js'\nimport '@operato/input/ox-select.js'\nimport '@operato/popup/ox-popup-list.js'\nimport '@operato/input/ox-input-search.js'\n\nimport json5 from 'json5'\nimport { css, html, LitElement, nothing, PropertyValues, TemplateResult } from 'lit'\nimport { customElement, property, queryAsync, state } from 'lit/decorators.js'\n\nimport { getDefaultValue } from '@operato/time-calculator'\nimport { PagePreferenceProvider } from '@operato/p13n'\n\nimport { FilterStyles } from './filter-styles.js'\nimport { getFilterRenderer } from './registry.js'\nimport { FilterConfig, FilterOperator, FilterSelectRenderer, FilterValue, PersonalFilterPreference } from '../types.js'\n\nexport type QueryFilterRangeValue = [from: number, to: number]\n\n@customElement('ox-filters-form-base')\nexport class OxFiltersFormBase extends LitElement {\n static styles = [\n FilterStyles,\n css`\n :host {\n display: flex;\n }\n\n form {\n flex: 1;\n\n display: flex;\n flex-flow: row wrap;\n gap: var(--ox-filters-form-gap);\n }\n\n form > * {\n display: flex;\n align-items: center;\n gap: var(--input-intra-gap, 7px);\n }\n\n label span {\n display: block;\n }\n\n @media only screen and (max-width: 460px) {\n form {\n flex-direction: column;\n flex-flow: column;\n }\n }\n `\n ]\n\n @property({ type: Array }) value: FilterValue[] = []\n @property({ type: Array }) filters: FilterConfig[] = []\n @property({ type: Boolean, attribute: 'url-params-sensitive' }) urlParamsSensitive?: boolean\n @property({ type: Boolean, attribute: 'autofocus' }) autofocus: boolean = true\n @property({ type: Object }) personalConfigProvider?: PagePreferenceProvider\n\n @state() personalConfig?: PersonalFilterPreference\n @state() personalFilters?: FilterConfig[]\n\n @queryAsync('form') form!: HTMLFormElement\n\n private _popstateEventHandler?: EventListener\n private _filtersChangeHandler?: EventListener\n private autoUpdateTargetsOnChange: { [name: string]: string[] } = {}\n\n connectedCallback(): void {\n super.connectedCallback()\n\n this.renderRoot.addEventListener('change', async (e: Event) => {\n const { target, detail: value } = e as CustomEvent\n const name = (target as HTMLInputElement).name\n const {\n label,\n type,\n operator,\n value: defaultValue,\n onchange\n } = (this.personalFilters || []).find(filter => filter.name == name) || {}\n\n if (this.autoUpdateTargetsOnChange[name]) {\n /* \n 일단은 심플하게, boundTo로 연결된 필터값이 바뀌면, 폼 전체를 update하도록 함.\n */\n ;(this.autoUpdateTargetsOnChange[name] || []).forEach(name => {\n const target = this.renderRoot.querySelector(`[name='${name}']`)\n if (target) {\n ;(target as HTMLInputElement).value = ''\n }\n })\n\n this.requestUpdate()\n }\n\n const keepGoing = onchange ? await onchange.call(null, value ?? (target as HTMLInputElement).value, this) : true\n\n this.value = await this.getQueryFilters()\n\n keepGoing &&\n this.dispatchEvent(\n new CustomEvent('filters-change', {\n bubbles: true,\n composed: true,\n detail: {\n filters: this.value,\n from: 'filters-form'\n }\n })\n )\n })\n }\n\n buildDefaultValue(operator: FilterOperator, defaultValue: any) {\n if (defaultValue === undefined) {\n return\n }\n if (operator == 'between') {\n return defaultValue instanceof Array && (defaultValue as Array<any>).map(v => getDefaultValue(v, this))\n } else {\n return getDefaultValue(defaultValue, this)\n }\n }\n\n render(): TemplateResult {\n return html`\n <form\n @submit=${(e: Event) => {\n e.preventDefault()\n }}\n >\n ${(this.personalFilters || [])\n .filter(filter => !filter.hidden)\n .map((filter: FilterConfig) => {\n const { name, label, type, operator, value: defaultValue } = filter\n const idx = operator === 'between' ? 1 : 0\n const renderer = getFilterRenderer(\n operator === 'like' || operator === 'i_like' || operator === 'i_nlike' || operator === 'nlike'\n ? 'text'\n : type\n )[idx]\n\n const value =\n this.value?.find(filter => filter.name == name)?.value ?? this.buildDefaultValue(operator!, defaultValue)\n\n if (!renderer) {\n return nothing\n }\n\n return type === 'search'\n ? html`<ox-input-search name=\"search\" .value=${value} ?autofocus=${this.autofocus}></ox-input-search>`\n : type === 'boolean' || type === 'checkbox'\n ? renderer(filter, value, this)\n : type !== 'select'\n ? html`\n <label filter-title ?between=${operator == 'between'}\n ><span>${label}</span> ${renderer(filter, value, this)}\n </label>\n `\n : this.renderSelect(filter, value, renderer)\n })}\n </form>\n\n <slot name=\"setting\"></slot>\n `\n }\n\n renderSelect(filter: FilterConfig, value: any, renderer: FilterSelectRenderer) {\n const { name, label, operator, value: defaultValue } = filter\n\n return operator === 'in'\n ? html`\n <ox-select\n name=${name}\n placeholder=${label}\n .value=${value ?? defaultValue}\n @change=${(e: CustomEvent) =>\n e.target?.dispatchEvent(\n new CustomEvent('filter-change', {\n detail: {\n name,\n operator,\n value: e.detail\n }\n })\n )}\n >\n <ox-popup-list multiple attr-selected=\"checked\" with-search>\n ${renderer(filter, value, this)}\n </ox-popup-list>\n </ox-select>\n `\n : html`\n <ox-select\n name=${name}\n placeholder=${label}\n .value=${value ?? defaultValue}\n @change=${(e: CustomEvent) =>\n e.target?.dispatchEvent(\n new CustomEvent('filter-change', {\n detail: {\n name,\n operator,\n value: e.detail\n }\n })\n )}\n >\n <ox-popup-list with-search> ${renderer(filter, value, this)} </ox-popup-list>\n </ox-select>\n `\n }\n\n async updated(changes: PropertyValues<this>) {\n if (changes.has('urlParamsSensitive')) {\n if (this.urlParamsSensitive) {\n this._popstateEventHandler = () => {\n const queryString = window.location.search\n const urlParams = new URLSearchParams(queryString)\n var filters = urlParams.get('filters')\n\n if (filters) {\n try {\n this.value = json5.parse(filters)\n this.dispatchEvent(\n new CustomEvent('filters-change', {\n bubbles: true,\n composed: true,\n detail: {\n filters: json5.parse(filters),\n from: 'url-parameter'\n }\n })\n )\n } catch (e) {\n console.error(`invalid filters params on URL query string : ${e}`)\n }\n }\n }\n\n //@ts-ignore\n this._popstateEventHandler() // call for the first time\n\n window.addEventListener('popstate', this._popstateEventHandler)\n\n this._filtersChangeHandler = (e: Event) => {\n const urlParams = new URLSearchParams(window.location.search)\n const { filters, from } = (e as CustomEvent).detail || {}\n\n if (from === 'url-parameter') {\n return\n }\n\n if (filters.length > 0) {\n urlParams.set('filters', json5.stringify(filters))\n } else {\n urlParams.delete('filters')\n }\n const queryString = String(urlParams)\n const url = `${window.location.pathname}${queryString ? `?${queryString}` : ''}`\n\n history.pushState({}, document.title, url)\n }\n\n this.addEventListener('filters-change', this._filtersChangeHandler)\n } else {\n if (this._popstateEventHandler) {\n window.removeEventListener('popstate', this._popstateEventHandler)\n }\n if (this._filtersChangeHandler) {\n this.removeEventListener('popstate', this._filtersChangeHandler)\n }\n }\n }\n\n if (changes.has('personalConfigProvider') && this.personalConfigProvider) {\n this.personalConfig = await this.personalConfigProvider.load()\n } else if (changes.has('filters') || changes.has('personalConfig')) {\n this.applyUpdatedConfiguration()\n }\n }\n\n async applyUpdatedConfiguration() {\n if (!this.personalConfig) {\n this.personalFilters = [...this.filters]\n } else {\n const { filters: personalFilters } = this.personalConfig\n\n if (personalFilters) {\n const xfilters = this.filters.map((filter: Partial<FilterConfig>) => {\n const personalFilter = personalFilters.find(pFilter => pFilter.name == filter.name)\n return personalFilter ? { ...filter, ...personalFilter } : filter\n })\n\n function reorderList(a: Partial<FilterConfig>[], b: Partial<FilterConfig>[]): Partial<FilterConfig>[] {\n // 결과 배열 초기화, a 배열 길이만큼 undefined로 채움\n const result = new Array(a.length)\n\n // b 배열에 없는 아이템은 원래 위치로 채움\n a.forEach((item, index) => {\n if (!item.name || !b.find(bi => bi.name == item.name)) {\n result[index] = item\n }\n })\n\n b.forEach(item => {\n const ai = a.find(ai => ai.name == item.name)\n if (ai) {\n result[result.findIndex(slot => slot === undefined)] = ai\n }\n })\n\n return result\n }\n\n // 배열 재정렬 실행\n this.personalFilters = reorderList(xfilters as any, personalFilters as any) as FilterConfig[]\n }\n }\n\n this.autoUpdateTargetsOnChange = {}\n\n this.personalFilters\n ?.filter(filter => filter.boundTo && filter.boundTo.length > 0)\n .map(({ name, boundTo }) => {\n boundTo!.forEach(to => {\n const origin = this.autoUpdateTargetsOnChange[to] || []\n if (name && !origin.includes(name)) {\n this.autoUpdateTargetsOnChange[to] = [...origin, name]\n }\n })\n })\n\n if (!this.urlParamsSensitive) {\n this.value = await this.getQueryFilters()\n }\n }\n\n getFieldByName(name: string) {\n return this.renderRoot.querySelector(`[name=${name}]`)\n }\n\n async getQueryFilters(): Promise<FilterValue[]> {\n const formData = new FormData(await this.form)\n\n var filters = (this.personalFilters || [])\n .map((filter: FilterConfig) => {\n const { name, type, operator } = filter\n\n var value = formData.getAll(name)\n if (value.length == 0) {\n return\n }\n\n if (-1 === value.findIndex(v => v !== '')) {\n return\n }\n\n const filterValue = value.map(v => {\n const value = v.toString()\n\n /* TODO registry에서 타입별로 parsing 방법을 지정할 수 있도록 해야한다. */\n switch (type) {\n case 'integer':\n case 'float':\n case 'number':\n case 'progress':\n case 'checkbox':\n case 'boolean':\n return !value ? undefined : JSON.parse(value)\n default:\n return value\n }\n })\n\n return {\n name,\n operator,\n value: filterValue.length === 1 ? filterValue[0] : filterValue\n }\n })\n .filter(result => result !== undefined) as FilterValue[]\n\n return filters\n }\n\n reset() {\n this.form\n .then((form: HTMLFormElement) => {\n form.reset()\n })\n .catch((error: any) => {\n console.error('Error resetting the form:', error)\n })\n }\n}\n"]}
|
package/dist/src/types.d.ts
CHANGED
|
@@ -29,6 +29,7 @@ export type FilterConfig = {
|
|
|
29
29
|
[params: string]: any;
|
|
30
30
|
}[] | undefined;
|
|
31
31
|
boundTo?: string[];
|
|
32
|
+
hidden?: boolean;
|
|
32
33
|
onchange?: FilterChangedCallback;
|
|
33
34
|
};
|
|
34
35
|
export type FilterValue = {
|
|
@@ -59,3 +60,6 @@ export type SearchFormField = {
|
|
|
59
60
|
};
|
|
60
61
|
onchange?: SearchFilterChangedCallback;
|
|
61
62
|
};
|
|
63
|
+
export type PersonalFilterPreference = {
|
|
64
|
+
filters?: Partial<FilterConfig>[];
|
|
65
|
+
};
|
package/dist/src/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"","sourcesContent":["import { TemplateResult } from 'lit-html'\nimport { OxFiltersFormBase } from './filters/ox-filters-form-base'\nimport { OxSearchForm } from './components/ox-search-form'\n\nexport type FilterOperator =\n | 'search'\n | 'eq'\n | 'between'\n | 'gte'\n | 'lte'\n | 'is_not_true'\n | 'in'\n | 'like'\n | 'i_like'\n | 'noteq'\n | 'is_empty_num_id'\n | 'is_blank'\n | 'is_present'\n | 'is_not_false'\n | 'is_true'\n | 'is_false'\n | 'is_not_null'\n | 'is_null'\n | 'notin_with_null'\n | 'notin'\n | 'gt'\n | 'lt'\n | 'i_nlike'\n | 'nlike'\n\nexport type SelectOptionObject =\n | {\n name: string\n display?: never\n value: string\n }\n | {\n display: string\n name?: never\n value: string\n }\n\nexport type SelectOption = SelectOptionObject | string\n\nexport type FilterChangedCallback = (value: any, form: OxFiltersFormBase) => boolean | Promise<boolean>\n\nexport type FilterConfig = {\n name: string\n label: string\n type: string\n operator?: FilterOperator\n options?:\n | { [key: string]: any }\n | SelectOption[]\n | ((form: OxFiltersFormBase) => SelectOption[] | Promise<SelectOption[]>)\n value?:\n | string\n | number\n | boolean\n | { name: string; [params: string]: any }\n | string[]\n | number[]\n | { name: string; [params: string]: any }[]\n | undefined\n boundTo?: string[]\n onchange?: FilterChangedCallback\n}\n\nexport type FilterValue = {\n name: string\n operator: FilterOperator\n value: string | number | boolean | string[] | number[] | undefined\n}\n\nexport type FilterSelectRenderer = (\n filter: FilterConfig,\n value: string | number | boolean | string[] | number[] | any | undefined,\n owner: Element\n) => TemplateResult | string | void\n\nexport type SearchFilterChangedCallback = (value: any, form: OxSearchForm) => boolean | Promise<boolean>\n\nexport type SearchFormField = {\n type: string\n hidden?: boolean\n name?: string\n id?: string\n label?: string\n placeholder?: string\n value?: any\n field?: string\n queryName?: string\n props?: { [prop: string]: string }\n attrs?: string[]\n options?: SelectOption[] | ((form: OxSearchForm) => SelectOption[] | Promise<SelectOption[]>)\n boundTo?: string[]\n handlers?: { [event: string]: EventListener }\n onchange?: SearchFilterChangedCallback\n}\n"]}
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"","sourcesContent":["import { TemplateResult } from 'lit-html'\nimport { OxFiltersFormBase } from './filters/ox-filters-form-base'\nimport { OxSearchForm } from './components/ox-search-form'\n\nexport type FilterOperator =\n | 'search'\n | 'eq'\n | 'between'\n | 'gte'\n | 'lte'\n | 'is_not_true'\n | 'in'\n | 'like'\n | 'i_like'\n | 'noteq'\n | 'is_empty_num_id'\n | 'is_blank'\n | 'is_present'\n | 'is_not_false'\n | 'is_true'\n | 'is_false'\n | 'is_not_null'\n | 'is_null'\n | 'notin_with_null'\n | 'notin'\n | 'gt'\n | 'lt'\n | 'i_nlike'\n | 'nlike'\n\nexport type SelectOptionObject =\n | {\n name: string\n display?: never\n value: string\n }\n | {\n display: string\n name?: never\n value: string\n }\n\nexport type SelectOption = SelectOptionObject | string\n\nexport type FilterChangedCallback = (value: any, form: OxFiltersFormBase) => boolean | Promise<boolean>\n\nexport type FilterConfig = {\n name: string\n label: string\n type: string\n operator?: FilterOperator\n options?:\n | { [key: string]: any }\n | SelectOption[]\n | ((form: OxFiltersFormBase) => SelectOption[] | Promise<SelectOption[]>)\n value?:\n | string\n | number\n | boolean\n | { name: string; [params: string]: any }\n | string[]\n | number[]\n | { name: string; [params: string]: any }[]\n | undefined\n boundTo?: string[]\n hidden?: boolean\n onchange?: FilterChangedCallback\n}\n\nexport type FilterValue = {\n name: string\n operator: FilterOperator\n value: string | number | boolean | string[] | number[] | undefined\n}\n\nexport type FilterSelectRenderer = (\n filter: FilterConfig,\n value: string | number | boolean | string[] | number[] | any | undefined,\n owner: Element\n) => TemplateResult | string | void\n\nexport type SearchFilterChangedCallback = (value: any, form: OxSearchForm) => boolean | Promise<boolean>\n\nexport type SearchFormField = {\n type: string\n hidden?: boolean\n name?: string\n id?: string\n label?: string\n placeholder?: string\n value?: any\n field?: string\n queryName?: string\n props?: { [prop: string]: string }\n attrs?: string[]\n options?: SelectOption[] | ((form: OxSearchForm) => SelectOption[] | Promise<SelectOption[]>)\n boundTo?: string[]\n handlers?: { [event: string]: EventListener }\n onchange?: SearchFilterChangedCallback\n}\n\nexport type PersonalFilterPreference = {\n filters?: Partial<FilterConfig>[]\n}\n"]}
|