namirasoft-site-react 1.5.10 → 1.5.12

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 (129) hide show
  1. package/dist/components/NSHeader.d.ts +2 -2
  2. package/dist/components/NSLayout.d.ts +2 -2
  3. package/dist/components/NSListMenu.d.ts +2 -0
  4. package/dist/components/NSListMenu.js +26 -9
  5. package/dist/components/NSListMenu.js.map +1 -1
  6. package/dist/components/NSReorderDialog.d.ts +30 -0
  7. package/dist/components/NSReorderDialog.js +73 -0
  8. package/dist/components/NSReorderDialog.js.map +1 -0
  9. package/dist/components/NSReorderDialog.module.css +50 -0
  10. package/dist/components/NSSortDialog.d.ts +21 -0
  11. package/dist/components/NSSortDialog.js +67 -0
  12. package/dist/components/NSSortDialog.js.map +1 -0
  13. package/dist/components/NSTable.d.ts +17 -1
  14. package/dist/components/NSTable.js +117 -39
  15. package/dist/components/NSTable.js.map +1 -1
  16. package/dist/components/NSTable.module.css +1 -0
  17. package/dist/formatter/BaseColumnFormatter.d.ts +7 -0
  18. package/dist/formatter/BaseColumnFormatter.js +53 -0
  19. package/dist/formatter/BaseColumnFormatter.js.map +1 -1
  20. package/dist/formatter/BaseURLImageFormatter.d.ts +1 -0
  21. package/dist/formatter/BaseURLImageFormatter.js +3 -0
  22. package/dist/formatter/BaseURLImageFormatter.js.map +1 -1
  23. package/dist/formatter/BooleanFormatter.d.ts +1 -0
  24. package/dist/formatter/BooleanFormatter.js +3 -0
  25. package/dist/formatter/BooleanFormatter.js.map +1 -1
  26. package/dist/formatter/BytesFormatter.d.ts +1 -0
  27. package/dist/formatter/BytesFormatter.js +3 -0
  28. package/dist/formatter/BytesFormatter.js.map +1 -1
  29. package/dist/formatter/DateFormatter.d.ts +1 -0
  30. package/dist/formatter/DateFormatter.js +3 -0
  31. package/dist/formatter/DateFormatter.js.map +1 -1
  32. package/dist/formatter/DateTimeFormatter.d.ts +1 -0
  33. package/dist/formatter/DateTimeFormatter.js +3 -0
  34. package/dist/formatter/DateTimeFormatter.js.map +1 -1
  35. package/dist/formatter/DurationFormatter.d.ts +1 -0
  36. package/dist/formatter/DurationFormatter.js +3 -0
  37. package/dist/formatter/DurationFormatter.js.map +1 -1
  38. package/dist/formatter/EmailFormatter.d.ts +1 -0
  39. package/dist/formatter/EmailFormatter.js +3 -0
  40. package/dist/formatter/EmailFormatter.js.map +1 -1
  41. package/dist/formatter/EnumFormatter.d.ts +1 -0
  42. package/dist/formatter/EnumFormatter.js +3 -0
  43. package/dist/formatter/EnumFormatter.js.map +1 -1
  44. package/dist/formatter/FloatFormatter.d.ts +1 -0
  45. package/dist/formatter/FloatFormatter.js +3 -0
  46. package/dist/formatter/FloatFormatter.js.map +1 -1
  47. package/dist/formatter/IDFormatter.d.ts +1 -0
  48. package/dist/formatter/IDFormatter.js +3 -0
  49. package/dist/formatter/IDFormatter.js.map +1 -1
  50. package/dist/formatter/IPFormatter.d.ts +1 -0
  51. package/dist/formatter/IPFormatter.js +23 -0
  52. package/dist/formatter/IPFormatter.js.map +1 -1
  53. package/dist/formatter/IntegerFormatter.d.ts +1 -0
  54. package/dist/formatter/IntegerFormatter.js +3 -0
  55. package/dist/formatter/IntegerFormatter.js.map +1 -1
  56. package/dist/formatter/JsonFormatter.d.ts +1 -0
  57. package/dist/formatter/JsonFormatter.js +13 -0
  58. package/dist/formatter/JsonFormatter.js.map +1 -1
  59. package/dist/formatter/MoneyFormatter.d.ts +1 -0
  60. package/dist/formatter/MoneyFormatter.js +3 -0
  61. package/dist/formatter/MoneyFormatter.js.map +1 -1
  62. package/dist/formatter/PercentFormatter.d.ts +1 -0
  63. package/dist/formatter/PercentFormatter.js +3 -0
  64. package/dist/formatter/PercentFormatter.js.map +1 -1
  65. package/dist/formatter/PhoneFormatter.d.ts +1 -0
  66. package/dist/formatter/PhoneFormatter.js +3 -0
  67. package/dist/formatter/PhoneFormatter.js.map +1 -1
  68. package/dist/formatter/SensitiveFormatter.d.ts +1 -0
  69. package/dist/formatter/SensitiveFormatter.js +3 -0
  70. package/dist/formatter/SensitiveFormatter.js.map +1 -1
  71. package/dist/formatter/StringFormatter.d.ts +1 -0
  72. package/dist/formatter/StringFormatter.js +3 -0
  73. package/dist/formatter/StringFormatter.js.map +1 -1
  74. package/dist/formatter/TimeFormatter.d.ts +1 -0
  75. package/dist/formatter/TimeFormatter.js +3 -0
  76. package/dist/formatter/TimeFormatter.js.map +1 -1
  77. package/dist/formatter/URLFormatter.d.ts +1 -0
  78. package/dist/formatter/URLFormatter.js +3 -0
  79. package/dist/formatter/URLFormatter.js.map +1 -1
  80. package/dist/formatter/UnknowFormatter.d.ts +1 -0
  81. package/dist/formatter/UnknowFormatter.js +3 -0
  82. package/dist/formatter/UnknowFormatter.js.map +1 -1
  83. package/dist/main.d.ts +2 -2
  84. package/dist/main.js +2 -2
  85. package/dist/main.js.map +1 -1
  86. package/dist/routing/NSRouterMaker.d.ts +13 -7
  87. package/dist/routing/NSRouterMaker.js +7 -8
  88. package/dist/routing/NSRouterMaker.js.map +1 -1
  89. package/package.json +1 -1
  90. package/src/components/NSHeader.tsx +2 -2
  91. package/src/components/NSLayout.tsx +2 -2
  92. package/src/components/NSListMenu.tsx +43 -12
  93. package/src/components/NSReorderDialog.module.css +50 -0
  94. package/src/components/NSReorderDialog.tsx +155 -0
  95. package/src/components/NSSortDialog.tsx +125 -0
  96. package/src/components/NSTable.module.css +1 -0
  97. package/src/components/NSTable.tsx +207 -68
  98. package/src/formatter/BaseColumnFormatter.ts +68 -0
  99. package/src/formatter/BaseURLImageFormatter.tsx +4 -0
  100. package/src/formatter/BooleanFormatter.ts +4 -0
  101. package/src/formatter/BytesFormatter.tsx +4 -0
  102. package/src/formatter/DateFormatter.ts +4 -0
  103. package/src/formatter/DateTimeFormatter.ts +4 -0
  104. package/src/formatter/DurationFormatter.ts +4 -0
  105. package/src/formatter/EmailFormatter.tsx +4 -0
  106. package/src/formatter/EnumFormatter.ts +4 -0
  107. package/src/formatter/FloatFormatter.ts +4 -0
  108. package/src/formatter/IDFormatter.tsx +5 -1
  109. package/src/formatter/IPFormatter.ts +26 -0
  110. package/src/formatter/IntegerFormatter.ts +4 -0
  111. package/src/formatter/JsonFormatter.tsx +17 -0
  112. package/src/formatter/MoneyFormatter.ts +4 -0
  113. package/src/formatter/PercentFormatter.tsx +4 -0
  114. package/src/formatter/PhoneFormatter.tsx +4 -0
  115. package/src/formatter/SensitiveFormatter.tsx +4 -0
  116. package/src/formatter/StringFormatter.tsx +4 -0
  117. package/src/formatter/TimeFormatter.ts +4 -0
  118. package/src/formatter/URLFormatter.tsx +4 -0
  119. package/src/formatter/UnknowFormatter.ts +4 -0
  120. package/src/main.ts +2 -2
  121. package/src/routing/NSRouterMaker.tsx +21 -13
  122. package/dist/routing/NSRouterMakerComponent.d.ts +0 -4
  123. package/dist/routing/NSRouterMakerComponent.js +0 -2
  124. package/dist/routing/NSRouterMakerComponent.js.map +0 -1
  125. package/dist/routing/NSRouterMakerProps.d.ts +0 -4
  126. package/dist/routing/NSRouterMakerProps.js +0 -2
  127. package/dist/routing/NSRouterMakerProps.js.map +0 -1
  128. package/src/routing/NSRouterMakerComponent.ts +0 -6
  129. package/src/routing/NSRouterMakerProps.ts +0 -6
