@operato/data-grist 1.11.6 → 1.11.7
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 +10 -0
- package/demo/data-grist-test.html +2 -1
- package/dist/src/configure/column-builder.js +8 -0
- package/dist/src/configure/column-builder.js.map +1 -1
- package/dist/src/data-grid/data-grid-accum-field.js +2 -15
- package/dist/src/data-grid/data-grid-accum-field.js.map +1 -1
- package/dist/src/data-grid/data-grid-header.d.ts +8 -5
- package/dist/src/data-grid/data-grid-header.js +131 -47
- package/dist/src/data-grid/data-grid-header.js.map +1 -1
- package/dist/src/renderers/ox-grist-renderer-tree.d.ts +8 -0
- package/dist/src/renderers/ox-grist-renderer-tree.js +134 -0
- package/dist/src/renderers/ox-grist-renderer-tree.js.map +1 -0
- package/dist/src/types.d.ts +2 -0
- package/dist/src/types.js.map +1 -1
- package/dist/stories/fixed-column.stories copy.d.ts +26 -0
- package/dist/stories/fixed-column.stories copy.js +448 -0
- package/dist/stories/fixed-column.stories copy.js.map +1 -0
- package/dist/stories/fixed-column.stories.js +2 -1
- package/dist/stories/fixed-column.stories.js.map +1 -1
- package/dist/stories/grist-modes.stories.js +2 -1
- package/dist/stories/grist-modes.stories.js.map +1 -1
- package/dist/stories/group-header.stories.d.ts +26 -0
- package/dist/stories/group-header.stories.js +473 -0
- package/dist/stories/group-header.stories.js.map +1 -0
- package/dist/stories/tree-column.stories.d.ts +26 -0
- package/dist/stories/tree-column.stories.js +310 -0
- package/dist/stories/tree-column.stories.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/src/configure/column-builder.ts +8 -0
- package/src/data-grid/data-grid-accum-field.ts +2 -15
- package/src/data-grid/data-grid-header.ts +148 -47
- package/src/types.ts +2 -0
- package/stories/fixed-column.stories.ts +2 -1
- package/stories/grist-modes.stories.ts +2 -1
- package/stories/group-header.stories.ts +505 -0
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { __decorate } from "tslib";
|
|
2
|
+
import { css, html } from 'lit';
|
|
3
|
+
import { customElement } from 'lit/decorators.js';
|
|
4
|
+
import { OxGristRenderer } from './ox-grist-renderer';
|
|
5
|
+
let OxGristRendererTree = class OxGristRendererTree extends OxGristRenderer {
|
|
6
|
+
get rendererTemplate() {
|
|
7
|
+
var { childrenProperty = 'children' } = this.column.record.options || {};
|
|
8
|
+
var { __parent__: parent, __children__: children, __collapsed__: collapsed = true } = this.record;
|
|
9
|
+
const expandable = childrenProperty in this.record;
|
|
10
|
+
return html `
|
|
11
|
+
${expandable
|
|
12
|
+
? html ` <span expander @click=${this.onClickExpander.bind(this)} ?collapsed=${collapsed}></span> `
|
|
13
|
+
: html ``}
|
|
14
|
+
<span checkbox></span>
|
|
15
|
+
<span label>${this.value}</span>
|
|
16
|
+
`;
|
|
17
|
+
}
|
|
18
|
+
updated(changes) {
|
|
19
|
+
var { __depth__ } = this.record;
|
|
20
|
+
this.style.setProperty('--tree-depth', String(__depth__));
|
|
21
|
+
}
|
|
22
|
+
onClickExpander(e) {
|
|
23
|
+
e.stopPropagation();
|
|
24
|
+
this.record.__collapsed__ = !this.record.__collapsed__;
|
|
25
|
+
this.requestUpdate();
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
OxGristRendererTree.styles = css `
|
|
29
|
+
:host {
|
|
30
|
+
position: relative;
|
|
31
|
+
|
|
32
|
+
display: flex;
|
|
33
|
+
align-items: center;
|
|
34
|
+
gap: 6px;
|
|
35
|
+
|
|
36
|
+
width: 100%;
|
|
37
|
+
padding-left: calc(var(--tree-depth, 0) * 18px);
|
|
38
|
+
|
|
39
|
+
cursor: pointer;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
span[expander] {
|
|
43
|
+
display: inline-block;
|
|
44
|
+
vertical-align: middle;
|
|
45
|
+
width: 12px;
|
|
46
|
+
height: 20px;
|
|
47
|
+
cursor: pointer;
|
|
48
|
+
position: relative;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
span[expander]::before {
|
|
52
|
+
position: absolute;
|
|
53
|
+
top: 50%;
|
|
54
|
+
left: 50%;
|
|
55
|
+
transform: translate(-50%, -25%);
|
|
56
|
+
content: ' ';
|
|
57
|
+
border: 5px solid transparent;
|
|
58
|
+
border-top: 5px solid var(--primary-color, #1890ff);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
span[expander][collapsed]::before {
|
|
62
|
+
transform: translate(-25%, -50%) rotate(-90deg);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
span[checkbox] {
|
|
66
|
+
display: inline-block;
|
|
67
|
+
vertical-align: middle;
|
|
68
|
+
width: 12px;
|
|
69
|
+
height: 20px;
|
|
70
|
+
cursor: pointer;
|
|
71
|
+
position: relative;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
span[checkbox]::before {
|
|
75
|
+
cursor: pointer;
|
|
76
|
+
position: absolute;
|
|
77
|
+
top: 50%;
|
|
78
|
+
left: 50%;
|
|
79
|
+
transform: translate(-50%, -50%);
|
|
80
|
+
content: ' ';
|
|
81
|
+
display: block;
|
|
82
|
+
width: 10px;
|
|
83
|
+
height: 10px;
|
|
84
|
+
border: 1px solid var(--primary-color, #1890ff);
|
|
85
|
+
border-radius: 2px;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
span[label][selected] {
|
|
89
|
+
background-color: var(--primary-color, #1890ff);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
li[checked='checked'] > div[self] > span[checkbox]::before {
|
|
93
|
+
background-color: var(--primary-color, #1890ff);
|
|
94
|
+
border-color: var(--primary-color, #1890ff);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
li[checked='checked'] > div[self] > span[checkbox]::after {
|
|
98
|
+
position: absolute;
|
|
99
|
+
content: ' ';
|
|
100
|
+
display: block;
|
|
101
|
+
top: 50%;
|
|
102
|
+
left: 50%;
|
|
103
|
+
width: 3px;
|
|
104
|
+
height: 7px;
|
|
105
|
+
border: 2px solid #fff;
|
|
106
|
+
border-top: none;
|
|
107
|
+
border-left: none;
|
|
108
|
+
-webkit-transform: translate(-50%, -50%) rotate(45deg);
|
|
109
|
+
-ms-transform: translate(-50%, -50%) rotate(45deg);
|
|
110
|
+
transform: translate(-50%, -50%) rotate(45deg);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
li[checked='half-checked'] > div[self] > span[checkbox]::before {
|
|
114
|
+
background-color: var(--primary-color, #1890ff);
|
|
115
|
+
border-color: var(--primary-color, #1890ff);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
li[checked='half-checked'] > div[self] > span[checkbox]::after {
|
|
119
|
+
position: absolute;
|
|
120
|
+
content: ' ';
|
|
121
|
+
display: block;
|
|
122
|
+
top: 50%;
|
|
123
|
+
left: 50%;
|
|
124
|
+
transform: translate(-50%, -50%);
|
|
125
|
+
width: 10px;
|
|
126
|
+
height: 2px;
|
|
127
|
+
background-color: #fff;
|
|
128
|
+
}
|
|
129
|
+
`;
|
|
130
|
+
OxGristRendererTree = __decorate([
|
|
131
|
+
customElement('ox-grist-tree-renderer')
|
|
132
|
+
], OxGristRendererTree);
|
|
133
|
+
export { OxGristRendererTree };
|
|
134
|
+
//# sourceMappingURL=ox-grist-renderer-tree.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ox-grist-renderer-tree.js","sourceRoot":"","sources":["../../../src/renderers/ox-grist-renderer-tree.ts"],"names":[],"mappings":";AAAA,OAAO,EAAkB,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAA;AAC/C,OAAO,EAAE,aAAa,EAAY,MAAM,mBAAmB,CAAA;AAE3D,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AAG9C,IAAM,mBAAmB,GAAzB,MAAM,mBAAoB,SAAQ,eAAe;IAwGtD,IAAI,gBAAgB;QAClB,IAAI,EAAE,gBAAgB,GAAG,UAAU,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAA;QACxE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,SAAS,GAAG,IAAI,EAAE,GAAG,IAAI,CAAC,MAAM,CAAA;QAEjG,MAAM,UAAU,GAAG,gBAAgB,IAAI,IAAI,CAAC,MAAM,CAAA;QAElD,OAAO,IAAI,CAAA;QACP,UAAU;YACV,CAAC,CAAC,IAAI,CAAA,0BAA0B,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,SAAS,WAAW;YAClG,CAAC,CAAC,IAAI,CAAA,EAAE;;oBAEI,IAAI,CAAC,KAAK;KACzB,CAAA;IACH,CAAC;IAED,OAAO,CAAC,OAA6B;QACnC,IAAI,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,MAAM,CAAA;QAE/B,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,cAAc,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC,CAAA;IAC3D,CAAC;IAED,eAAe,CAAC,CAAa;QAC3B,CAAC,CAAC,eAAe,EAAE,CAAA;QAEnB,IAAI,CAAC,MAAM,CAAC,aAAa,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAA;QAEtD,IAAI,CAAC,aAAa,EAAE,CAAA;IACtB,CAAC;;AAlIM,0BAAM,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqGlB,AArGY,CAqGZ;AAtGU,mBAAmB;IAD/B,aAAa,CAAC,wBAAwB,CAAC;GAC3B,mBAAmB,CA4L/B","sourcesContent":["import { PropertyValues, css, html } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\n\nimport { OxGristRenderer } from './ox-grist-renderer'\n\n@customElement('ox-grist-tree-renderer')\nexport class OxGristRendererTree extends OxGristRenderer {\n static styles = css`\n :host {\n position: relative;\n\n display: flex;\n align-items: center;\n gap: 6px;\n\n width: 100%;\n padding-left: calc(var(--tree-depth, 0) * 18px);\n\n cursor: pointer;\n }\n\n span[expander] {\n display: inline-block;\n vertical-align: middle;\n width: 12px;\n height: 20px;\n cursor: pointer;\n position: relative;\n }\n\n span[expander]::before {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -25%);\n content: ' ';\n border: 5px solid transparent;\n border-top: 5px solid var(--primary-color, #1890ff);\n }\n\n span[expander][collapsed]::before {\n transform: translate(-25%, -50%) rotate(-90deg);\n }\n\n span[checkbox] {\n display: inline-block;\n vertical-align: middle;\n width: 12px;\n height: 20px;\n cursor: pointer;\n position: relative;\n }\n\n span[checkbox]::before {\n cursor: pointer;\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n content: ' ';\n display: block;\n width: 10px;\n height: 10px;\n border: 1px solid var(--primary-color, #1890ff);\n border-radius: 2px;\n }\n\n span[label][selected] {\n background-color: var(--primary-color, #1890ff);\n }\n\n li[checked='checked'] > div[self] > span[checkbox]::before {\n background-color: var(--primary-color, #1890ff);\n border-color: var(--primary-color, #1890ff);\n }\n\n li[checked='checked'] > div[self] > span[checkbox]::after {\n position: absolute;\n content: ' ';\n display: block;\n top: 50%;\n left: 50%;\n width: 3px;\n height: 7px;\n border: 2px solid #fff;\n border-top: none;\n border-left: none;\n -webkit-transform: translate(-50%, -50%) rotate(45deg);\n -ms-transform: translate(-50%, -50%) rotate(45deg);\n transform: translate(-50%, -50%) rotate(45deg);\n }\n\n li[checked='half-checked'] > div[self] > span[checkbox]::before {\n background-color: var(--primary-color, #1890ff);\n border-color: var(--primary-color, #1890ff);\n }\n\n li[checked='half-checked'] > div[self] > span[checkbox]::after {\n position: absolute;\n content: ' ';\n display: block;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 10px;\n height: 2px;\n background-color: #fff;\n }\n `\n\n get rendererTemplate() {\n var { childrenProperty = 'children' } = this.column.record.options || {}\n var { __parent__: parent, __children__: children, __collapsed__: collapsed = true } = this.record\n\n const expandable = childrenProperty in this.record\n\n return html`\n ${expandable\n ? html` <span expander @click=${this.onClickExpander.bind(this)} ?collapsed=${collapsed}></span> `\n : html``}\n <span checkbox></span>\n <span label>${this.value}</span>\n `\n }\n\n updated(changes: PropertyValues<this>) {\n var { __depth__ } = this.record\n\n this.style.setProperty('--tree-depth', String(__depth__))\n }\n\n onClickExpander(e: MouseEvent) {\n e.stopPropagation()\n\n this.record.__collapsed__ = !this.record.__collapsed__\n\n this.requestUpdate()\n }\n\n // onClickItem(e: MouseEvent) {\n // e.stopPropagation()\n\n // const target = e.target as HTMLSpanElement\n // const itemElement = target!.closest('li') as HTMLLIElement\n\n // var item = (itemElement as any).item\n // var checked = itemElement.getAttribute('checked') || ''\n\n // this.walkTreeCheckedUpdate(item, checked == '' || checked == 'unchecked' ? 'checked' : 'unchecked')\n // this.updateCheckedAll(this.data!)\n\n // this.requestUpdate()\n // }\n\n // walkTreeCheckedUpdate(item: TreeItem, checked: string = '') {\n // const { __status__ } = item\n // const children = item[this.childrenProperty] as TreeItem[]\n\n // children?.forEach(child => this.walkTreeCheckedUpdate(child, checked))\n // item.__status__ = {\n // ...__status__,\n // checked\n // }\n // }\n\n // updateCheckedAll(item: TreeItem) {\n // const { __status__ } = item\n // const children = item[this.childrenProperty] as TreeItem[]\n\n // if (!children || children.length == 0) {\n // return\n // }\n\n // children.forEach(child => this.updateCheckedAll(child))\n\n // var checked: string = ''\n\n // children.forEach(child => {\n // const { __status__ = {} } = child\n\n // if (__status__.checked == 'half-checked') {\n // checked = 'half-checked'\n // } else if (__status__.checked == 'checked') {\n // checked = checked == 'checked' || checked == '' ? 'checked' : 'half-checked'\n // } else {\n // checked = checked == 'unchecked' || checked == '' ? 'unchecked' : 'half-checked'\n // }\n // })\n\n // item.__status__ = {\n // ...__status__,\n // checked\n // }\n // }\n}\n"]}
|
package/dist/src/types.d.ts
CHANGED
|
@@ -107,6 +107,8 @@ export type ColumnWidthCallback = (column: ColumnConfig) => string;
|
|
|
107
107
|
export type HeaderConfig = {
|
|
108
108
|
renderer: HeaderRenderer;
|
|
109
109
|
style?: string;
|
|
110
|
+
group?: string;
|
|
111
|
+
groupStyle?: string;
|
|
110
112
|
};
|
|
111
113
|
export type HeaderRenderer = (column: ColumnConfig) => any;
|
|
112
114
|
export type ValueGeneratorFn = (...args: any[]) => any;
|
package/dist/src/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAmFA,MAAM,CAAN,IAAY,kBAIX;AAJD,WAAY,kBAAkB;IAC5B,mCAAa,CAAA;IACb,yCAAmB,CAAA;IACnB,mCAAa,CAAA;AACf,CAAC,EAJW,kBAAkB,KAAlB,kBAAkB,QAI7B","sourcesContent":["import { TemplateResult } from 'lit-html'\n\nimport { DataCardField } from './data-card/data-card-field'\nimport { DataCardGutter } from './data-card/data-card-gutter'\nimport { RecordCard } from './data-card/record-card'\nimport { DataGridField } from './data-grid/data-grid-field'\nimport { DataListField } from './data-list/data-list-field'\nimport { DataListGutter } from './data-list/data-list-gutter'\nimport { RecordPartial } from './data-list/record-partial'\nimport { DataReportField } from './data-report/data-report-field'\nimport { OxGristEditor } from './editors'\nimport { QueryFilter } from './filters'\nimport { OxGristRenderer } from './renderers/ox-grist-renderer'\n\nexport type GristConfig = {\n columns: ColumnConfig[]\n rows: RowsConfig\n list: ListConfig\n pagination?: PaginationConfig\n sorters?: SortersConfig\n filters?: FiltersConfig\n}\n\nexport type SorterConfig = { name: string; desc?: boolean }\nexport type SortersConfig = SorterConfig[]\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 FilterConfigObject = {\n type: string\n operator?: FilterOperator\n options?: { [key: string]: any }\n value?: string | number | boolean | string[] | number[] | undefined\n label?: string\n}\nexport type FilterConfig = FilterConfigObject | FilterOperator | boolean\n\nexport type FilterValue = {\n name: string\n operator: FilterOperator\n value: string | number | boolean | string[] | number[] | undefined\n}\n\n/**\n * Configuration options for filters.\n */\nexport type FiltersConfig = {\n /**\n * Specifies whether to provide filtering functionality in the header.\n */\n header?: boolean\n}\n\nexport type PaginationConfig = {\n page?: number\n limit?: number\n pages?: number[]\n infinite?: boolean\n}\n\nexport enum InheritedValueType {\n None = 'None',\n Include = 'Include',\n Only = 'Only'\n}\n\nexport type FetchOption = {\n page?: number\n limit?: number\n sorters?: SortersConfig\n sortings?: SortersConfig\n filters?: QueryFilter[]\n inherited?: InheritedValueType\n options?: object\n}\nexport type FetchResult = {\n page?: number\n limit?: number\n total: number\n records: GristRecord[]\n} | void\nexport type FetchHandler = (param: FetchOption) => Promise<FetchResult>\n\nexport type GristEventHandler = (\n columns: ColumnConfig[],\n data?: GristData,\n column?: ColumnConfig,\n record?: GristRecord,\n rowIndex?: number,\n target?: any\n) => void\n\nexport type AccumulatorFunc =\n | 'sum'\n | 'avg'\n | 'count'\n | 'min'\n | 'max'\n | ((data: GristData, column: ColumnConfig) => string | number)\n\nexport type ColumnConfig = {\n type: string\n name: string\n gutterName?: string\n fixed?: boolean\n header: HeaderConfig\n record: RecordConfig\n handlers: GristEventHandlerSet\n label: LabelConfig\n hidden?: boolean\n sortable?: boolean\n resizable?: boolean\n width?: number | string | ColumnWidthCallback\n forList?: boolean\n validation?: ValidationCallback\n accumulator?: AccumulatorFunc\n filter?: FilterConfig\n imex?: ImexConfig | boolean\n multiple?: boolean\n rowCount?: boolean\n}\n\nexport type ValidationCallback = (after: any, before: any, record: GristRecord, column: ColumnConfig) => boolean\n\nexport type LabelConfig =\n | string\n | boolean\n | {\n renderer: LabelRenderer\n }\n\nexport type LabelRenderer = () => void\n\nexport type ColumnWidthCallback = (column: ColumnConfig) => string\n\nexport type HeaderConfig = {\n renderer: HeaderRenderer\n style?: string\n}\nexport type HeaderRenderer = (column: ColumnConfig) => any\n\nexport type ValueGeneratorFn = (...args: any[]) => any\nexport type DefaultValueFnConfig =\n | {\n /**\n * The name of the default value function to be used for the column.\n */\n name: string\n\n /**\n * The parameters to be passed to the default value function.\n */\n params?: any[]\n }\n | Function\n\nexport type RecordConfig = {\n renderer: FieldRenderer\n editor?: FieldEditor\n editable?: boolean | Function\n mandatory?: boolean\n classifier: GristClassifier\n align?: 'left' | 'right' | 'center'\n options: any\n rowOptionField?: string\n defaultValue?: DefaultValueFnConfig\n [extended: string]: any\n}\n\nexport type FieldRenderer = (\n value: any,\n column: ColumnConfig,\n record: GristRecord,\n rowIndex: number,\n owner:\n | DataGridField\n | RecordCard\n | DataCardGutter\n | DataCardField\n | DataListGutter\n | DataListField\n | RecordPartial\n | DataReportField\n | Element\n) => OxGristRenderer | TemplateResult | string | void\nexport type FieldEditor = (\n value: any,\n column: ColumnConfig,\n record: GristRecord,\n rowIndex: number,\n field: DataGridField\n) => OxGristEditor\n\nexport type FilterSelectRenderer = (\n column: ColumnConfig,\n value: string | number | boolean | string[] | number[] | any | undefined,\n owner: Element\n) => TemplateResult | string | void\n\nexport type GristEventHandlerSet = {\n click?: GristEventHandler\n dblclick?: GristEventHandler\n focus?: GristEventHandler\n}\n\nexport type ListConfig = {\n thumbnail?: string\n fields: string[]\n details: string[]\n}\n\nexport type ImexConfig = {\n header: string\n key: string\n width: number\n type: string\n}\n\nexport type RowsConfig = {\n accumulator?: boolean\n appendable: boolean\n insertable: boolean\n selectable?: RowSelectableConfig\n groups: GroupConfig[]\n totals: string[]\n classifier: GristClassifier\n handlers: GristEventHandlerSet\n}\n\nexport type GristClassifier = (\n record: GristRecord,\n rowIndex: number\n) => { emphasized?: boolean | string | string[]; [key: string]: any } | void\n\nexport type GroupConfig = {\n align: string\n titleColumn?: ColumnConfig\n title: string\n value?: string\n groupName?: string\n row?: number\n column: string | number\n rowspan: number\n colspan?: number\n}\n\nexport type RowSelectableConfig = {\n multiple?: boolean\n}\n\nexport type GristRecord = {\n id?: string\n name?: string\n __seq__?: number\n __dirty__?: string\n __selected__?: boolean\n __changes__?: object[]\n __dirtyfields__?: { [key: string]: any }\n __origin__?: any\n [key: string]: any\n}\n\nexport type GristData = {\n page?: number\n total?: number\n limit?: number\n records: GristRecord[]\n}\n\nexport type GristSelectFunction = (record: GristRecord) => boolean\n"]}
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAmFA,MAAM,CAAN,IAAY,kBAIX;AAJD,WAAY,kBAAkB;IAC5B,mCAAa,CAAA;IACb,yCAAmB,CAAA;IACnB,mCAAa,CAAA;AACf,CAAC,EAJW,kBAAkB,KAAlB,kBAAkB,QAI7B","sourcesContent":["import { TemplateResult } from 'lit-html'\n\nimport { DataCardField } from './data-card/data-card-field'\nimport { DataCardGutter } from './data-card/data-card-gutter'\nimport { RecordCard } from './data-card/record-card'\nimport { DataGridField } from './data-grid/data-grid-field'\nimport { DataListField } from './data-list/data-list-field'\nimport { DataListGutter } from './data-list/data-list-gutter'\nimport { RecordPartial } from './data-list/record-partial'\nimport { DataReportField } from './data-report/data-report-field'\nimport { OxGristEditor } from './editors'\nimport { QueryFilter } from './filters'\nimport { OxGristRenderer } from './renderers/ox-grist-renderer'\n\nexport type GristConfig = {\n columns: ColumnConfig[]\n rows: RowsConfig\n list: ListConfig\n pagination?: PaginationConfig\n sorters?: SortersConfig\n filters?: FiltersConfig\n}\n\nexport type SorterConfig = { name: string; desc?: boolean }\nexport type SortersConfig = SorterConfig[]\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 FilterConfigObject = {\n type: string\n operator?: FilterOperator\n options?: { [key: string]: any }\n value?: string | number | boolean | string[] | number[] | undefined\n label?: string\n}\nexport type FilterConfig = FilterConfigObject | FilterOperator | boolean\n\nexport type FilterValue = {\n name: string\n operator: FilterOperator\n value: string | number | boolean | string[] | number[] | undefined\n}\n\n/**\n * Configuration options for filters.\n */\nexport type FiltersConfig = {\n /**\n * Specifies whether to provide filtering functionality in the header.\n */\n header?: boolean\n}\n\nexport type PaginationConfig = {\n page?: number\n limit?: number\n pages?: number[]\n infinite?: boolean\n}\n\nexport enum InheritedValueType {\n None = 'None',\n Include = 'Include',\n Only = 'Only'\n}\n\nexport type FetchOption = {\n page?: number\n limit?: number\n sorters?: SortersConfig\n sortings?: SortersConfig\n filters?: QueryFilter[]\n inherited?: InheritedValueType\n options?: object\n}\nexport type FetchResult = {\n page?: number\n limit?: number\n total: number\n records: GristRecord[]\n} | void\nexport type FetchHandler = (param: FetchOption) => Promise<FetchResult>\n\nexport type GristEventHandler = (\n columns: ColumnConfig[],\n data?: GristData,\n column?: ColumnConfig,\n record?: GristRecord,\n rowIndex?: number,\n target?: any\n) => void\n\nexport type AccumulatorFunc =\n | 'sum'\n | 'avg'\n | 'count'\n | 'min'\n | 'max'\n | ((data: GristData, column: ColumnConfig) => string | number)\n\nexport type ColumnConfig = {\n type: string\n name: string\n gutterName?: string\n fixed?: boolean\n header: HeaderConfig\n record: RecordConfig\n handlers: GristEventHandlerSet\n label: LabelConfig\n hidden?: boolean\n sortable?: boolean\n resizable?: boolean\n width?: number | string | ColumnWidthCallback\n forList?: boolean\n validation?: ValidationCallback\n accumulator?: AccumulatorFunc\n filter?: FilterConfig\n imex?: ImexConfig | boolean\n multiple?: boolean\n rowCount?: boolean\n}\n\nexport type ValidationCallback = (after: any, before: any, record: GristRecord, column: ColumnConfig) => boolean\n\nexport type LabelConfig =\n | string\n | boolean\n | {\n renderer: LabelRenderer\n }\n\nexport type LabelRenderer = () => void\n\nexport type ColumnWidthCallback = (column: ColumnConfig) => string\n\nexport type HeaderConfig = {\n renderer: HeaderRenderer\n style?: string\n group?: string\n groupStyle?: string\n}\nexport type HeaderRenderer = (column: ColumnConfig) => any\n\nexport type ValueGeneratorFn = (...args: any[]) => any\nexport type DefaultValueFnConfig =\n | {\n /**\n * The name of the default value function to be used for the column.\n */\n name: string\n\n /**\n * The parameters to be passed to the default value function.\n */\n params?: any[]\n }\n | Function\n\nexport type RecordConfig = {\n renderer: FieldRenderer\n editor?: FieldEditor\n editable?: boolean | Function\n mandatory?: boolean\n classifier: GristClassifier\n align?: 'left' | 'right' | 'center'\n options: any\n rowOptionField?: string\n defaultValue?: DefaultValueFnConfig\n [extended: string]: any\n}\n\nexport type FieldRenderer = (\n value: any,\n column: ColumnConfig,\n record: GristRecord,\n rowIndex: number,\n owner:\n | DataGridField\n | RecordCard\n | DataCardGutter\n | DataCardField\n | DataListGutter\n | DataListField\n | RecordPartial\n | DataReportField\n | Element\n) => OxGristRenderer | TemplateResult | string | void\nexport type FieldEditor = (\n value: any,\n column: ColumnConfig,\n record: GristRecord,\n rowIndex: number,\n field: DataGridField\n) => OxGristEditor\n\nexport type FilterSelectRenderer = (\n column: ColumnConfig,\n value: string | number | boolean | string[] | number[] | any | undefined,\n owner: Element\n) => TemplateResult | string | void\n\nexport type GristEventHandlerSet = {\n click?: GristEventHandler\n dblclick?: GristEventHandler\n focus?: GristEventHandler\n}\n\nexport type ListConfig = {\n thumbnail?: string\n fields: string[]\n details: string[]\n}\n\nexport type ImexConfig = {\n header: string\n key: string\n width: number\n type: string\n}\n\nexport type RowsConfig = {\n accumulator?: boolean\n appendable: boolean\n insertable: boolean\n selectable?: RowSelectableConfig\n groups: GroupConfig[]\n totals: string[]\n classifier: GristClassifier\n handlers: GristEventHandlerSet\n}\n\nexport type GristClassifier = (\n record: GristRecord,\n rowIndex: number\n) => { emphasized?: boolean | string | string[]; [key: string]: any } | void\n\nexport type GroupConfig = {\n align: string\n titleColumn?: ColumnConfig\n title: string\n value?: string\n groupName?: string\n row?: number\n column: string | number\n rowspan: number\n colspan?: number\n}\n\nexport type RowSelectableConfig = {\n multiple?: boolean\n}\n\nexport type GristRecord = {\n id?: string\n name?: string\n __seq__?: number\n __dirty__?: string\n __selected__?: boolean\n __changes__?: object[]\n __dirtyfields__?: { [key: string]: any }\n __origin__?: any\n [key: string]: any\n}\n\nexport type GristData = {\n page?: number\n total?: number\n limit?: number\n records: GristRecord[]\n}\n\nexport type GristSelectFunction = (record: GristRecord) => boolean\n"]}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import '../src/index.js';
|
|
2
|
+
import '../src/filters/filters-form.js';
|
|
3
|
+
import '../src/sorters/sorters-control.js';
|
|
4
|
+
import '../src/record-view/record-creator.js';
|
|
5
|
+
import '@operato/popup/ox-popup-list.js';
|
|
6
|
+
import '@material/mwc-icon';
|
|
7
|
+
import { TemplateResult } from 'lit';
|
|
8
|
+
declare const _default: {
|
|
9
|
+
title: string;
|
|
10
|
+
component: string;
|
|
11
|
+
argTypes: {
|
|
12
|
+
config: {
|
|
13
|
+
control: string;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
export default _default;
|
|
18
|
+
interface Story<T> {
|
|
19
|
+
(args: T): TemplateResult;
|
|
20
|
+
args?: Partial<T>;
|
|
21
|
+
argTypes?: Record<string, unknown>;
|
|
22
|
+
}
|
|
23
|
+
interface ArgTypes {
|
|
24
|
+
config: object;
|
|
25
|
+
}
|
|
26
|
+
export declare const Regular: Story<ArgTypes>;
|
|
@@ -0,0 +1,448 @@
|
|
|
1
|
+
import '../src/index.js';
|
|
2
|
+
import '../src/filters/filters-form.js';
|
|
3
|
+
import '../src/sorters/sorters-control.js';
|
|
4
|
+
import '../src/record-view/record-creator.js';
|
|
5
|
+
import '@operato/popup/ox-popup-list.js';
|
|
6
|
+
import '@material/mwc-icon';
|
|
7
|
+
import { html } from 'lit';
|
|
8
|
+
const fetchHandler = async ({ page, limit }) => {
|
|
9
|
+
var total = 120993;
|
|
10
|
+
var start = (page - 1) * limit;
|
|
11
|
+
await new Promise(resolve => setTimeout(resolve, 500));
|
|
12
|
+
return {
|
|
13
|
+
total,
|
|
14
|
+
records: Array(limit * page > total ? total % limit : limit)
|
|
15
|
+
.fill('')
|
|
16
|
+
.map((item, idx) => {
|
|
17
|
+
return {
|
|
18
|
+
id: String(idx),
|
|
19
|
+
name: idx % 2 ? `shnam-${start + idx + 1}` : `heartyoh-${start + idx + 1}`,
|
|
20
|
+
description: idx % 2 ? `hatiolabmanager${start + idx + 1}1234567890` : `hatiosea manager-${start + idx + 1}`,
|
|
21
|
+
email: idx % 2 ? `shnam-${start + idx + 1}@gmail.com` : `heartyoh-${start + idx + 1}@gmail.com`,
|
|
22
|
+
active: Math.round(Math.random() * 2) % 2 ? true : false,
|
|
23
|
+
barcode: idx % 2 ? `1234567890${start + idx + 1}` : `0987654321${start + idx + 1}`,
|
|
24
|
+
company: idx % 2
|
|
25
|
+
? {
|
|
26
|
+
id: '2',
|
|
27
|
+
name: 'HatioLAB',
|
|
28
|
+
description: `경기도 성남시-${start + idx + 1}`
|
|
29
|
+
}
|
|
30
|
+
: {
|
|
31
|
+
id: '3',
|
|
32
|
+
name: 'HatioSEA',
|
|
33
|
+
description: `말레이시아 세티아알람-${start + idx + 1}`
|
|
34
|
+
},
|
|
35
|
+
thumbnail: idx % 4 === 0
|
|
36
|
+
? '' /* no source */
|
|
37
|
+
: idx % 4 === 1
|
|
38
|
+
? `http://www.hatiolab.com/assets/img/operato-biz3.png`
|
|
39
|
+
: idx % 4 === 2
|
|
40
|
+
? `http://www.hatiolab.com/assets/img/thingsboard-30.png`
|
|
41
|
+
: `http://www.hatiolab.com/wrong-url.png` /* wrong source */,
|
|
42
|
+
role: ['admin', 'worker', 'tester'][idx % 3],
|
|
43
|
+
color: idx % 2 ? `#87f018` : `#180f87`,
|
|
44
|
+
rate: Math.round(Math.random() * 100),
|
|
45
|
+
dynamicType: ['text', 'email', 'checkbox', 'color', 'progress', 'barcode'][idx % 5],
|
|
46
|
+
dynamicValue: ['abcdefghijkl', 'heartyoh@hatiolab.com', 'true', 'orange', '50', '1234567890'][idx % 5],
|
|
47
|
+
homepage: idx % 2 ? `http://hatiolab.com/${start + idx + 1}` : `http://deadpool.hatiolab.com/${start + idx + 1}`,
|
|
48
|
+
json5: {
|
|
49
|
+
abc: 'abc',
|
|
50
|
+
value: 123
|
|
51
|
+
},
|
|
52
|
+
createdAt: Date.now(),
|
|
53
|
+
updatedAt: Date.now()
|
|
54
|
+
};
|
|
55
|
+
})
|
|
56
|
+
};
|
|
57
|
+
};
|
|
58
|
+
const config = {
|
|
59
|
+
list: {
|
|
60
|
+
thumbnail: 'thumbnail',
|
|
61
|
+
fields: ['name', 'description'],
|
|
62
|
+
details: ['role', 'email']
|
|
63
|
+
},
|
|
64
|
+
columns: [
|
|
65
|
+
{
|
|
66
|
+
type: 'gutter',
|
|
67
|
+
gutterName: 'dirty',
|
|
68
|
+
fixed: true
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
type: 'gutter',
|
|
72
|
+
gutterName: 'sequence',
|
|
73
|
+
fixed: true
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
type: 'gutter',
|
|
77
|
+
gutterName: 'row-selector',
|
|
78
|
+
multiple: true,
|
|
79
|
+
fixed: true
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
type: 'gutter',
|
|
83
|
+
gutterName: 'button',
|
|
84
|
+
icon: 'edit',
|
|
85
|
+
title: 'edit',
|
|
86
|
+
handlers: {
|
|
87
|
+
click: function () {
|
|
88
|
+
console.log('clicked');
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
fixed: true
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
type: 'gutter',
|
|
95
|
+
gutterName: 'button',
|
|
96
|
+
icon: 'add',
|
|
97
|
+
title: 'add',
|
|
98
|
+
handlers: {
|
|
99
|
+
click: 'record-copy'
|
|
100
|
+
},
|
|
101
|
+
fixed: true
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
type: 'gutter',
|
|
105
|
+
gutterName: 'button',
|
|
106
|
+
icon: 'arrow_downward',
|
|
107
|
+
title: 'download',
|
|
108
|
+
handlers: {
|
|
109
|
+
click: 'move-down'
|
|
110
|
+
},
|
|
111
|
+
fixed: true
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
type: 'string',
|
|
115
|
+
name: 'id',
|
|
116
|
+
hidden: true
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
type: 'link',
|
|
120
|
+
name: 'name',
|
|
121
|
+
label: true,
|
|
122
|
+
header: 'name',
|
|
123
|
+
record: {
|
|
124
|
+
editable: true,
|
|
125
|
+
options: {
|
|
126
|
+
// href: 'http://hatiolab.com',
|
|
127
|
+
href: function (column, record, rowIndex) {
|
|
128
|
+
return record['homepage'];
|
|
129
|
+
},
|
|
130
|
+
target: '_blank'
|
|
131
|
+
}
|
|
132
|
+
},
|
|
133
|
+
filter: 'search',
|
|
134
|
+
sortable: true,
|
|
135
|
+
width: 120,
|
|
136
|
+
fixed: true
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
type: 'string',
|
|
140
|
+
name: 'description',
|
|
141
|
+
header: 'description',
|
|
142
|
+
filter: 'search',
|
|
143
|
+
record: {
|
|
144
|
+
editable: true,
|
|
145
|
+
align: 'left'
|
|
146
|
+
},
|
|
147
|
+
width: 200,
|
|
148
|
+
handlers: {
|
|
149
|
+
click: (columns, data, column, record, rowIndex, target) => {
|
|
150
|
+
alert(`${column.name} ${record[column.name]}, row : ${rowIndex}`);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
type: 'email',
|
|
156
|
+
name: 'email',
|
|
157
|
+
label: true,
|
|
158
|
+
header: 'email',
|
|
159
|
+
record: {
|
|
160
|
+
editable: true
|
|
161
|
+
},
|
|
162
|
+
filter: 'search',
|
|
163
|
+
sortable: true,
|
|
164
|
+
width: 130,
|
|
165
|
+
validation: function (after, before, record, column) {
|
|
166
|
+
if (after.indexOf('@') == -1) {
|
|
167
|
+
document.dispatchEvent(new CustomEvent('notify', {
|
|
168
|
+
detail: {
|
|
169
|
+
type: 'error',
|
|
170
|
+
message: `invalid value - ${after}`
|
|
171
|
+
}
|
|
172
|
+
}));
|
|
173
|
+
return false;
|
|
174
|
+
}
|
|
175
|
+
return true;
|
|
176
|
+
}
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
type: 'boolean',
|
|
180
|
+
name: 'active',
|
|
181
|
+
header: 'active',
|
|
182
|
+
record: {
|
|
183
|
+
editable: true
|
|
184
|
+
},
|
|
185
|
+
filter: true,
|
|
186
|
+
handlers: {
|
|
187
|
+
dblclick: () => {
|
|
188
|
+
const grist = document.querySelector('ox-grist');
|
|
189
|
+
console.log(grist.dirtyRecords);
|
|
190
|
+
}
|
|
191
|
+
},
|
|
192
|
+
sortable: true,
|
|
193
|
+
width: 60
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
type: 'string[]',
|
|
197
|
+
name: 'role',
|
|
198
|
+
label: true,
|
|
199
|
+
header: 'role',
|
|
200
|
+
record: {
|
|
201
|
+
options: ['', 'admin', 'worker', 'tester'],
|
|
202
|
+
editable: true
|
|
203
|
+
},
|
|
204
|
+
filter: true,
|
|
205
|
+
sortable: true,
|
|
206
|
+
width: 120
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
type: 'color',
|
|
210
|
+
name: 'color',
|
|
211
|
+
header: 'color',
|
|
212
|
+
record: {
|
|
213
|
+
editable: true
|
|
214
|
+
},
|
|
215
|
+
sortable: true,
|
|
216
|
+
width: 50
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
type: 'float',
|
|
220
|
+
name: 'rate',
|
|
221
|
+
header: 'rate',
|
|
222
|
+
record: {
|
|
223
|
+
align: 'right',
|
|
224
|
+
editable: true,
|
|
225
|
+
defaultValue: 10000.1
|
|
226
|
+
},
|
|
227
|
+
filter: 'between',
|
|
228
|
+
sortable: true,
|
|
229
|
+
width: 50
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
type: 'json5',
|
|
233
|
+
name: 'json5',
|
|
234
|
+
header: 'JSON5',
|
|
235
|
+
width: 200
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
type: 'image',
|
|
239
|
+
name: 'thumbnail',
|
|
240
|
+
header: 'thumbnail',
|
|
241
|
+
record: {
|
|
242
|
+
editable: true
|
|
243
|
+
},
|
|
244
|
+
width: 120
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
type: 'datetime',
|
|
248
|
+
name: 'updatedAt',
|
|
249
|
+
header: 'updated at',
|
|
250
|
+
record: {
|
|
251
|
+
editable: true,
|
|
252
|
+
defaultValue: {
|
|
253
|
+
name: 'now'
|
|
254
|
+
}
|
|
255
|
+
},
|
|
256
|
+
filter: 'between',
|
|
257
|
+
sortable: true,
|
|
258
|
+
width: 180
|
|
259
|
+
},
|
|
260
|
+
{
|
|
261
|
+
type: 'datetime',
|
|
262
|
+
name: 'createdAt',
|
|
263
|
+
header: 'created at',
|
|
264
|
+
record: {
|
|
265
|
+
editable: false
|
|
266
|
+
},
|
|
267
|
+
sortable: true,
|
|
268
|
+
width: 180
|
|
269
|
+
}
|
|
270
|
+
],
|
|
271
|
+
rows: {
|
|
272
|
+
selectable: {
|
|
273
|
+
multiple: true
|
|
274
|
+
},
|
|
275
|
+
handlers: {
|
|
276
|
+
focus: 'select-row-toggle'
|
|
277
|
+
},
|
|
278
|
+
classifier: function (record, rowIndex) {
|
|
279
|
+
const rate = record['rate'];
|
|
280
|
+
const emphasized = rate < 10 ? ['black', 'white'] : rate < 25 ? ['yellow', 'blue'] : rate < 40 ? ['cyan', 'red'] : undefined;
|
|
281
|
+
return {
|
|
282
|
+
emphasized
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
},
|
|
286
|
+
sorters: [
|
|
287
|
+
{
|
|
288
|
+
name: 'name',
|
|
289
|
+
desc: true
|
|
290
|
+
},
|
|
291
|
+
{
|
|
292
|
+
name: 'email'
|
|
293
|
+
}
|
|
294
|
+
],
|
|
295
|
+
pagination: {
|
|
296
|
+
pages: [20, 30, 50, 100, 200]
|
|
297
|
+
}
|
|
298
|
+
};
|
|
299
|
+
export default {
|
|
300
|
+
title: 'fixed column',
|
|
301
|
+
component: 'ox-grist',
|
|
302
|
+
argTypes: {
|
|
303
|
+
config: { control: 'object' }
|
|
304
|
+
}
|
|
305
|
+
};
|
|
306
|
+
const Template = ({ config }) => html ` <link
|
|
307
|
+
href="https://fonts.googleapis.com/css?family=Material+Icons&display=block"
|
|
308
|
+
rel="stylesheet"
|
|
309
|
+
/>
|
|
310
|
+
<link href="/themes/app-theme.css" rel="stylesheet" />
|
|
311
|
+
<link href="/themes/oops-theme.css" rel="stylesheet" />
|
|
312
|
+
<link href="/themes/grist-theme.css" rel="stylesheet" />
|
|
313
|
+
|
|
314
|
+
<style>
|
|
315
|
+
[slot='headroom'] {
|
|
316
|
+
display: flex;
|
|
317
|
+
flex-direction: row;
|
|
318
|
+
align-items: center;
|
|
319
|
+
padding: var(--padding-default) var(--padding-wide);
|
|
320
|
+
background-color: var(--theme-white-color);
|
|
321
|
+
box-shadow: var(--box-shadow);
|
|
322
|
+
|
|
323
|
+
--mdc-icon-size: 24px;
|
|
324
|
+
}
|
|
325
|
+
#sorters mwc-icon,
|
|
326
|
+
#modes mwc-icon {
|
|
327
|
+
--mdc-icon-size: 18px;
|
|
328
|
+
}
|
|
329
|
+
#sorters {
|
|
330
|
+
margin-left: auto;
|
|
331
|
+
margin-right: var(--margin-default);
|
|
332
|
+
padding-left: var(--padding-narrow);
|
|
333
|
+
border-bottom: var(--border-dark-color);
|
|
334
|
+
position: relative;
|
|
335
|
+
color: var(--secondary-color);
|
|
336
|
+
font-size: var(--fontsize-default);
|
|
337
|
+
user-select: none;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
#sorters > * {
|
|
341
|
+
padding: var(--padding-narrow);
|
|
342
|
+
vertical-align: middle;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
#modes > * {
|
|
346
|
+
padding: var(--padding-narrow);
|
|
347
|
+
opacity: 0.5;
|
|
348
|
+
color: var(--primary-text-color);
|
|
349
|
+
cursor: pointer;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
#modes > mwc-icon[active] {
|
|
353
|
+
border-radius: 9px;
|
|
354
|
+
background-color: rgba(var(--primary-color-rgb), 0.05);
|
|
355
|
+
opacity: 1;
|
|
356
|
+
color: var(--secondary-text-color);
|
|
357
|
+
cursor: default;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
#modes > mwc-icon:hover {
|
|
361
|
+
opacity: 1;
|
|
362
|
+
color: var(--secondary-text-color);
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
#add {
|
|
366
|
+
width: 50px;
|
|
367
|
+
text-align: right;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
#add button {
|
|
371
|
+
background-color: var(--primary-color);
|
|
372
|
+
border: 0;
|
|
373
|
+
border-radius: 50%;
|
|
374
|
+
padding: 5px;
|
|
375
|
+
width: 36px;
|
|
376
|
+
height: 36px;
|
|
377
|
+
cursor: pointer;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
#add button:hover {
|
|
381
|
+
background-color: var(--focus-background-color);
|
|
382
|
+
box-shadow: var(--box-shadow);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
#add button mwc-icon {
|
|
386
|
+
font-size: 2em;
|
|
387
|
+
color: var(--theme-white-color);
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
#filters {
|
|
391
|
+
display: flex;
|
|
392
|
+
justify-content: center;
|
|
393
|
+
align-items: center;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
#filters * {
|
|
397
|
+
margin-right: var(--margin-default);
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
@media only screen and (max-width: 460px) {
|
|
401
|
+
#filters {
|
|
402
|
+
flex-direction: column;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
#modes {
|
|
406
|
+
display: none;
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
</style>
|
|
410
|
+
|
|
411
|
+
<ox-grist
|
|
412
|
+
mode="GRID"
|
|
413
|
+
.config=${config}
|
|
414
|
+
.fetchHandler=${fetchHandler}
|
|
415
|
+
@filters-change=${(e) => console.log('filters', e.target.filters)}
|
|
416
|
+
>
|
|
417
|
+
<div slot="headroom">
|
|
418
|
+
<div id="filters">
|
|
419
|
+
<ox-filters-form autofocus></ox-filters-form>
|
|
420
|
+
</div>
|
|
421
|
+
|
|
422
|
+
<div id="sorters">
|
|
423
|
+
Sort
|
|
424
|
+
<mwc-icon
|
|
425
|
+
@click=${(e) => {
|
|
426
|
+
const target = e.currentTarget;
|
|
427
|
+
target.closest('#sorters').querySelector('#sorter-control').open({
|
|
428
|
+
right: 0,
|
|
429
|
+
top: target.offsetTop + target.offsetHeight
|
|
430
|
+
});
|
|
431
|
+
}}
|
|
432
|
+
>expand_more</mwc-icon
|
|
433
|
+
>
|
|
434
|
+
<ox-popup id="sorter-control">
|
|
435
|
+
<ox-sorters-control> </ox-sorters-control>
|
|
436
|
+
</ox-popup>
|
|
437
|
+
</div>
|
|
438
|
+
|
|
439
|
+
<ox-record-creator id="add" light-popup>
|
|
440
|
+
<button><mwc-icon>add</mwc-icon></button>
|
|
441
|
+
</ox-record-creator>
|
|
442
|
+
</div>
|
|
443
|
+
</ox-grist>`;
|
|
444
|
+
export const Regular = Template.bind({});
|
|
445
|
+
Regular.args = {
|
|
446
|
+
config
|
|
447
|
+
};
|
|
448
|
+
//# sourceMappingURL=fixed-column.stories%20copy.js.map
|