@itrocks/list 0.2.1 → 0.3.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/build.js +0 -1
- package/cjs/filter.d.ts +12 -2
- package/cjs/filter.js +28 -2
- package/cjs/list.d.ts +1 -1
- package/cjs/list.html +9 -3
- package/cjs/list.js +2 -2
- package/cjs/sort.d.ts +2 -0
- package/cjs/sort.js +10 -1
- package/filter-reset.svg +1 -0
- package/list.css +29 -7
- package/package.json +1 -1
package/build.js
CHANGED
|
@@ -9,7 +9,6 @@ import { xTargetCall } from '../xtarget/xtarget.js';
|
|
|
9
9
|
build('article[data-action="list"] > form > table.objects', table => {
|
|
10
10
|
const tableLink = new TableLink({
|
|
11
11
|
call: url => xTargetCall(url, 'main'),
|
|
12
|
-
href: 'action',
|
|
13
12
|
id: (element) => {
|
|
14
13
|
const input = element.closest('tr')?.querySelector(':scope > th.select > input[name=id]');
|
|
15
14
|
if (input)
|
package/cjs/filter.d.ts
CHANGED
|
@@ -1,9 +1,19 @@
|
|
|
1
1
|
import { Type } from '@itrocks/class-type';
|
|
2
2
|
import { Request } from '@itrocks/request-response';
|
|
3
3
|
import { Option } from '@itrocks/storage';
|
|
4
|
+
import { Columns } from './columns';
|
|
4
5
|
import { Parameter } from './parameter';
|
|
5
|
-
|
|
6
|
-
|
|
6
|
+
type Search = {
|
|
7
|
+
[property: string]: string;
|
|
8
|
+
};
|
|
9
|
+
export declare class Filter<T extends object> extends Parameter {
|
|
10
|
+
columns: Columns<T>;
|
|
11
|
+
search: Search;
|
|
12
|
+
constructor(columns: Columns<T>);
|
|
13
|
+
getParams(request: Request): void;
|
|
7
14
|
readOptions(options?: Option[]): Option[];
|
|
8
15
|
searchObject(type: Type): any;
|
|
16
|
+
serialize(): Search;
|
|
17
|
+
unserialize(data: Search): void;
|
|
9
18
|
}
|
|
19
|
+
export {};
|
package/cjs/filter.js
CHANGED
|
@@ -3,13 +3,39 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.Filter = void 0;
|
|
4
4
|
const parameter_1 = require("./parameter");
|
|
5
5
|
class Filter extends parameter_1.Parameter {
|
|
6
|
-
|
|
6
|
+
columns;
|
|
7
|
+
search = {};
|
|
8
|
+
constructor(columns) {
|
|
9
|
+
super();
|
|
10
|
+
this.columns = columns;
|
|
11
|
+
}
|
|
12
|
+
getParams(request) {
|
|
13
|
+
for (const property of this.columns.map(property => property.name)) {
|
|
14
|
+
this.search[property] = '';
|
|
15
|
+
}
|
|
16
|
+
for (const [property, search] of Object.entries(request.data.search ?? {})) {
|
|
17
|
+
if (!(property in this.search))
|
|
18
|
+
continue;
|
|
19
|
+
this.search[property] = search;
|
|
20
|
+
}
|
|
7
21
|
}
|
|
8
22
|
readOptions(options = new Array) {
|
|
9
23
|
return options;
|
|
10
24
|
}
|
|
11
25
|
searchObject(type) {
|
|
12
|
-
|
|
26
|
+
const search = {};
|
|
27
|
+
for (const [property, value] of Object.entries(this.search)) {
|
|
28
|
+
if (value === '')
|
|
29
|
+
continue;
|
|
30
|
+
search[property] = value;
|
|
31
|
+
}
|
|
32
|
+
return Object.setPrototypeOf(search, type.prototype);
|
|
33
|
+
}
|
|
34
|
+
serialize() {
|
|
35
|
+
return this.search;
|
|
36
|
+
}
|
|
37
|
+
unserialize(data) {
|
|
38
|
+
this.search = data;
|
|
13
39
|
}
|
|
14
40
|
}
|
|
15
41
|
exports.Filter = Filter;
|
package/cjs/list.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ import { Sort } from './sort';
|
|
|
7
7
|
export declare class List<T extends object = object> extends Action<T> {
|
|
8
8
|
columns: Columns<object>;
|
|
9
9
|
feed: Feed;
|
|
10
|
-
filter: Filter
|
|
10
|
+
filter: Filter<object>;
|
|
11
11
|
sort: Sort<object>;
|
|
12
12
|
html(request: Request<T>): Promise<import("@itrocks/core-responses").HtmlResponse>;
|
|
13
13
|
json(request: Request<T>): Promise<import("@itrocks/core-responses").JsonResponse>;
|
package/cjs/list.html
CHANGED
|
@@ -24,15 +24,21 @@
|
|
|
24
24
|
<!--end-->
|
|
25
25
|
</ul>
|
|
26
26
|
</header>
|
|
27
|
-
<form action="app://(type.@route)" autocomplete="off" method="post" target="main">
|
|
28
|
-
<table class="objects">
|
|
29
|
-
|
|
27
|
+
<form action="app://(type.@route)/list" autocomplete="off" method="post" target="main">
|
|
28
|
+
<table class="objects" data-link="{type.@route}">
|
|
29
|
+
<thead>
|
|
30
30
|
<tr class="properties">
|
|
31
31
|
<th class="select"><input name="select" type="checkbox" value="all"></th>
|
|
32
32
|
<!--columns-->
|
|
33
33
|
<th data-property="{name}" data-reverse="{?reverse}" data-sort="{?sort}">{@display}</th>
|
|
34
34
|
<!--end-->
|
|
35
35
|
</tr>
|
|
36
|
+
<tr class="search">
|
|
37
|
+
<th><input name="reset" title="reset search filters" type="submit" value="reset"></th>
|
|
38
|
+
<!--columns-->
|
|
39
|
+
<th><input name="search.{name.toField}" value="{?.search.{name.toField}}"></th>
|
|
40
|
+
<!--end-->
|
|
41
|
+
</tr>
|
|
36
42
|
</thead>
|
|
37
43
|
<tbody>
|
|
38
44
|
{./feed.html}
|
package/cjs/list.js
CHANGED
|
@@ -64,7 +64,7 @@ let List = (() => {
|
|
|
64
64
|
}
|
|
65
65
|
columns = new columns_1.Columns;
|
|
66
66
|
feed = new feed_1.Feed;
|
|
67
|
-
filter = new filter_1.Filter;
|
|
67
|
+
filter = new filter_1.Filter(this.columns);
|
|
68
68
|
sort = new sort_1.Sort(this.columns);
|
|
69
69
|
async html(request) {
|
|
70
70
|
const columns = this.columns;
|
|
@@ -90,7 +90,7 @@ let List = (() => {
|
|
|
90
90
|
const actions = (action.need === 'object') ? selectionActions : generalActions;
|
|
91
91
|
actions.push(action);
|
|
92
92
|
}
|
|
93
|
-
return this.htmlTemplateResponse({ columns, count, generalActions, objects, selectionActions, type }, request, __dirname + '/list.html');
|
|
93
|
+
return this.htmlTemplateResponse({ columns, count, generalActions, objects, search: filter.search, selectionActions, type }, request, __dirname + '/list.html');
|
|
94
94
|
}
|
|
95
95
|
async json(request) {
|
|
96
96
|
const objects = await (0, storage_1.dataSource)().search(request.type);
|
package/cjs/sort.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Type } from '@itrocks/class-type';
|
|
2
2
|
import { Request } from '@itrocks/request-response';
|
|
3
3
|
import { Option } from '@itrocks/storage';
|
|
4
|
+
import { Sort as SortOption } from '@itrocks/storage';
|
|
4
5
|
import { Columns } from './columns';
|
|
5
6
|
import { Parameter } from './parameter';
|
|
6
7
|
interface Serialized {
|
|
@@ -17,6 +18,7 @@ export declare class Sort<T extends object> extends Parameter {
|
|
|
17
18
|
getParams(request: Request, type: Type<T>): void;
|
|
18
19
|
readOptions(options?: Option[]): Option[];
|
|
19
20
|
serialize(): Serialized | undefined;
|
|
21
|
+
sortOption(): SortOption | Type<SortOption>;
|
|
20
22
|
unserialize(data: Serialized): void;
|
|
21
23
|
}
|
|
22
24
|
export {};
|
package/cjs/sort.js
CHANGED
|
@@ -56,12 +56,21 @@ class Sort extends parameter_1.Parameter {
|
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
58
|
readOptions(options = new Array) {
|
|
59
|
-
options.push(
|
|
59
|
+
options.push(this.sortOption());
|
|
60
60
|
return options;
|
|
61
61
|
}
|
|
62
62
|
serialize() {
|
|
63
63
|
return this.sorted;
|
|
64
64
|
}
|
|
65
|
+
sortOption() {
|
|
66
|
+
if (!this.sorted)
|
|
67
|
+
return storage_1.Sort;
|
|
68
|
+
const properties = new Array;
|
|
69
|
+
for (const [propertyName, reverse] of Object.entries(this.sorted)) {
|
|
70
|
+
properties.push(reverse ? new sort_1.Reverse(propertyName) : propertyName);
|
|
71
|
+
}
|
|
72
|
+
return new storage_1.Sort(properties);
|
|
73
|
+
}
|
|
65
74
|
unserialize(data) {
|
|
66
75
|
this.sorted = data;
|
|
67
76
|
}
|
package/filter-reset.svg
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg stroke="#666" stroke-linecap="round" stroke-width="2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><circle cx="11" cy="11" fill="none" r="7"/><path d="M20 20l-3.5-3.5" /><path d="M8.5 8.5l5 5M13.5 8.5l-5 5"/></svg>
|
package/list.css
CHANGED
|
@@ -56,13 +56,13 @@ table.objects > tbody:first-child > tr:nth-child(even) > td {
|
|
|
56
56
|
table.objects > tbody:first-child > tr:nth-child(odd) > td {
|
|
57
57
|
background: #f8f8f8;
|
|
58
58
|
}
|
|
59
|
-
table.objects > thead > tr > th[data-property] {
|
|
59
|
+
table.objects > thead > tr.properties > th[data-property] {
|
|
60
60
|
cursor: pointer;
|
|
61
61
|
}
|
|
62
|
-
table.objects > thead > tr > th[data-sort] {
|
|
62
|
+
table.objects > thead > tr.properties > th[data-sort] {
|
|
63
63
|
padding-right: calc(0.6em + 16px);
|
|
64
64
|
}
|
|
65
|
-
table.objects > thead > tr > th[data-sort]::after {
|
|
65
|
+
table.objects > thead > tr.properties > th[data-sort]::after {
|
|
66
66
|
content: "";
|
|
67
67
|
height: 24px;
|
|
68
68
|
mask: url("sort.svg") right center/24px 24px no-repeat;
|
|
@@ -71,18 +71,40 @@ table.objects > thead > tr > th[data-sort]::after {
|
|
|
71
71
|
top: calc(50% - 12px);
|
|
72
72
|
width: 24px;
|
|
73
73
|
}
|
|
74
|
-
table.objects > thead > tr > th[data-sort][data-reverse]::after {
|
|
74
|
+
table.objects > thead > tr.properties > th[data-sort][data-reverse]::after {
|
|
75
75
|
transform: scaleY(-1);
|
|
76
76
|
}
|
|
77
|
-
table.objects > thead > tr > th[data-sort][data-sort="1"]::after {
|
|
77
|
+
table.objects > thead > tr.properties > th[data-sort][data-sort="1"]::after {
|
|
78
78
|
background-color: #444;
|
|
79
79
|
}
|
|
80
|
-
table.objects > thead > tr > th[data-sort][data-sort="2"]::after {
|
|
80
|
+
table.objects > thead > tr.properties > th[data-sort][data-sort="2"]::after {
|
|
81
81
|
background-color: #888;
|
|
82
82
|
}
|
|
83
|
-
table.objects > thead > tr > th[data-sort][data-sort="3"]::after {
|
|
83
|
+
table.objects > thead > tr.properties > th[data-sort][data-sort="3"]::after {
|
|
84
84
|
background-color: #ccc;
|
|
85
85
|
}
|
|
86
|
+
table.objects > thead > tr.search > th {
|
|
87
|
+
padding: 0;
|
|
88
|
+
}
|
|
89
|
+
table.objects > thead > tr.search > th > input {
|
|
90
|
+
border: none;
|
|
91
|
+
border-radius: 0;
|
|
92
|
+
width: 100%;
|
|
93
|
+
}
|
|
94
|
+
table.objects > thead > tr.search > th > input[type=submit] {
|
|
95
|
+
background: url("filter-reset.svg") center no-repeat;
|
|
96
|
+
color: transparent;
|
|
97
|
+
font-size: 0;
|
|
98
|
+
height: 26px;
|
|
99
|
+
min-width: 28px;
|
|
100
|
+
}
|
|
101
|
+
table.objects > thead > tr.search > th > input:not([type=submit]) {
|
|
102
|
+
border-left: 1px solid #d8d8d8;
|
|
103
|
+
}
|
|
104
|
+
table.objects > thead > tr.search > th > input:focus {
|
|
105
|
+
outline: none;
|
|
106
|
+
box-shadow: inset 0 0 0 2px Highlight;
|
|
107
|
+
}
|
|
86
108
|
table.objects > thead + tbody > tr:nth-child(even) > td {
|
|
87
109
|
background: #f8f8f8;
|
|
88
110
|
}
|
package/package.json
CHANGED