@@ -3,7 +3,7 @@ import { Fragment, ReactNode } from 'react';
3
3
  import { IBackgroundProps } from '../props/IBackgroundProps';
4
4
  import { IBaseComponentProps } from '../props/IBaseComponentProps';
5
5
  import { IHeaderRightProps } from '../props/IHeaderRightProps';
6
- import { NSRouterMakerProps } from '../routing/NSRouterMakerProps';
6
+ import { NSRouterMakerResult } from '../routing/NSRouterMaker';
7
7
  import { NSBarAction, NSBarActionProps, isValidAction } from './NSBarAction';
8
8
  import { NSBarAlert, NSBarAlertProps } from './NSBarAlert';
9
9
  import { NSBarNotification, NSBarNotificationProps } from './NSBarNotification';
@@ -13,7 +13,7 @@ import { NSHeader } from './NSHeader';
13
13
  import Styles from './NSLayout.module.css';
14
14
  import { NSSpace, NSSpaceSizeType } from './NSSpace';
15
15
 
16
- export interface NSLayoutProps extends IBaseComponentProps, NSRouterMakerProps
16
+ export interface NSLayoutProps extends IBaseComponentProps, NSRouterMakerResult
17
17
  {
18
18
  scope: string;
19
19
  logo: string;
@@ -3,6 +3,7 @@ import { EnvService } from "namirasoft-core";
3
3
  import { useEffect, useState } from "react";
4
4
  import { NSCard } from "./NSCard";
5
5
  import { NSSection } from "./NSSection";
6
+ import { NSTitle } from "./NSTitle";
6
7
 
7
8
  export interface NSListMenuProps
8
9
  {
@@ -10,6 +11,7 @@ export interface NSListMenuProps
10
11
  name: string;
11
12
  isLoggedIn?: () => boolean;
12
13
  onError?: (error: Error | string) => void;
14
+ filters?: FilterLinkFullRow[];
13
15
  }
14
16
 
15
17
  interface NSListMenuState
@@ -19,10 +21,12 @@ interface NSListMenuState
19
21
 
20
22
  export function NSListMenu(props: NSListMenuProps)
21
23
  {
22
- const [state, setState] = useState<NSListMenuState>({ filters: [] });
24
+ const [state, setState] = useState<NSListMenuState>({ filters: props.filters ?? [] });
23
25
 
24
26
  useEffect(() =>
25
27
  {
28
+ if (props.filters)
29
+ return;
26
30
  let REACT_APP_BASE_URL_API_LINK = new EnvService("REACT_APP_BASE_URL_API_LINK", true).getString();
27
31
  let server = new NamirasoftAPILinkServer(REACT_APP_BASE_URL_API_LINK, props.onError ?? (() => { }));
28
32
  server.filter.ListFilterLinks(props.scope, props.name, null, null, null, []).then((filters) =>
@@ -79,8 +83,15 @@ export function NSListMenu(props: NSListMenuProps)
79
83
  return chain;
80
84
  };
81
85
 
82
- const titleOf = (f: FilterLinkFullRow): string =>
83
- chainOf(displayOf(f)).map(nameOf).join(" / ");
86
+ const rootOf = (f: FilterLinkFullRow): FilterLinkFullRow =>
87
+ chainOf(displayOf(f))[0];
88
+
89
+ const subtitleOf = (f: FilterLinkFullRow): string =>
90
+ {
91
+ let chain = chainOf(displayOf(f));
92
+ let rest = chain.slice(1);
93
+ return rest.length > 0 ? rest.map(nameOf).join(" / ") : nameOf(chain[0]);
94
+ };
84
95
 
85
96
  const descriptionOf = (f: FilterLinkFullRow): string =>
86
97
  f.link?.description ?? "";
@@ -136,19 +147,39 @@ export function NSListMenu(props: NSListMenuProps)
136
147
  };
137
148
 
138
149
  let items = getMenuItems();
150
+
151
+ let groups: { root: FilterLinkFullRow; items: FilterLinkFullRow[] }[] = [];
152
+ for (let f of items)
153
+ {
154
+ let root = rootOf(f);
155
+ let last = groups[groups.length - 1];
156
+ if (last && last.root.id === root.id)
157
+ last.items.push(f);
158
+ else
159
+ groups.push({ root, items: [f] });
160
+ }
139
161
 
140
162
  return (
141
- <NSSection style={{ gap: "16px" }}>
163
+ <div style={{ display: "flex", flexDirection: "column", width: "100%", gap: "32px" }}>
142
164
  {
143
- items.map((filter: FilterLinkFullRow) =>
144
- <NSCard
145
- key={filter.id}
146
- link={{ href: filter.link?.url ?? "" }}
147
- title={titleOf(filter)}
148
- description={descriptionOf(filter)}
149
- />
165
+ groups.map((group) =>
166
+ <div key={group.root.id} style={{ width: "100%" }}>
167
+ <NSTitle title={nameOf(group.root)} style={{ marginBottom: 16, fontSize: 32 }} />
168
+ <NSSection style={{ gap: "16px" }}>
169
+ {
170
+ group.items.map((filter: FilterLinkFullRow) =>
171
+ <NSCard
172
+ key={filter.id}
173
+ link={{ href: filter.link?.url ?? "" }}
174
+ title={subtitleOf(filter)}
175
+ description={descriptionOf(filter)}
176
+ />
177
+ )
178
+ }
179
+ </NSSection>
180
+ </div>
150
181
  )
151
182
  }
152
- </NSSection>
183
+ </div>
153
184
  );
154
185
  }
@@ -0,0 +1,50 @@
1
+ .column_item {
2
+ width: 100%;
3
+ display: flex;
4
+ align-items: center;
5
+ gap: 10px;
6
+ padding: 8px 12px;
7
+ border-radius: 6px;
8
+ border: 2px solid transparent;
9
+ background-color: rgba(20, 27, 92, 0.04);
10
+ cursor: grab;
11
+ user-select: none;
12
+ box-sizing: border-box;
13
+ transition: background-color 0.1s, border-color 0.1s;
14
+ }
15
+
16
+ .column_item:hover {
17
+ background-color: rgba(20, 27, 92, 0.08);
18
+ }
19
+
20
+ .column_item_dragging {
21
+ opacity: 0.35;
22
+ }
23
+
24
+ .column_item_drag_over {
25
+ border-color: rgba(20, 27, 92, 0.45);
26
+ border-style: dashed;
27
+ background-color: rgba(20, 27, 92, 0.1);
28
+ }
29
+
30
+ .drag_handle {
31
+ color: #bbb;
32
+ font-size: 20px;
33
+ line-height: 1;
34
+ cursor: grab;
35
+ flex-shrink: 0;
36
+ }
37
+
38
+ .checkbox {
39
+ width: 18px;
40
+ height: 18px;
41
+ cursor: pointer;
42
+ margin: 0;
43
+ flex-shrink: 0;
44
+ accent-color: rgba(20, 27, 92, 1);
45
+ }
46
+
47
+ .column_label {
48
+ font-size: 14px;
49
+ flex: 1;
50
+ }
@@ -0,0 +1,155 @@
1
+ import { Component, DragEvent } from "react";
2
+ import { NSBox } from "./NSBox";
3
+ import { NSButtonBlue } from "./NSButtonBlue";
4
+ import { NSColumn } from "./NSColumn";
5
+ import { NSDialog } from "./NSDialog";
6
+ import { NSTitle } from "./NSTitle";
7
+ import { TableColumnInfo } from "./NSTable";
8
+ import Styles from "./NSReorderDialog.module.css";
9
+
10
+ interface ColumnItem
11
+ {
12
+ key: string;
13
+ text: string;
14
+ checked: boolean;
15
+ }
16
+
17
+ interface NSReorderDialogProps
18
+ {
19
+ visibleColumnKeys: string[];
20
+ getColumns: () => TableColumnInfo[];
21
+ onCancel: () => void;
22
+ onApply: (orderedKeys: string[]) => void;
23
+ }
24
+
25
+ interface NSReorderDialogState
26
+ {
27
+ columns: ColumnItem[];
28
+ dragFromIndex: number | null;
29
+ dragOverIndex: number | null;
30
+ }
31
+
32
+ export class NSReorderDialog extends Component<NSReorderDialogProps, NSReorderDialogState>
33
+ {
34
+ constructor(props: NSReorderDialogProps)
35
+ {
36
+ super(props);
37
+ this.state = {
38
+ columns: this.buildColumnItems(props),
39
+ dragFromIndex: null,
40
+ dragOverIndex: null
41
+ };
42
+ }
43
+
44
+ private buildColumnItems(props: NSReorderDialogProps): ColumnItem[]
45
+ {
46
+ const allColumns = props.getColumns();
47
+ const visibleKeys = props.visibleColumnKeys;
48
+
49
+ if (visibleKeys.length === 0)
50
+ return allColumns.map(c => ({ key: c.table.name + "." + c.name, text: c.text, checked: true }));
51
+
52
+ const visibleItems: ColumnItem[] = visibleKeys
53
+ .map(k => allColumns.find(c => c.table.name + "." + c.name === k))
54
+ .filter(Boolean)
55
+ .map(c => ({ key: c!.table.name + "." + c!.name, text: c!.text, checked: true }));
56
+
57
+ const hiddenItems: ColumnItem[] = allColumns
58
+ .filter(c => !visibleKeys.includes(c.table.name + "." + c.name))
59
+ .map(c => ({ key: c.table.name + "." + c.name, text: c.text, checked: false }));
60
+
61
+ return [...visibleItems, ...hiddenItems];
62
+ }
63
+
64
+ private onDragStart = (index: number) => this.setState({ dragFromIndex: index });
65
+
66
+ private onDragOver = (e: DragEvent, index: number) =>
67
+ {
68
+ e.preventDefault();
69
+ if (this.state.dragOverIndex !== index)
70
+ this.setState({ dragOverIndex: index });
71
+ };
72
+
73
+ private onDrop = (e: DragEvent, dropIndex: number) =>
74
+ {
75
+ e.preventDefault();
76
+ const { dragFromIndex, columns } = this.state;
77
+ if (dragFromIndex === null || dragFromIndex === dropIndex)
78
+ {
79
+ this.setState({ dragFromIndex: null, dragOverIndex: null });
80
+ return;
81
+ }
82
+ const next = [...columns];
83
+ const [moved] = next.splice(dragFromIndex, 1);
84
+ next.splice(dropIndex, 0, moved);
85
+ this.setState({ columns: next, dragFromIndex: null, dragOverIndex: null });
86
+ };
87
+
88
+ private onDragEnd = () => this.setState({ dragFromIndex: null, dragOverIndex: null });
89
+
90
+ private toggleChecked = (key: string) =>
91
+ this.setState(prev => ({
92
+ columns: prev.columns.map(c => c.key === key ? { ...c, checked: !c.checked } : c)
93
+ }));
94
+
95
+ private handleApply = () =>
96
+ {
97
+ const orderedKeys = this.state.columns.filter(c => c.checked).map(c => c.key);
98
+ this.props.onApply(orderedKeys);
99
+ };
100
+
101
+ override render()
102
+ {
103
+ const { onCancel } = this.props;
104
+ const { columns, dragFromIndex, dragOverIndex } = this.state;
105
+
106
+ return (
107
+ <NSDialog
108
+ center_dialog
109
+ closeButton={{ show: true }}
110
+ onClose={onCancel}
111
+ style={{ minWidth: NSBox.width.double }}
112
+ >
113
+ <NSColumn classList={["align-items-center"]}>
114
+ <NSTitle title="Columns" style={{ marginBottom: 0, fontSize: 24 }} />
115
+ <NSColumn classList={["gap-1"]}>
116
+ {
117
+ columns.map((col, index) =>
118
+ {
119
+ const isDragging = dragFromIndex === index;
120
+ const isDragOver = dragOverIndex === index && !isDragging;
121
+ let cls = Styles.column_item;
122
+ if (isDragging) cls += " " + Styles.column_item_dragging;
123
+ if (isDragOver) cls += " " + Styles.column_item_drag_over;
124
+ return (
125
+ <div
126
+ key={col.key}
127
+ draggable
128
+ onDragStart={() => this.onDragStart(index)}
129
+ onDragOver={e => this.onDragOver(e, index)}
130
+ onDrop={e => this.onDrop(e, index)}
131
+ onDragEnd={this.onDragEnd}
132
+ className={cls}
133
+ >
134
+ <span className={Styles.drag_handle}>⠿</span>
135
+ <input
136
+ type="checkbox"
137
+ checked={col.checked}
138
+ onChange={() => this.toggleChecked(col.key)}
139
+ className={Styles.checkbox}
140
+ />
141
+ <span className={Styles.column_label}>{col.text}</span>
142
+ </div>
143
+ );
144
+ })
145
+ }
146
+ </NSColumn>
147
+ <NSButtonBlue
148
+ title="Apply"
149
+ onClick={{ action: this.handleApply, showLoading: false }}
150
+ />
151
+ </NSColumn>
152
+ </NSDialog>
153
+ );
154
+ }
155
+ }
@@ -0,0 +1,125 @@
1
+ import { BaseMetaColumn, BaseMetaTable, SortItem } from "namirasoft-core";
2
+ import { Component, createRef } from "react";
3
+ import { NSBoxBaseCombo } from "./NSBoxBaseCombo";
4
+ import { NSBoxBoolean } from "./NSBoxBoolean";
5
+ import { NSBoxCombo } from "./NSBoxCombo";
6
+ import { NSButtonBlue } from "./NSButtonBlue";
7
+ import { NSColumn } from "./NSColumn";
8
+ import { NSDialog } from "./NSDialog";
9
+ import { NSTitle } from "./NSTitle";
10
+ import { TableColumnInfo } from "./NSTable";
11
+
12
+ interface NSSortDialogProps
13
+ {
14
+ sorts: SortItem[];
15
+ getColumns: () => TableColumnInfo[];
16
+ onCancel: () => void;
17
+ onApply: (sorts: SortItem[] | null) => void;
18
+ }
19
+
20
+ interface NSSortDialogState
21
+ {
22
+ sortEnabled: boolean;
23
+ }
24
+
25
+ export class NSSortDialog extends Component<NSSortDialogProps, NSSortDialogState>
26
+ {
27
+ private sortBoolRef = createRef<NSBoxBoolean>();
28
+ private sortColumnRef = createRef<NSBoxBaseCombo<TableColumnInfo>>();
29
+ private sortDirectionRef = createRef<NSBoxCombo>();
30
+
31
+ constructor(props: NSSortDialogProps)
32
+ {
33
+ super(props);
34
+ this.state = { sortEnabled: props.sorts.length > 0 };
35
+ }
36
+
37
+ private handleApply = () =>
38
+ {
39
+ if (!this.sortBoolRef.current?.getValueBool())
40
+ {
41
+ this.props.onApply(null);
42
+ return;
43
+ }
44
+ const column = this.sortColumnRef.current?.getDataOne();
45
+ const direction = this.sortDirectionRef.current?.getValueOne();
46
+ if (column)
47
+ {
48
+ const t = new BaseMetaTable(null, column.table.name, column.table.text);
49
+ const c = new BaseMetaColumn(t, column.name, column.text, "", true);
50
+ const sort = new SortItem(t, c, direction === "true");
51
+ this.props.onApply([sort]);
52
+ }
53
+ else
54
+ this.props.onApply(null);
55
+ };
56
+
57
+ override render()
58
+ {
59
+ const { sorts, getColumns, onCancel } = this.props;
60
+
61
+ return (
62
+ <NSDialog
63
+ center_dialog
64
+ closeButton={{ show: true }}
65
+ onClose={onCancel}
66
+ >
67
+ <NSTitle title="Sort" style={{ marginBottom: 0, fontSize: 24 }} />
68
+ <NSColumn classList={["align-items-center mt-3"]}>
69
+ <NSBoxBoolean
70
+ ref={this.sortBoolRef}
71
+ required
72
+ title="Sort"
73
+ hideHeader={true}
74
+ checked={sorts.length > 0}
75
+ onChanged={box => this.setState({ sortEnabled: box.getValueBool(false) })}
76
+ />
77
+ <NSBoxBaseCombo<TableColumnInfo>
78
+ ref={this.sortColumnRef}
79
+ title="Column"
80
+ required
81
+ defaultValue={sorts[0]?.column.name}
82
+ getItems={async () =>
83
+ {
84
+ const cs = getColumns();
85
+ return { count: cs.length, rows: cs }
86
+ }}
87
+ getTitle={c => c.text}
88
+ getValue={c => c.name}
89
+ getSort={() => null}
90
+ multiple={false}
91
+ disabled={!this.state.sortEnabled}
92
+ menu={{
93
+ builtin: {
94
+ copy: { enabled: false, getValue: () => "" }
95
+ },
96
+ items: []
97
+ }}
98
+ />
99
+ <NSBoxCombo
100
+ ref={this.sortDirectionRef}
101
+ title="Direction"
102
+ required
103
+ defaultValue={sorts[0] ? String(sorts[0].ascending) : "true"}
104
+ getOptions={() => [
105
+ { value: "true", title: "Ascending" },
106
+ { value: "false", title: "Descending" }
107
+ ]}
108
+ multiple={false}
109
+ disabled={!this.state.sortEnabled}
110
+ menu={{
111
+ builtin: {
112
+ copy: { enabled: false, getValue: () => "" }
113
+ },
114
+ items: []
115
+ }}
116
+ />
117
+ <NSButtonBlue
118
+ title="Apply"
119
+ onClick={{ action: this.handleApply, showLoading: false }}
120
+ />
121
+ </NSColumn>
122
+ </NSDialog>
123
+ );
124
+ }
125
+ }
@@ -142,6 +142,7 @@
142
142
  align-items: center;
143
143
  width: 100%;
144
144
  gap: 16px;
145
+ margin-left: auto;
145
146
  }
146
147
 
147
148
  .ns_table_button {