aio-entitykit 2.0.1 → 2.0.3

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.
Files changed (5) hide show
  1. package/d1.css +3 -77
  2. package/index.css +187 -36
  3. package/index.d.ts +95 -0
  4. package/index.js +355 -0
  5. package/package.json +1 -1
package/d1.css CHANGED
@@ -464,7 +464,7 @@
464
464
  }
465
465
 
466
466
  .d1 .ai-indent-line {
467
- stroke: var(--d1-border-light);
467
+ color: var(--d1-border-light);
468
468
  }
469
469
 
470
470
 
@@ -822,7 +822,7 @@
822
822
  height: 2.4em;
823
823
  cursor:pointer;
824
824
  }
825
- .ai-form-submit-button{
825
+ .d1 .ai-form-submit-button{
826
826
  background: var(--d1-active);
827
827
  color:#555;
828
828
  border: none;
@@ -832,83 +832,9 @@
832
832
  cursor:pointer;
833
833
  }
834
834
  .ai-form-wizard-step-button:disabled,.ai-form-wizard-submit-button:disabled{
835
- cursor:pointer;
835
+ cursor:not-allowed;
836
836
  opacity:0.5;
837
837
  }
838
- .d1 .entity-card{
839
- background: var(--d1-active);
840
- padding:0.5em;
841
- display:flex;
842
- flex-direction: column;
843
- gap:0.5em;
844
- border-radius:0.8em;
845
- color:#333;
846
- }
847
- .d1 .entity-card-header{
848
- display: flex;
849
- align-items: center;
850
- }
851
- .d1 .entity-card-toggle-icon{
852
- display: flex;
853
- align-items: center;
854
- justify-content: center;
855
- width:24px;
856
- height:30px;
857
- }
858
- .d1 .entity-card-title{
859
- cursor: pointer;
860
- flex:1;
861
- font-weight:bold;
862
- }
863
- .d1 .entity-row{
864
- display: flex;
865
- flex-direction: column;
866
- padding: 0.2em;
867
- justify-content: center;
868
- gap:0.4em;
869
- }
870
- .d1 .entity-row-header{
871
- display: flex;
872
- align-items: center;
873
- }
874
- .d1 .entity-table-deselect-all{
875
- height:30px;
876
- width: 30px;
877
- display:flex;
878
- align-items: center;
879
- justify-content: center;
880
- }
881
- .d1 .entity-table-selected-options{
882
- display: flex;
883
- align-items: center;
884
- justify-content: center;
885
- }
886
- .d1 .entity-table-today{
887
- font-size:0.7em;
888
- width:100%;
889
- display: flex;
890
- justify-content: center;
891
- }
892
- .d1 .entity-table .aio-table{
893
- flex:1;
894
- overflow: hidden;
895
- }
896
- .d1 .entity-table-toolbar{
897
- display: flex;
898
- align-items: center;
899
- gap:3em;
900
- font-size:0.8em;
901
- }
902
838
  .d1 .date-box{
903
- display:flex;
904
- align-items: center;
905
- justify-content: center;
906
- border-radius:1em;
907
- cursor:pointer;
908
- font-size:0.8em;
909
- width:48px;
910
- height:48px;
911
- text-align: center;
912
839
  border:1px solid var(--d1-border-medium);
913
- padding:0;
914
840
  }
package/index.css CHANGED
@@ -1,81 +1,232 @@
1
- .date-filter{
1
+ .date-filter {
2
2
  display: flex;
3
3
  flex-direction: column;
4
4
  gap: 0.5em;
5
5
  padding: 0 0.5em;
6
- padding-bottom:0.5em;
6
+ padding-bottom: 0.5em;
7
7
  }
8
- .date-filter-toolbar{
9
- display:flex;
8
+
9
+ .date-filter-toolbar {
10
+ display: flex;
10
11
  flex-direction: row;
11
12
  align-items: center;
12
13
  }
13
- .date-filter-toolbar-buttons{
14
- display:flex;
14
+
15
+ .date-filter-toolbar-buttons {
16
+ display: flex;
15
17
  flex-direction: row;
16
18
  gap: 0.5em;
17
19
  }
18
- .date-filter-input{
19
- display:flex;
20
+
21
+ .date-filter-input {
22
+ display: flex;
20
23
  align-items: center;
21
24
  justify-content: center;
22
25
  border-radius: 0.4em;
23
- cursor:pointer;
24
- font-size: 1em;
26
+ cursor: pointer;
25
27
  width: 48px;
26
28
  height: 48px;
27
29
  text-align: center;
28
- border:none;
30
+ border: none;
29
31
  }
30
- .date-filter-result{
31
- border:none;
32
+
33
+ .date-filter-result {
34
+ border: none;
32
35
  border-radius: 0.4em;
33
- padding:0 1em;
34
- height:2.4em;
35
- font-size:1em;
36
+ padding: 0 1em;
37
+ height: 2.4em;
36
38
  font-weight: bold;
37
- background:linear-gradient(180deg, #f7e5b3, #9a7e2f);
39
+ background: linear-gradient(180deg, #f7e5b3, #9a7e2f);
38
40
  }
39
- .time-range{
40
- display:flex;
41
+
42
+ .time-range {
43
+ display: flex;
41
44
  flex-direction: row;
42
45
  align-items: center;
43
46
  border-radius: 0;
44
47
  padding: 0;
45
48
  border: 1px solid #444;
46
49
  }
47
- .time-range-splitter{
50
+
51
+ .time-range-splitter {
48
52
  width: 1px;
49
53
  background-color: #444;
50
54
  height: 100%;
51
55
  }
52
- .time-range-input{
53
- border:none;
54
- font-size: 1em;
56
+
57
+ .time-range-input {
58
+ border: none;
55
59
  border-radius: 0;
56
60
  background: none;
57
61
  }
58
- .card-row{
62
+
63
+ .card-rows {
64
+ display: flex;
65
+ flex-direction: column;
66
+ gap: 1em;
67
+ }
68
+
69
+ .card-rows-placeholder {
70
+ font-size: 80%;
71
+ width: 100%;
72
+ display: flex;
73
+ align-items: center;
74
+ justify-content: center;
75
+ }
76
+
77
+ .card-row {
59
78
  display: flex;
60
79
  padding: 0.5em 0.75em;
61
80
  margin: 0.25em 0;
62
81
  border-radius: 0.4em;
63
82
  align-items: center;
64
- background:rgba(0,0,0,0.2);
83
+ background: rgba(0, 0, 0, 0.2);
84
+ }
85
+
86
+ .card-row-value {
87
+ font-weight: bold;
88
+ font-size: 80%;
89
+ display: flex;
90
+ align-items: center;
91
+ justify-content: center;
92
+ }
93
+
94
+ .card-row-label {
95
+ font-size: 80%;
65
96
  }
66
- .entity-row-title{
67
- flex:1;
68
- font-size:0.8em;
69
- font-weight:bold;
97
+
98
+ .entity-row {
99
+ display: flex;
100
+ flex-direction: column;
101
+ padding: 0.6em 0.2em !important;
102
+ justify-content: center;
103
+ gap: 0.4em;
70
104
  }
71
- .entity-table-selected{
72
- padding:0 1em;
73
- height:2.4em;
74
- display:flex;
105
+
106
+ .entity-row-header {
107
+ display: flex;
108
+ align-items: center;
109
+ }
110
+
111
+ .entity-card {
112
+ background: var(--d1-active);
113
+ padding: 0.5em;
114
+ display: flex;
115
+ flex-direction: column;
116
+ gap: 0.5em;
117
+ border-radius: 0.8em;
118
+ color: #333;
119
+ }
120
+
121
+ .entity-card-toggle-icon {
122
+ display: flex;
75
123
  align-items: center;
76
- color:orange;
124
+ justify-content: center;
125
+ width: 24px;
126
+ height: 30px;
77
127
  }
78
- .entity-card-title{
79
- display:flex;
128
+
129
+ .entity-card-header {
130
+ display: flex;
80
131
  align-items: center;
132
+ }
133
+ .entity-card-title {
134
+ cursor: pointer;
135
+ flex: 1;
136
+ padding: 0;
137
+ background: none;
138
+ }
139
+ .entity-table-deselect-all {
140
+ height: 30px;
141
+ width: 30px;
142
+ display: flex;
143
+ align-items: center;
144
+ justify-content: center;
145
+ }
146
+
147
+ .entity-table-selected-options {
148
+ display: flex;
149
+ align-items: center;
150
+ justify-content: center;
151
+ }
152
+
153
+ .entity-table-today {
154
+ width: 100%;
155
+ display: flex;
156
+ justify-content: center;
157
+ }
158
+
159
+ .entity-table .aio-table {
160
+ flex: 1;
161
+ overflow: hidden;
162
+ }
163
+
164
+ .entity-table-toolbar {
165
+ display: flex;
166
+ align-items: center;
167
+ gap: 3em;
168
+ }
169
+
170
+ .date-box {
171
+ display: flex;
172
+ align-items: center;
173
+ justify-content: center;
174
+ border-radius: 1em;
175
+ cursor: pointer;
176
+ width: 48px;
177
+ height: 48px;
178
+ text-align: center;
179
+ border: 1px solid var(--d1-border-medium);
180
+ padding: 0;
181
+ }
182
+
183
+ .entity-row-title {
184
+ flex: 1;
185
+ }
186
+
187
+ .entity-table-selected {
188
+ padding: 0 1em;
189
+ height: 2.4em;
190
+ display: flex;
191
+ align-items: center;
192
+ color: orange;
193
+ }
194
+
195
+ .entity-card-title {
196
+ display: flex;
197
+ align-items: center;
198
+ }
199
+
200
+ .entity-table-header {
201
+ display: flex;
202
+ }
203
+
204
+ .entity-table-side-button {
205
+ margin-inline-end: 1em;
206
+ padding: 1em;
207
+ border-radius: 100%;
208
+ }
209
+
210
+ .entity-table-align-vh {
211
+ display: flex;
212
+ align-items: center;
213
+ justify-content: center;
214
+ }
215
+
216
+ .card-box {
217
+ display: flex;
218
+ flex: 1;
219
+ flex-direction: column;
220
+ border-radius: 0.8em;
221
+ align-items: center;
222
+ font-size: 80%;
223
+ opacity: 0.9;
224
+ }
225
+
226
+ .card-box-value {
227
+ font-weight: bold;
228
+ }
229
+
230
+ .entity-table .aio-input-tree-option {
231
+ min-height: 2.4em !important;
81
232
  }
package/index.d.ts ADDED
@@ -0,0 +1,95 @@
1
+ import { type FC, type ReactNode } from "react";
2
+ import { type I_table } from 'aio-table';
3
+ import type { AIOCordova } from 'aio-cordova';
4
+ import { useEntity } from 'aio-entity';
5
+ import './index.css';
6
+ type I_option = {
7
+ text: string;
8
+ title?: string;
9
+ show?: boolean;
10
+ body?: () => ReactNode;
11
+ onClick?: () => void;
12
+ };
13
+ type I_EntityTable<T> = {
14
+ root?: boolean;
15
+ popup?: any;
16
+ cordova?: AIOCordova;
17
+ sideOptions?: {
18
+ text: string;
19
+ value: any;
20
+ onClick?: () => void;
21
+ before?: ReactNode;
22
+ }[];
23
+ header?: () => ReactNode;
24
+ footer?: () => ReactNode;
25
+ entity: ReturnType<typeof useEntity<T>>;
26
+ table: Partial<I_table<T>>;
27
+ attrs?: any;
28
+ moveTo?: (moveFrom: T, moveTo: T) => boolean;
29
+ getCardContent: (row: T, parent: T | false, type: 'root' | 'leaf' | 'node') => ReactNode;
30
+ getCardOptions?: (row: T, parent: T | false) => I_option[];
31
+ getSelectedOptions?: (selected: T[], parent?: T) => I_option[];
32
+ getRootOptions?: () => I_option[];
33
+ getCardTitle: (row: T) => ReactNode;
34
+ getCardOptionsType?: (row: T) => 'button' | 'onTitle';
35
+ getCardSubtitle?: (row: T) => ReactNode;
36
+ onSearch?: (searchValue: string) => void;
37
+ toggleIcon?: (row: T) => {
38
+ close?: ReactNode;
39
+ open?: ReactNode;
40
+ leaf?: ReactNode;
41
+ } | undefined;
42
+ archive?: boolean;
43
+ reOrder?: 'dir';
44
+ filteredData?: T[];
45
+ };
46
+ export declare const EntityTable: <T>(props: I_EntityTable<T>) => import("react/jsx-runtime").JSX.Element;
47
+ export declare const Card: <T>({ row }: {
48
+ row: T;
49
+ index: number;
50
+ }) => import("react/jsx-runtime").JSX.Element;
51
+ type I_DateFilter = {
52
+ result?: any;
53
+ fromDate?: number;
54
+ toDate?: number;
55
+ onChange: (p: {
56
+ fromDate?: number;
57
+ toDate?: number;
58
+ }) => void;
59
+ };
60
+ export declare const DateFilter: FC<I_DateFilter>;
61
+ export declare const TimeRange: FC<{
62
+ fromDate?: number;
63
+ toDate?: number;
64
+ onChange: (p: {
65
+ fromDate?: number;
66
+ toDate?: number;
67
+ }) => void;
68
+ }>;
69
+ export declare const CardRow: FC<{
70
+ label: string;
71
+ value: ReactNode;
72
+ color?: string;
73
+ onClick?: () => void;
74
+ }>;
75
+ export type I_CardRow = [label: string, value: ReactNode, config?: {
76
+ isPrice?: boolean;
77
+ onClick?: () => void;
78
+ }];
79
+ export declare const CardRows: FC<{
80
+ rows: I_CardRow[];
81
+ placeholder?: string;
82
+ }>;
83
+ export declare const CardBox: FC<{
84
+ label: string;
85
+ value: ReactNode;
86
+ color?: string;
87
+ onClick?: () => void;
88
+ type: number;
89
+ isPrice?: boolean;
90
+ }>;
91
+ export declare const Panel: FC<{
92
+ label?: ReactNode;
93
+ content: ReactNode;
94
+ }>;
95
+ export {};
package/index.js ADDED
@@ -0,0 +1,355 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
11
+ import { createContext, useContext, useEffect, useState } from "react";
12
+ import AIOInput, { AIDate, AISelect, AITime, AITree } from 'aio-input';
13
+ import AIOTable from 'aio-table';
14
+ import { AddToAttrs, classListToString, GetSvg, SplitNumber, useSide } from 'aio-utils';
15
+ import AIODate from 'aio-date';
16
+ import Icon from '@mdi/react';
17
+ import { mdiCheckboxMarked, mdiClose, mdiDownload, mdiListBox, mdiSelect, mdiUpload } from "@mdi/js";
18
+ import './index.css';
19
+ const Context = createContext({});
20
+ const Provider = ({ children, value }) => {
21
+ return _jsx(Context.Provider, { value: value, children: children });
22
+ };
23
+ const useProvider = () => useContext(Context);
24
+ export const EntityTable = (props) => {
25
+ const DATE = new AIODate();
26
+ const { table, moveTo, entity, popup, archive, filteredData, onSearch } = props;
27
+ const [showArchive, setShowArchive] = useState(false);
28
+ const { data } = entity;
29
+ const [selected, setSelected] = useState({});
30
+ const select = (row) => {
31
+ if (!props.getSelectedOptions) {
32
+ return;
33
+ }
34
+ const rowId = entity.id.get(row);
35
+ const keys = Object.keys(selected);
36
+ const firstSelected = keys.length ? selected[keys[0]] : undefined;
37
+ if (firstSelected) {
38
+ const firstSelectedParent = entity.getParentByRowId(entity.data, entity.id.get(firstSelected));
39
+ const firstSelectedParentId = firstSelectedParent ? entity.id.get(firstSelectedParent) : undefined;
40
+ const rowParent = entity.getParentByRowId(entity.data, entity.id.get(row));
41
+ const rowParentId = rowParent ? entity.id.get(rowParent) : undefined;
42
+ if (firstSelectedParentId !== rowParentId) {
43
+ setSelected({ [rowId]: row });
44
+ return;
45
+ }
46
+ }
47
+ if (selected[rowId]) {
48
+ setSelected((prev) => {
49
+ const newSelected = {};
50
+ for (let prop in prev) {
51
+ if (rowId.toString() !== prop.toString()) {
52
+ newSelected[prop] = prev[prop];
53
+ }
54
+ }
55
+ return newSelected;
56
+ });
57
+ }
58
+ else {
59
+ setSelected((prev) => (Object.assign(Object.assign({}, prev), { [rowId]: row })));
60
+ }
61
+ };
62
+ const canMoveTo = (row) => {
63
+ const rowId = entity.id.get(row);
64
+ if (selected[rowId.toString()]) {
65
+ return false;
66
+ }
67
+ if (!moveTo) {
68
+ return false;
69
+ }
70
+ const keys = Object.keys(selected);
71
+ if (!keys.length) {
72
+ return false;
73
+ }
74
+ return true;
75
+ };
76
+ const getOptionDetails = (options, deselect) => {
77
+ return options.map((o) => {
78
+ return {
79
+ text: o.text, show: o.show,
80
+ onClick: () => {
81
+ if (o.body) {
82
+ popup.addModal({ header: { title: o.title || o.text }, body: o.body() });
83
+ }
84
+ if (o.onClick) {
85
+ o.onClick();
86
+ }
87
+ if (deselect) {
88
+ setTimeout(() => setSelected({}), 0);
89
+ }
90
+ }
91
+ };
92
+ });
93
+ };
94
+ const getRootOptions = () => {
95
+ const options = props.getRootOptions ? props.getRootOptions() : [];
96
+ const res = [];
97
+ if (props.archive) {
98
+ res.push({
99
+ text: showArchive ? 'مخفی سازی آرشیو' : 'نمایش آرشیو', onClick: () => {
100
+ setShowArchive(!showArchive);
101
+ }
102
+ });
103
+ }
104
+ return [...options, ...res];
105
+ };
106
+ const getOptions = (row, parent) => {
107
+ const options = props.getCardOptions ? props.getCardOptions(row, parent) : [];
108
+ const res = getOptionDetails(options);
109
+ return [
110
+ ...res,
111
+ {
112
+ show: canMoveTo(row), text: 'انتقال به اینجا', onClick: () => __awaiter(void 0, void 0, void 0, function* () {
113
+ const keys = Object.keys(selected);
114
+ const toRow = row;
115
+ const toId = entity.id.get(toRow);
116
+ if (!moveTo || !keys.length) {
117
+ return;
118
+ }
119
+ const { parents } = entity.getRowAndParentsById(toId);
120
+ for (let i = 0; i < parents.length; i++) {
121
+ const id = entity.id.get(parents[i]).toString();
122
+ if (selected[id]) {
123
+ return;
124
+ }
125
+ }
126
+ const rows = keys.map((key) => selected[key]).filter((fromRow) => !!moveTo(fromRow, toRow));
127
+ const fromIds = rows.map((o) => entity.id.get(o));
128
+ yield entity.moveTo(fromIds, toId);
129
+ setSelected({});
130
+ })
131
+ },
132
+ { show: props.reOrder === 'dir', text: 'جابجایی به بالا', onClick: () => entity.changeOrderByDir(row, -1) },
133
+ { show: props.reOrder === 'dir', text: 'جابجایی به پایین', onClick: () => entity.changeOrderByDir(row, 1) },
134
+ { show: !!archive && !row.archive, text: 'انتقال به آرشیو', onClick: () => { if (!!archive) {
135
+ entity.edit(Object.assign(Object.assign({}, row), { archive: true }));
136
+ } } },
137
+ { show: !!archive && !!row.archive, text: 'خروج از آرشیو', onClick: () => { if (!!archive) {
138
+ entity.edit(Object.assign(Object.assign({}, row), { archive: false }));
139
+ } } },
140
+ { text: 'حذف', onClick: () => entity.remove(entity.id.get(row)) }
141
+ ];
142
+ };
143
+ const side = useSide({
144
+ options: props.sideOptions || [],
145
+ option: {
146
+ before: (o) => _jsx(Icon, { path: { reports: mdiListBox, export: mdiDownload, import: mdiUpload }[o.value], size: 1 })
147
+ },
148
+ onChange: () => {
149
+ side.close();
150
+ }
151
+ });
152
+ const rows = filteredData ? filteredData : data;
153
+ const attrs = AddToAttrs(props.attrs, { className: 'entity-table' });
154
+ return (_jsx(Provider, { value: { selected, setSelected, getRootOptions, rootProps: props, getOptions, entity, getOptionDetails, showArchive, setShowArchive, select }, children: _jsxs("div", Object.assign({}, attrs, { children: [_jsx("div", { className: "entity-table-today", style: { background: 'rgba(0,0,0,0.2)' }, children: DATE.getDateByPattern(DATE.getToday(true), 'امروز {weekDay} {day} {monthString} {year}') }), _jsxs("div", { className: "entity-table-header", children: [!!props.sideOptions && !!props.sideOptions.length &&
155
+ _jsx("div", { className: "entity-table-side-button", onClick: () => side.open(), children: _jsx(Icon, { path: mdiListBox, size: 1 }) }), !!props.header && props.header()] }), _jsx(Selected, {}), _jsx(AIOTable, Object.assign({}, table, { onSearch: onSearch, value: rows, headerAttrs: { style: { display: 'none' } }, rowTemplate: ({ row, rowIndex }) => _jsx(Card, { row: row, index: rowIndex }), toolbar: () => _jsx(TableToolbar, {}) })), _jsx("div", { style: { marginBottom: '1em' } }), !!props.footer && props.footer(), side.render()] })) }));
156
+ };
157
+ const Selected = () => {
158
+ const { selected, rootProps, getOptionDetails, entity, setSelected } = useProvider();
159
+ const keys = Object.keys(selected);
160
+ const [options, setOptions] = useState([]);
161
+ function getOptions() {
162
+ const { getSelectedOptions } = rootProps;
163
+ if (!getSelectedOptions || !keys.length) {
164
+ return [];
165
+ }
166
+ const parent = keys.length ? entity.getParentByRowId(entity.data, entity.id.get(selected[keys[0]])) : undefined;
167
+ const list = [];
168
+ for (let prop in selected) {
169
+ list.push(selected[prop]);
170
+ }
171
+ const options = getSelectedOptions(list, parent);
172
+ return getOptionDetails(options, true);
173
+ }
174
+ useEffect(() => { setOptions(getOptions); }, [selected]);
175
+ if (!options.length) {
176
+ return null;
177
+ }
178
+ return (_jsxs("div", { className: "entity-table-selected", children: [_jsx("div", { className: "entity-table-deselect-all", onClick: () => setSelected({}), children: _jsx(Icon, { path: mdiClose, size: 0.8 }) }), _jsx("div", { className: "msf", children: `${keys.length} مورد انتخاب شده` }), _jsx("div", { style: { flex: 1 } }), _jsx(AISelect, { rtl: true, options: options, text: new GetSvg().getIcon('mdiDotsHorizontal', .8), caret: false, justify: true, className: 'entity-table-selected-options', style: { background: 'orange', color: '#000', border: 'none', height: 30, width: 30, padding: 0, } })] }));
179
+ };
180
+ const TableToolbar = () => {
181
+ const { rootProps, getOptionDetails, getRootOptions } = useProvider();
182
+ const { table } = rootProps;
183
+ let node = null;
184
+ if (typeof table.toolbar === 'function') {
185
+ node = table.toolbar() || null;
186
+ }
187
+ else if (table.toolbar) {
188
+ node = table.toolbar || null;
189
+ }
190
+ const options = getRootOptions();
191
+ const res = getOptionDetails(options);
192
+ return (_jsxs("div", { className: "entity-table-toolbar", children: [!!res.length &&
193
+ _jsx(AISelect, { rtl: true, options: res, text: new GetSvg().getIcon('mdiDotsHorizontal', .8), caret: false, justify: true, className: 'd1-bg-cream entity-table-align-vh', style: { background: 'none', border: 'none', height: 30, width: 30, padding: 0, } }), node] }));
194
+ };
195
+ export const Card = ({ row }) => {
196
+ const { rootProps, entity, selected } = useProvider();
197
+ const rowId = entity.id.get(row);
198
+ const isSelected = selected[rowId];
199
+ const { getCardContent } = rootProps;
200
+ const [open, setOpen] = useState(false);
201
+ return (_jsxs("div", { className: "entity-card", children: [_jsx(CardHeader, { isRoot: true, row: row, before: _jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: '0.4em' }, children: [_jsx("div", { className: "entity-card-toggle-icon", onClick: (e) => { e.stopPropagation(); setOpen(!open); }, children: new GetSvg().getIcon(open ? 'mdiChevronDown' : 'mdiChevronLeft', .8) }), !!isSelected && _jsx(Icon, { path: mdiCheckboxMarked, size: 0.8, color: 'orange' })] }) }), getCardContent(row, false, 'root'), _jsx(CardTree, { row: row, open: open })] }));
202
+ };
203
+ const CardTree = ({ row, open }) => {
204
+ const { entity, showArchive, rootProps } = useProvider();
205
+ const childs = entity.childs.get(row);
206
+ if (!childs || !childs.length || !open) {
207
+ return null;
208
+ }
209
+ return (_jsx(AITree, { rtl: true, autoHeight: true, indent: 24, value: childs, option: {
210
+ childs: (o) => entity.childs.get(o),
211
+ text: (row, { parentOptions }) => _jsx(CardTreeRow, { row: row, parentOptions: parentOptions }),
212
+ value: (o) => entity.id.get(o),
213
+ show: (o) => showArchive ? true : !o.archive,
214
+ className: () => `${'d1-bg-dark-gray'}`,
215
+ style: () => ({ borderBottom: '2px dashed #333', borderRadius: '0.5em' }),
216
+ toggleIcon: rootProps.toggleIcon ? (row) => rootProps.toggleIcon(row) : undefined
217
+ } }));
218
+ };
219
+ const CardTreeRow = ({ row, parentOptions }) => {
220
+ const { rootProps, entity, selected } = useProvider();
221
+ const { getCardContent } = rootProps;
222
+ const rowId = entity.id.get(row);
223
+ const isSelected = selected[rowId];
224
+ const childs = entity.childs.get(row);
225
+ const parentOption = parentOptions.length ? parentOptions[parentOptions.length - 1] : undefined;
226
+ const parent = parentOption ? parentOption.optionOrg : false;
227
+ return (_jsxs("div", { className: classListToString(["entity-row", isSelected ? 'selected' : undefined]), children: [_jsx(CardHeader, { row: row, isRoot: false }), getCardContent(row, parent, childs ? 'node' : 'leaf')] }));
228
+ };
229
+ const CardHeader = ({ row, before, isRoot }) => {
230
+ const { entity, selected, rootProps, select } = useProvider();
231
+ const { getCardOptionsType = (() => 'button') } = rootProps;
232
+ const rowId = entity.id.get(row);
233
+ const isSelected = selected[rowId];
234
+ const cardOptionsType = getCardOptionsType(row);
235
+ if (cardOptionsType === 'onTitle') {
236
+ return (_jsxs("div", { className: "entity-card-header", children: [_jsx(CardOptionsOnTitle, { row: row, parent: false, isRoot: isRoot, isSelected: isSelected, before: before }), !!rootProps.getSelectedOptions && _jsx("div", { className: "entity-card-select-icon", onClick: () => select(row), children: _jsx(Icon, { path: mdiSelect, size: 0.7 }) })] }));
237
+ }
238
+ else {
239
+ return (_jsxs("div", { className: "entity-card-header", children: [_jsx(CardTitle, { isSelected: isSelected, before: before, row: row }), _jsx(CardOptionsButton, { row: row, parent: false, isRoot: true })] }));
240
+ }
241
+ };
242
+ const CardTitle = ({ row, before, isSelected }) => {
243
+ const { rootProps, select } = useProvider();
244
+ const { getCardTitle } = rootProps;
245
+ const hasBefore = !!before || !!isSelected;
246
+ return (_jsx(AIOInput, { type: 'button', text: getCardTitle(row), before: !hasBefore ? undefined :
247
+ _jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: '0.4em' }, children: [!!before && before, !!isSelected && _jsx(Icon, { path: mdiCheckboxMarked, size: 0.8, color: 'orange' })] }), className: "entity-card-title", style: { flex: 1, color: isSelected ? 'orange' : undefined }, onClick: () => select(row) }));
248
+ };
249
+ const CardOptionsButton = ({ row, parent, isRoot }) => {
250
+ const { getOptions } = useProvider();
251
+ return (_jsx(AISelect, { text: new GetSvg().getIcon('mdiDotsHorizontal', .8), caret: false, options: getOptions(row, parent, !!isRoot), justify: true, className: `${!isRoot ? 'd1-bg-cream' : 'd1-bg-gray'}`, style: { background: 'none', border: 'none', height: 24, width: 42, fontSize: '0.7em' }, popover: { modalAttrs: { style: { fontSize: '0.8em' } } } }));
252
+ };
253
+ const CardOptionsOnTitle = ({ row, parent, isRoot, isSelected, before }) => {
254
+ const { getOptions, rootProps } = useProvider();
255
+ const { getCardSubtitle } = rootProps;
256
+ const subtitle = getCardSubtitle ? getCardSubtitle(row) : undefined;
257
+ return (_jsx(AISelect, { className: "entity-card-title", rtl: true, subtext: subtitle, text: rootProps.getCardTitle(row), caret: false, options: getOptions(row, parent, !!isRoot), style: { flex: 1, color: isSelected ? 'orange' : undefined, border: 'none', height: 'fit-content' }, before: _jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: '0.4em' }, children: [!!before && before, !!isSelected && _jsx(Icon, { path: mdiCheckboxMarked, size: 0.8, color: 'orange' })] }), popover: { modalAttrs: { style: { fontSize: '0.8em' } } } }));
258
+ };
259
+ export const DateFilter = ({ result, fromDate, toDate, onChange }) => {
260
+ const DATE = new AIODate();
261
+ const changeDateByDay = (date) => {
262
+ const [year, month, day] = date;
263
+ const fromDate = DATE.getTime([year, month, day, 0, 0]);
264
+ const toDate = DATE.getTime([year, month, day, 23, 59]);
265
+ onChange({ fromDate, toDate });
266
+ };
267
+ return (_jsxs("div", { className: "date-filter", children: [_jsxs("div", { className: "date-filter-toolbar", children: [result !== undefined && _jsx("button", { className: 'date-filter-result', children: result }), _jsx("div", { style: { flex: 1 } }), _jsxs("div", { className: "date-filter-toolbar-buttons", children: [_jsx(AIDate, { className: 'date-filter-input', style: { background: 'none' }, caret: false, justify: true, jalali: true, calendarClose: true, text: _jsx(CalendarIcon, {}), dateUnit: 'day', dateType: 'dateArray', onChange: (v) => { changeDateByDay(v); }, popover: { position: 'center' } }), _jsx(DateBox, { unit: 'day', className: 'd1-bg-blue-grad', onChange: onChange }), _jsx(DateBox, { unit: 'month', className: 'd1-bg-green-grad', onChange: onChange }), _jsx(DateBox, { unit: 'year', className: 'd1-bg-red-grad', onChange: onChange })] })] }), _jsx(TimeRange, { fromDate: fromDate, toDate: toDate, onChange: ({ fromDate, toDate }) => { onChange({ fromDate, toDate }); } })] }));
268
+ };
269
+ const DateBox = ({ unit, onChange }) => {
270
+ const DATE = new AIODate();
271
+ const dic = { day: 'امروز', week: 'هفته جاری', month: 'انتخاب ماه', year: 'سال جاری' };
272
+ const changeDateByUnit = (unit) => {
273
+ let [fromArray, toArray] = DATE.getCurrentRange(unit, true);
274
+ const fromDate = DATE.getTime(fromArray);
275
+ const toDate = DATE.getTime(toArray);
276
+ onChange({ fromDate, toDate });
277
+ };
278
+ const changeDateByMonth = (month) => {
279
+ const [year] = DATE.getToday(true);
280
+ const dateArray = [year, month];
281
+ const monthDaysLength = DATE.getMonthDaysLength(dateArray);
282
+ const fromArray = [dateArray[0], dateArray[1], 1, 0, 0];
283
+ const toArray = [dateArray[0], dateArray[1], monthDaysLength, 23, 59];
284
+ const fromDate = DATE.getTime(fromArray);
285
+ const toDate = DATE.getTime(toArray);
286
+ onChange({ fromDate, toDate });
287
+ };
288
+ if (unit === 'month') {
289
+ return (_jsx(AISelect, { className: `date-box`, style: { color: '#ddd', background: 'none' }, caret: false, text: dic[unit], popover: { modalAttrs: { style: { width: '100vw' } } }, options: [
290
+ { text: 'ماه جاری', onClick: () => changeDateByUnit('month') },
291
+ ...DATE.getMonths(true).map((o, i) => ({ text: o, onClick: () => changeDateByMonth(i + 1) }))
292
+ ] }));
293
+ }
294
+ return (_jsx("div", { className: `date-box`, style: { color: '#ddd' }, onClick: () => {
295
+ if (unit === 'day') {
296
+ changeDateByUnit('day');
297
+ }
298
+ if (unit === 'year') {
299
+ changeDateByUnit('year');
300
+ }
301
+ }, children: dic[unit] }));
302
+ };
303
+ const CalendarIcon = () => {
304
+ return (_jsx("svg", { viewBox: "0 0 24 24", role: "presentation", style: { width: '1.5rem', height: '1.5rem' }, children: _jsx("path", { d: "M19,19H5V8H19M16,1V3H8V1H6V3H5C3.89,3 3,3.89 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V5C21,3.89 20.1,3 19,3H18V1M17,12H12V17H17V12Z", style: { fill: 'currentcolor' } }) }));
305
+ };
306
+ export const TimeRange = ({ fromDate, toDate, onChange }) => {
307
+ const getText = (time, field) => {
308
+ if (!time) {
309
+ return field === 'fromDate' ? 'از تاریخ' : 'تا تاریخ';
310
+ }
311
+ const DATE = new AIODate();
312
+ const { weekDay, monthString, yearStr, dayStr } = DATE.getDetails(time, true);
313
+ return `${weekDay} ${dayStr} ${monthString} ${yearStr}`;
314
+ };
315
+ const renderTime = (time, field) => {
316
+ const text = getText(time, field);
317
+ return (_jsx(AITime, { dateType: "dateNumber", className: 'time-range-input', style: { background: 'none' }, value: time, text: text, jalali: true, caret: false, onChange: (v) => onChange({ fromDate, toDate, [field]: v }), deSelect: true }));
318
+ };
319
+ return (_jsxs("div", { className: "time-range", children: [_jsx("div", { style: { flex: 1 }, children: renderTime(fromDate, 'fromDate') }), _jsx("div", { className: "time-range-splitter" }), _jsx("div", { style: { flex: 1 }, children: renderTime(toDate, 'toDate') })] }));
320
+ };
321
+ export const CardRow = ({ label, value, color, onClick }) => {
322
+ return (_jsxs("div", { className: 'card-row', onClick: () => { if (onClick) {
323
+ onClick();
324
+ } }, children: [_jsx("div", { className: "card-row-label", children: label }), _jsx("div", { style: { flex: 1 } }), _jsx("div", { className: "card-row-value", style: { color }, children: value })] }));
325
+ };
326
+ export const CardRows = ({ rows, placeholder = 'موردی وجود ندارد' }) => {
327
+ return (_jsxs("div", { className: "card-rows", children: [!rows.length && _jsx("div", { className: "card-rows-placeholder", children: placeholder }), rows.map((r, i) => {
328
+ const { onClick, isPrice } = r[2] || {};
329
+ let value = r[1];
330
+ if (isPrice && (typeof r[1] === 'number' || typeof r[1] === 'string')) {
331
+ value = SplitNumber(r[1]);
332
+ }
333
+ return _jsx(CardRow, { label: r[0], value: value, onClick: onClick }, i);
334
+ })] }));
335
+ };
336
+ export const CardBox = ({ type, label, value, color, onClick, isPrice }) => {
337
+ let cls = `card-box`;
338
+ if (type === 0) {
339
+ cls += ' d1-bg-cream';
340
+ }
341
+ const style = {};
342
+ if (type === 1) {
343
+ style.boxShadow = 'inset 2px 2px 5px 0px rgb(110 85 27 / 40%)';
344
+ }
345
+ else if (type === 2) {
346
+ style.background = 'rgba(0,0,0,0.2)';
347
+ style.color = '#fff';
348
+ }
349
+ return (_jsxs("div", { className: cls, style: style, onClick: () => { if (onClick) {
350
+ onClick();
351
+ } }, children: [_jsx("div", { className: 'card-box-label', children: label }), _jsx("div", { style: { flex: 1 } }), _jsx("div", { className: "card-box-value", style: { color }, children: isPrice ? SplitNumber(value) : value })] }));
352
+ };
353
+ export const Panel = ({ label, content }) => {
354
+ return (_jsxs("div", { className: 'd1-panel', children: [!!label && _jsx("div", { className: "d1-panel-label d1-panel-label-online-rtl", children: label }), content] }));
355
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aio-entitykit",
3
- "version": "2.0.1",
3
+ "version": "2.0.3",
4
4
  "description": "kit",
5
5
  "main": "index.js",
6
6
  "scripts": {