namirasoft-account-react 1.4.431 → 1.4.433

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 (158) hide show
  1. package/.env.template +15 -15
  2. package/SKILLS.md +514 -514
  3. package/config-overrides.js +72 -72
  4. package/dist/App.d.ts +1 -1
  5. package/dist/NSARouterMaker.js +1 -0
  6. package/dist/NSARouterMaker.js.map +1 -1
  7. package/dist/NSARouterMakerProps.d.ts +2 -0
  8. package/dist/NSATaskService.d.ts +35 -0
  9. package/dist/NSATaskService.js +80 -0
  10. package/dist/NSATaskService.js.map +1 -0
  11. package/dist/UseParams.d.ts +1 -1
  12. package/dist/components/NSAAccessListDialog.d.ts +2 -2
  13. package/dist/components/NSAAccessListDialog.module.css +71 -71
  14. package/dist/components/NSAMasterMenu.d.ts +1 -1
  15. package/dist/components/NSAMasterMenu.module.css +248 -248
  16. package/dist/components/NSAMasterMenuItem.d.ts +1 -1
  17. package/dist/components/NSAMessageListDialog.d.ts +1 -1
  18. package/dist/components/NSAMessageListDialog.js +4 -3
  19. package/dist/components/NSAMessageListDialog.js.map +1 -1
  20. package/dist/components/NSAMessageListDialog.module.css +99 -99
  21. package/dist/components/NSANavigationGuard.d.ts +6 -0
  22. package/dist/components/NSANavigationGuard.js +37 -0
  23. package/dist/components/NSANavigationGuard.js.map +1 -0
  24. package/dist/components/NSAProductListDialog.d.ts +1 -1
  25. package/dist/components/NSAProductListDialog.module.css +44 -44
  26. package/dist/components/NSAReorderDialog.d.ts +1 -1
  27. package/dist/components/NSAReorderDialog.module.css +49 -49
  28. package/dist/components/NSASortDialog.d.ts +1 -1
  29. package/dist/components/NSATable.js +7 -0
  30. package/dist/components/NSATable.js.map +1 -1
  31. package/dist/components/NSATaskBar.d.ts +13 -0
  32. package/dist/components/NSATaskBar.js +53 -0
  33. package/dist/components/NSATaskBar.js.map +1 -0
  34. package/dist/components/NSATaskBar.module.css +58 -0
  35. package/dist/components/NSAUserDialog.d.ts +1 -1
  36. package/dist/components/NSAUserDialog.module.css +67 -67
  37. package/dist/components/NSAWorkspaceListDialog.d.ts +1 -1
  38. package/dist/components/NSAWorkspaceListDialog.module.css +41 -41
  39. package/dist/components/NSBoxSecret.d.ts +1 -1
  40. package/dist/components/NSBoxSecret.module.css +23 -23
  41. package/dist/components/NSLabelSecret.d.ts +1 -1
  42. package/dist/components/quickfilter/NSAQuickFilterBar.d.ts +1 -1
  43. package/dist/components/quickfilter/NSAQuickFilterDialog.d.ts +1 -1
  44. package/dist/index.js +5 -2
  45. package/dist/index.js.map +1 -1
  46. package/dist/layouts/Actions.d.ts +1 -1
  47. package/dist/layouts/Actions.js +8 -6
  48. package/dist/layouts/Actions.js.map +1 -1
  49. package/dist/layouts/NSALayout.d.ts +1 -6
  50. package/dist/layouts/NSALayout.js +36 -61
  51. package/dist/layouts/NSALayout.js.map +1 -1
  52. package/dist/layouts/NSASectionEdit.d.ts +3 -1
  53. package/dist/layouts/NSASectionEdit.js +28 -19
  54. package/dist/layouts/NSASectionEdit.js.map +1 -1
  55. package/dist/layouts/NSASectionEditTabPage.d.ts +1 -1
  56. package/dist/layouts/NSASectionEditTabPage.module.css +4 -4
  57. package/dist/layouts/NSASectionList.d.ts +1 -1
  58. package/dist/layouts/NSASectionList.module.css +31 -31
  59. package/dist/layouts/NSASectionView.d.ts +1 -1
  60. package/dist/layouts/NSASectionViewTabMore.d.ts +1 -1
  61. package/dist/layouts/NSASectionViewTabMore.js +3 -3
  62. package/dist/layouts/NSASectionViewTabMore.js.map +1 -1
  63. package/dist/layouts/NSASectionViewTabPage.d.ts +1 -1
  64. package/dist/layouts/NSASectionViewTabPage.module.css +47 -47
  65. package/dist/pages/NSAConsentPage.module.css +26 -26
  66. package/dist/pages/NSAEmailVerificationPage.d.ts +1 -1
  67. package/dist/pages/NSAHomePage.d.ts +1 -1
  68. package/dist/pages/NSAHomePage.module.css +41 -41
  69. package/dist/pages/NSALoginPage.d.ts +1 -1
  70. package/dist/pages/NSALoginPage.module.css +26 -26
  71. package/dist/pages/NSAPhoneVerificationPage.d.ts +1 -1
  72. package/dist/pages/NSAVerificationPage.d.ts +1 -1
  73. package/dist/pages/NSAVerificationPage.module.css +31 -31
  74. package/dist/pages/PaymentRequired.js +4 -2
  75. package/dist/pages/PaymentRequired.js.map +1 -1
  76. package/package.json +94 -94
  77. package/public/index.html +21 -21
  78. package/src/App.css +31 -31
  79. package/src/App.tsx +19 -19
  80. package/src/CTFRow.ts +7 -7
  81. package/src/IEntityInfo.ts +33 -33
  82. package/src/NSACacheService.ts +120 -120
  83. package/src/NSAFilterOperators.ts +92 -92
  84. package/src/NSARouterMaker.tsx +140 -139
  85. package/src/NSARouterMakerConfig.ts +15 -15
  86. package/src/NSARouterMakerProps.ts +24 -22
  87. package/src/NSATaskService.ts +123 -0
  88. package/src/Router.tsx +45 -45
  89. package/src/UseParams.tsx +18 -18
  90. package/src/components/NSAAccessListDialog.module.css +71 -71
  91. package/src/components/NSAAccessListDialog.tsx +178 -178
  92. package/src/components/NSAMasterMenu.module.css +248 -248
  93. package/src/components/NSAMasterMenu.tsx +169 -169
  94. package/src/components/NSAMasterMenuItem.tsx +250 -250
  95. package/src/components/NSAMessageListDialog.module.css +99 -99
  96. package/src/components/NSAMessageListDialog.tsx +142 -141
  97. package/src/components/NSANavigationGuard.tsx +65 -0
  98. package/src/components/NSAProductListDialog.module.css +44 -44
  99. package/src/components/NSAProductListDialog.tsx +88 -88
  100. package/src/components/NSAReorderDialog.module.css +49 -49
  101. package/src/components/NSAReorderDialog.tsx +149 -149
  102. package/src/components/NSASortDialog.tsx +117 -117
  103. package/src/components/NSATable.tsx +498 -489
  104. package/src/components/NSATaskBar.module.css +58 -0
  105. package/src/components/NSATaskBar.tsx +102 -0
  106. package/src/components/NSAUserDialog.module.css +67 -67
  107. package/src/components/NSAUserDialog.tsx +122 -122
  108. package/src/components/NSAWorkspaceListDialog.module.css +41 -41
  109. package/src/components/NSAWorkspaceListDialog.tsx +147 -147
  110. package/src/components/NSBoxSecret.module.css +23 -23
  111. package/src/components/NSBoxSecret.tsx +258 -258
  112. package/src/components/NSLabelSecret.tsx +37 -37
  113. package/src/components/quickfilter/NSAFilterBoxBase.tsx +55 -55
  114. package/src/components/quickfilter/NSAFilterBoxBoolean.tsx +54 -54
  115. package/src/components/quickfilter/NSAFilterBoxDate.tsx +104 -104
  116. package/src/components/quickfilter/NSAFilterBoxDateTime.tsx +105 -105
  117. package/src/components/quickfilter/NSAFilterBoxEnum.module.css +44 -44
  118. package/src/components/quickfilter/NSAFilterBoxEnum.tsx +79 -79
  119. package/src/components/quickfilter/NSAFilterBoxNumber.tsx +136 -136
  120. package/src/components/quickfilter/NSAFilterBoxString.tsx +81 -81
  121. package/src/components/quickfilter/NSAFilterBoxTime.tsx +101 -101
  122. package/src/components/quickfilter/NSAQuickFilterBar.module.css +19 -19
  123. package/src/components/quickfilter/NSAQuickFilterBar.tsx +114 -114
  124. package/src/components/quickfilter/NSAQuickFilterDialog.module.css +74 -74
  125. package/src/components/quickfilter/NSAQuickFilterDialog.tsx +260 -260
  126. package/src/css.d.ts +13 -13
  127. package/src/formatters/SecretFormatter.tsx +24 -24
  128. package/src/index.tsx +26 -24
  129. package/src/layouts/Actions.ts +146 -145
  130. package/src/layouts/CFTUtil.ts +18 -18
  131. package/src/layouts/NSALayout.tsx +790 -841
  132. package/src/layouts/NSASectionEdit.tsx +279 -260
  133. package/src/layouts/NSASectionEditTabPage.module.css +4 -4
  134. package/src/layouts/NSASectionEditTabPage.tsx +250 -250
  135. package/src/layouts/NSASectionList.module.css +31 -31
  136. package/src/layouts/NSASectionList.tsx +149 -149
  137. package/src/layouts/NSASectionView.tsx +100 -100
  138. package/src/layouts/NSASectionViewTabMore.tsx +77 -77
  139. package/src/layouts/NSASectionViewTabPage.module.css +47 -47
  140. package/src/layouts/NSASectionViewTabPage.tsx +419 -419
  141. package/src/main.ts +46 -46
  142. package/src/pages/NSAConsentPage.module.css +26 -26
  143. package/src/pages/NSAConsentPage.tsx +120 -120
  144. package/src/pages/NSAEmailVerificationPage.tsx +30 -30
  145. package/src/pages/NSAHomePage.module.css +41 -41
  146. package/src/pages/NSAHomePage.tsx +102 -102
  147. package/src/pages/NSALoginPage.module.css +26 -26
  148. package/src/pages/NSALoginPage.tsx +87 -87
  149. package/src/pages/NSAPhoneVerificationPage.tsx +94 -94
  150. package/src/pages/NSAVerificationPage.module.css +31 -31
  151. package/src/pages/NSAVerificationPage.tsx +186 -186
  152. package/src/pages/PaymentRequired.tsx +76 -74
  153. package/tsconfig.json +43 -43
  154. package/dist/App.css +0 -32
  155. package/dist/components/quickfilter/NSAFilterBoxEnum.module.css +0 -45
  156. package/dist/components/quickfilter/NSAQuickFilterBar.module.css +0 -20
  157. package/dist/components/quickfilter/NSAQuickFilterDialog.module.css +0 -75
  158. package/dist/index.css +0 -0
@@ -1,261 +1,280 @@
1
- import { IBaseComponentProps, NSID, NSLoading } from "namirasoft-site-react";
2
- import { NSSection, NSPanel, NSButtonBlue, NSLine, NSSpace, NSSpaceSizeType } from 'namirasoft-site-react';
3
- import { NSARouterMakerProps } from "../NSARouterMakerProps";
4
- import { Component, createRef, ReactNode } from "react";
5
- import { IEntityInfo } from "../IEntityInfo";
6
- import { IStorageLocal, NamingConvention } from "namirasoft-core";
7
- import { NSASectionViewTabPage, NSASectionViewTabPageUIProps } from "./NSASectionViewTabPage";
8
- import { NSASectionEditTabPage, NSASectionEditTabPageEditorProps, NSASectionEditTabPageUIProps } from "./NSASectionEditTabPage";
9
- import { CategoryRow, FieldRow } from "namirasoft-field";
10
-
11
- export interface NSASectionEditCustomProps<RowType extends { id: string }, RowTypeInput = RowType> extends NSARouterMakerProps, IBaseComponentProps
12
- {
13
- isEdit: boolean;
14
- ui: {
15
- panel?: IBaseComponentProps;
16
- tab_page_edit: {
17
- ui?: NSASectionEditTabPageUIProps;
18
- editor: NSASectionEditTabPageEditorProps<RowType, RowTypeInput>;
19
- };
20
- tab_page_view?: NSASectionViewTabPageUIProps<RowType>;
21
- getChildrenBefore?: (id: string, row: RowType | null) => ReactNode;
22
- getChildrenAfter?: (id: string, row: RowType | null) => ReactNode;
23
- }
24
- onLoaded?: () => void;
25
- onRowLoaded?: (item: RowType) => void;
26
- children?: React.ReactNode;
27
- }
28
-
29
- export interface NSASectionEditProps<RowType extends { id: string }, RowTypeInput = RowType> extends NSASectionEditCustomProps<RowType, RowTypeInput>, NSARouterMakerProps
30
- {
31
- model: {
32
- id: string | null;
33
- row: RowType | null;
34
- };
35
- entity: IEntityInfo<RowType, RowTypeInput>,
36
- ctf: {
37
- enabled: boolean;
38
- fields: FieldRow[] | null;
39
- categories: CategoryRow[] | null;
40
- };
41
- deleteFieldCache: () => void;
42
- children: ReactNode;
43
- }
44
-
45
- interface NSASectionEditState<RowType>
46
- {
47
- row: RowType | null;
48
- loading: boolean;
49
- }
50
-
51
- export class NSASectionEdit<RowType extends { id: string }, RowTypeInput = RowType> extends Component<NSASectionEditProps<RowType, RowTypeInput>, NSASectionEditState<RowType>>
52
- {
53
- NSASectionViewTabPage_Ref = createRef<NSASectionViewTabPage<RowType, RowTypeInput>>();
54
- NSASectionEditTabPage_Ref = createRef<NSASectionEditTabPage<RowType, RowTypeInput>>();
55
-
56
- constructor(props: NSASectionEditProps<RowType, RowTypeInput>)
57
- {
58
- super(props);
59
-
60
- this.state = {
61
- row: this.props.model.row,
62
- loading: !this.props.model.row,
63
- };
64
-
65
- this.reload = this.reload.bind(this);
66
- this.getRow = this.getRow.bind(this);
67
- this.onApply = this.onApply.bind(this);
68
- }
69
- reload()
70
- {
71
- this.setState(() => ({ row: null, loading: true }));
72
- if (this.props.model.id)
73
- this.props.entity.server.get?.(this.props.model.id).then(row =>
74
- {
75
- this.setState(
76
- () => ({ row, loading: false }),
77
- () =>
78
- {
79
- this.props.onLoaded?.();
80
- this.props.onRowLoaded?.(row);
81
- }
82
- );
83
- }).catch(() => { });
84
- }
85
- getRow()
86
- {
87
- return this.state.row;
88
- }
89
- async onApply(onFinshied: () => void): Promise<void>
90
- {
91
- try
92
- {
93
- let Name_Pascal_Space = NamingConvention.lower_case_underscore.convert(this.props.entity.name, NamingConvention.Pascal_Case_Space);
94
-
95
- let onSuccess = (new_row: RowType, message: string) =>
96
- {
97
- this.props.notifier.onSuccess(message);
98
- let handled = false;
99
- if (this.props.entity.client.onSuccess)
100
- handled = this.props.entity.client.onSuccess(new_row);
101
- if (!handled)
102
- {
103
- let url = null;
104
- if (this.props.entity.client.getViewURL)
105
- url = this.props.entity.client.getViewURL(new_row.id);
106
- else if (this.props.entity.client.getListURL)
107
- url = this.props.entity.client.getListURL();
108
- if (url)
109
- this.props.url.redirect(url, {});
110
- }
111
- };
112
- let cur_row: RowTypeInput | null = null;
113
- if (this.NSASectionEditTabPage_Ref.current)
114
- cur_row = await this.NSASectionEditTabPage_Ref.current.getInputRow();
115
- if (cur_row)
116
- if (this.props.isEdit)
117
- {
118
- if (this.props.model.id)
119
- {
120
- if (this.props.entity.client.onUpdate)
121
- {
122
- this.props.entity.client.onUpdate(this.props.model.id, cur_row).then(new_entity =>
123
- {
124
- if (new_entity)
125
- onSuccess(new_entity, Name_Pascal_Space + " has been updated successfully");
126
- if (this.props.model.id)
127
- NSID.clearID(new IStorageLocal(), this.props.model.id);
128
- onFinshied();
129
- }).catch(onFinshied);
130
- }
131
- else if (this.props.entity.server.update)
132
- {
133
- this.props.entity.server.update(this.props.model.id, cur_row).then(new_entity =>
134
- {
135
- onSuccess(new_entity, Name_Pascal_Space + " has been updated successfully");
136
- if (this.props.model.id)
137
- NSID.clearID(new IStorageLocal(), this.props.model.id);
138
- onFinshied();
139
- }).catch(onFinshied);
140
- }
141
- else
142
- onFinshied();
143
- }
144
- else
145
- throw new Error("ID was not provided.");
146
- }
147
- else
148
- {
149
- if (this.props.entity.client.onCreate)
150
- {
151
- this.props.entity.client.onCreate(cur_row).then(new_entity =>
152
- {
153
- if (new_entity)
154
- onSuccess(new_entity, Name_Pascal_Space + " has been created successfully");
155
- onFinshied();
156
- }).catch(onFinshied);
157
- }
158
- else if (this.props.entity.server.create)
159
- {
160
- this.props.entity.server.create(cur_row).then(new_entity =>
161
- {
162
- onSuccess(new_entity, Name_Pascal_Space + " has been created successfully");;
163
- onFinshied();
164
- }).catch(onFinshied);
165
- }
166
- else
167
- onFinshied();
168
- }
169
- else
170
- onFinshied();
171
- } catch (error: any)
172
- {
173
- this.props.notifier.onError(error);
174
- onFinshied();
175
- }
176
- }
177
- override componentDidMount()
178
- {
179
- let { id, row } = this.props.model;
180
-
181
- if ((id && !row) || (id && id !== row?.id))
182
- this.reload();
183
- else
184
- this.setState(
185
- () => ({ loading: false }),
186
- () => this.props.onLoaded?.()
187
- );
188
- }
189
- override render()
190
- {
191
- return (
192
- <>
193
- <NSSection
194
- id={this.props.id}
195
- classList={[`${this.props.classList?.join(" ") ?? ""}`]}
196
- style={{ ...this.props.style }}
197
- >
198
- {
199
- !this.state.loading
200
- ?
201
- <NSPanel
202
- id={this.props.ui.panel?.id}
203
- classList={[`${this.props.ui.panel?.classList?.join(" ") ?? ""}`]}
204
- style={{ ...this.props.ui.panel?.style }}
205
- >
206
- <NSASectionEditTabPage<RowType, RowTypeInput>
207
- ref={this.NSASectionEditTabPage_Ref}
208
- {...this.props}
209
- model={{
210
- id: this.props.model.id,
211
- row: this.state.row
212
- }}
213
- editor={this.props.ui.tab_page_edit.editor}
214
- ui={this.props.ui.tab_page_edit.ui}
215
- >
216
- {this.props.children}
217
- </NSASectionEditTabPage>
218
- </NSPanel>
219
- :
220
- <NSLoading />
221
- }
222
- <NSSpace size={NSSpaceSizeType.SMALL}></NSSpace>
223
- <NSButtonBlue
224
- title="Apply"
225
- onClick={{
226
- action: (onFinished) =>
227
- {
228
- this.onApply(onFinished);
229
- }
230
- }}
231
- />
232
- </NSSection>
233
- {
234
- this.props.isEdit && (this.props.ui.tab_page_view?.enabled ?? true) && !this.state.loading &&
235
- <>
236
- <NSSpace size={NSSpaceSizeType.SMALL} />
237
- <NSLine />
238
- <NSSpace size={NSSpaceSizeType.SMALL} />
239
- {
240
- this.props.ui.getChildrenBefore &&
241
- this.props.ui.getChildrenBefore(this.props.model.id ?? "", this.state.row)
242
- }
243
- <NSASectionViewTabPage<RowType, RowTypeInput>
244
- ref={this.NSASectionViewTabPage_Ref}
245
- {...this.props}
246
- model={{
247
- id: this.props.model.id,
248
- row: this.state.row
249
- }}
250
- ui={this.props.ui.tab_page_view}
251
- />
252
- {
253
- this.props.ui.getChildrenAfter &&
254
- this.props.ui.getChildrenAfter(this.props.model.id ?? "", this.state.row)
255
- }
256
- </>
257
- }
258
- </>
259
- );
260
- }
1
+ import { IBaseComponentProps, NSID, NSLoading } from "namirasoft-site-react";
2
+ import { NSSection, NSPanel, NSButtonBlue, NSLine, NSSpace, NSSpaceSizeType } from 'namirasoft-site-react';
3
+ import { NSARouterMakerProps } from "../NSARouterMakerProps";
4
+ import { Component, createRef, ReactNode } from "react";
5
+ import { IEntityInfo } from "../IEntityInfo";
6
+ import { IStorageLocal, NamingConvention } from "namirasoft-core";
7
+ import { NSASectionViewTabPage, NSASectionViewTabPageUIProps } from "./NSASectionViewTabPage";
8
+ import { NSASectionEditTabPage, NSASectionEditTabPageEditorProps, NSASectionEditTabPageUIProps } from "./NSASectionEditTabPage";
9
+ import { CategoryRow, FieldRow } from "namirasoft-field";
10
+ import { NSANavigationGuard } from "../components/NSANavigationGuard";
11
+
12
+ export interface NSASectionEditCustomProps<RowType extends { id: string }, RowTypeInput = RowType> extends NSARouterMakerProps, IBaseComponentProps
13
+ {
14
+ isEdit: boolean;
15
+ ui: {
16
+ panel?: IBaseComponentProps;
17
+ tab_page_edit: {
18
+ ui?: NSASectionEditTabPageUIProps;
19
+ editor: NSASectionEditTabPageEditorProps<RowType, RowTypeInput>;
20
+ };
21
+ tab_page_view?: NSASectionViewTabPageUIProps<RowType>;
22
+ getChildrenBefore?: (id: string, row: RowType | null) => ReactNode;
23
+ getChildrenAfter?: (id: string, row: RowType | null) => ReactNode;
24
+ }
25
+ onLoaded?: () => void;
26
+ onRowLoaded?: (item: RowType) => void;
27
+ children?: React.ReactNode;
28
+ }
29
+
30
+ export interface NSASectionEditProps<RowType extends { id: string }, RowTypeInput = RowType> extends NSASectionEditCustomProps<RowType, RowTypeInput>, NSARouterMakerProps
31
+ {
32
+ model: {
33
+ id: string | null;
34
+ row: RowType | null;
35
+ };
36
+ entity: IEntityInfo<RowType, RowTypeInput>,
37
+ ctf: {
38
+ enabled: boolean;
39
+ fields: FieldRow[] | null;
40
+ categories: CategoryRow[] | null;
41
+ };
42
+ deleteFieldCache: () => void;
43
+ children: ReactNode;
44
+ }
45
+
46
+ interface NSASectionEditState<RowType>
47
+ {
48
+ row: RowType | null;
49
+ loading: boolean;
50
+ isDirty: boolean;
51
+ }
52
+
53
+ export class NSASectionEdit<RowType extends { id: string }, RowTypeInput = RowType> extends Component<NSASectionEditProps<RowType, RowTypeInput>, NSASectionEditState<RowType>>
54
+ {
55
+ NSASectionViewTabPage_Ref = createRef<NSASectionViewTabPage<RowType, RowTypeInput>>();
56
+ NSASectionEditTabPage_Ref = createRef<NSASectionEditTabPage<RowType, RowTypeInput>>();
57
+
58
+ constructor(props: NSASectionEditProps<RowType, RowTypeInput>)
59
+ {
60
+ super(props);
61
+
62
+ this.state = {
63
+ row: this.props.model.row,
64
+ loading: !this.props.model.row,
65
+ isDirty: false,
66
+ };
67
+
68
+ this.reload = this.reload.bind(this);
69
+ this.getRow = this.getRow.bind(this);
70
+ this.onApply = this.onApply.bind(this);
71
+ this.markDirty = this.markDirty.bind(this);
72
+ }
73
+ private markDirty()
74
+ {
75
+ if (!this.state.isDirty)
76
+ this.setState(prev => ({ ...prev, isDirty: true }));
77
+ }
78
+ reload()
79
+ {
80
+ this.setState(() => ({ row: null, loading: true }));
81
+ if (this.props.model.id)
82
+ this.props.entity.server.get?.(this.props.model.id).then(row =>
83
+ {
84
+ this.setState(
85
+ () => ({ row, loading: false, isDirty: false }),
86
+ () =>
87
+ {
88
+ this.props.onLoaded?.();
89
+ this.props.onRowLoaded?.(row);
90
+ }
91
+ );
92
+ }).catch(() => { });
93
+ }
94
+ getRow()
95
+ {
96
+ return this.state.row;
97
+ }
98
+ async onApply(onFinshied: () => void): Promise<void>
99
+ {
100
+ try
101
+ {
102
+ let Name_Pascal_Space = NamingConvention.lower_case_underscore.convert(this.props.entity.name, NamingConvention.Pascal_Case_Space);
103
+
104
+ let onSuccess = (new_row: RowType, message: string) =>
105
+ {
106
+ this.props.notifier.onSuccess(message);
107
+ // Clear the dirty flag BEFORE redirecting so the navigation guard does not
108
+ // block this intentional, post-save redirect. The redirect runs in the
109
+ // setState callback, after the guard has re-rendered with when=false.
110
+ this.setState(prev => ({ ...prev, isDirty: false }), () =>
111
+ {
112
+ let handled = false;
113
+ if (this.props.entity.client.onSuccess)
114
+ handled = this.props.entity.client.onSuccess(new_row);
115
+ if (!handled)
116
+ {
117
+ let url = null;
118
+ if (this.props.entity.client.getViewURL)
119
+ url = this.props.entity.client.getViewURL(new_row.id);
120
+ else if (this.props.entity.client.getListURL)
121
+ url = this.props.entity.client.getListURL();
122
+ if (url)
123
+ this.props.url.redirect(url, {});
124
+ }
125
+ });
126
+ };
127
+ let cur_row: RowTypeInput | null = null;
128
+ if (this.NSASectionEditTabPage_Ref.current)
129
+ cur_row = await this.NSASectionEditTabPage_Ref.current.getInputRow();
130
+ if (cur_row)
131
+ if (this.props.isEdit)
132
+ {
133
+ if (this.props.model.id)
134
+ {
135
+ if (this.props.entity.client.onUpdate)
136
+ {
137
+ this.props.entity.client.onUpdate(this.props.model.id, cur_row).then(new_entity =>
138
+ {
139
+ if (new_entity)
140
+ onSuccess(new_entity, Name_Pascal_Space + " has been updated successfully");
141
+ if (this.props.model.id)
142
+ NSID.clearID(new IStorageLocal(), this.props.model.id);
143
+ onFinshied();
144
+ }).catch(onFinshied);
145
+ }
146
+ else if (this.props.entity.server.update)
147
+ {
148
+ this.props.entity.server.update(this.props.model.id, cur_row).then(new_entity =>
149
+ {
150
+ onSuccess(new_entity, Name_Pascal_Space + " has been updated successfully");
151
+ if (this.props.model.id)
152
+ NSID.clearID(new IStorageLocal(), this.props.model.id);
153
+ onFinshied();
154
+ }).catch(onFinshied);
155
+ }
156
+ else
157
+ onFinshied();
158
+ }
159
+ else
160
+ throw new Error("ID was not provided.");
161
+ }
162
+ else
163
+ {
164
+ if (this.props.entity.client.onCreate)
165
+ {
166
+ this.props.entity.client.onCreate(cur_row).then(new_entity =>
167
+ {
168
+ if (new_entity)
169
+ onSuccess(new_entity, Name_Pascal_Space + " has been created successfully");
170
+ onFinshied();
171
+ }).catch(onFinshied);
172
+ }
173
+ else if (this.props.entity.server.create)
174
+ {
175
+ this.props.entity.server.create(cur_row).then(new_entity =>
176
+ {
177
+ onSuccess(new_entity, Name_Pascal_Space + " has been created successfully");;
178
+ onFinshied();
179
+ }).catch(onFinshied);
180
+ }
181
+ else
182
+ onFinshied();
183
+ }
184
+ else
185
+ onFinshied();
186
+ } catch (error: any)
187
+ {
188
+ this.props.notifier.onError(error);
189
+ onFinshied();
190
+ }
191
+ }
192
+ override componentDidMount()
193
+ {
194
+ let { id, row } = this.props.model;
195
+
196
+ if ((id && !row) || (id && id !== row?.id))
197
+ this.reload();
198
+ else
199
+ this.setState(
200
+ () => ({ loading: false, isDirty: false }),
201
+ () => this.props.onLoaded?.()
202
+ );
203
+ }
204
+ override render()
205
+ {
206
+ return (
207
+ <>
208
+ <NSANavigationGuard when={this.state.isDirty} />
209
+ <NSSection
210
+ id={this.props.id}
211
+ classList={[`${this.props.classList?.join(" ") ?? ""}`]}
212
+ style={{ ...this.props.style }}
213
+ >
214
+ {
215
+ !this.state.loading
216
+ ?
217
+ <NSPanel
218
+ id={this.props.ui.panel?.id}
219
+ classList={[`${this.props.ui.panel?.classList?.join(" ") ?? ""}`]}
220
+ style={{ ...this.props.ui.panel?.style }}
221
+ >
222
+ {/* Any user edit inside the form (input/change bubbling) marks the page dirty. */}
223
+ <div onInput={this.markDirty} onChange={this.markDirty}>
224
+ <NSASectionEditTabPage<RowType, RowTypeInput>
225
+ ref={this.NSASectionEditTabPage_Ref}
226
+ {...this.props}
227
+ model={{
228
+ id: this.props.model.id,
229
+ row: this.state.row
230
+ }}
231
+ editor={this.props.ui.tab_page_edit.editor}
232
+ ui={this.props.ui.tab_page_edit.ui}
233
+ >
234
+ {this.props.children}
235
+ </NSASectionEditTabPage>
236
+ </div>
237
+ </NSPanel>
238
+ :
239
+ <NSLoading />
240
+ }
241
+ <NSSpace size={NSSpaceSizeType.SMALL}></NSSpace>
242
+ <NSButtonBlue
243
+ title="Apply"
244
+ onClick={{
245
+ action: (onFinished) =>
246
+ {
247
+ this.onApply(onFinished);
248
+ }
249
+ }}
250
+ />
251
+ </NSSection>
252
+ {
253
+ this.props.isEdit && (this.props.ui.tab_page_view?.enabled ?? true) && !this.state.loading &&
254
+ <>
255
+ <NSSpace size={NSSpaceSizeType.SMALL} />
256
+ <NSLine />
257
+ <NSSpace size={NSSpaceSizeType.SMALL} />
258
+ {
259
+ this.props.ui.getChildrenBefore &&
260
+ this.props.ui.getChildrenBefore(this.props.model.id ?? "", this.state.row)
261
+ }
262
+ <NSASectionViewTabPage<RowType, RowTypeInput>
263
+ ref={this.NSASectionViewTabPage_Ref}
264
+ {...this.props}
265
+ model={{
266
+ id: this.props.model.id,
267
+ row: this.state.row
268
+ }}
269
+ ui={this.props.ui.tab_page_view}
270
+ />
271
+ {
272
+ this.props.ui.getChildrenAfter &&
273
+ this.props.ui.getChildrenAfter(this.props.model.id ?? "", this.state.row)
274
+ }
275
+ </>
276
+ }
277
+ </>
278
+ );
279
+ }
261
280
  }
@@ -1,5 +1,5 @@
1
- @media screen and (min-width: 768px) {
2
- .nsa_section_edit_tab_page {
3
- min-width: 560px;
4
- }
1
+ @media screen and (min-width: 768px) {
2
+ .nsa_section_edit_tab_page {
3
+ min-width: 560px;
4
+ }
5
5
  }