namirasoft-account-react 1.5.2 → 1.5.4
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/SKILLS.md +5 -5
- package/dist/FieldCacheService.d.ts +6 -0
- package/dist/FieldCacheService.js +40 -0
- package/dist/FieldCacheService.js.map +1 -0
- package/dist/components/{NSBoxSecret.d.ts → NSABoxSecret.d.ts} +4 -4
- package/dist/components/{NSBoxSecret.js → NSABoxSecret.js} +3 -3
- package/dist/components/NSABoxSecret.js.map +1 -0
- package/dist/components/NSATable.d.ts +2 -3
- package/dist/components/NSATable.js +16 -15
- package/dist/components/NSATable.js.map +1 -1
- package/dist/components/NSFBoxCategoryScope.d.ts +16 -0
- package/dist/components/NSFBoxCategoryScope.js +34 -0
- package/dist/components/NSFBoxCategoryScope.js.map +1 -0
- package/dist/components/NSFBoxField.d.ts +15 -0
- package/dist/components/NSFBoxField.js +16 -0
- package/dist/components/NSFBoxField.js.map +1 -0
- package/dist/components/NSFBoxSlot.d.ts +22 -0
- package/dist/components/NSFBoxSlot.js +49 -0
- package/dist/components/NSFBoxSlot.js.map +1 -0
- package/dist/components/NSFBoxWrapper.d.ts +15 -0
- package/dist/components/NSFBoxWrapper.js +44 -0
- package/dist/components/NSFBoxWrapper.js.map +1 -0
- package/dist/layouts/NSALayout.d.ts +3 -4
- package/dist/layouts/NSALayout.js +14 -52
- package/dist/layouts/NSALayout.js.map +1 -1
- package/dist/layouts/NSASectionEdit.d.ts +4 -5
- package/dist/layouts/NSASectionEdit.js +4 -5
- package/dist/layouts/NSASectionEdit.js.map +1 -1
- package/dist/layouts/NSASectionEditTabPage.d.ts +3 -5
- package/dist/layouts/NSASectionEditTabPage.js +60 -52
- package/dist/layouts/NSASectionEditTabPage.js.map +1 -1
- package/dist/layouts/NSASectionList.d.ts +2 -3
- package/dist/layouts/NSASectionList.js.map +1 -1
- package/dist/layouts/NSASectionView.d.ts +2 -3
- package/dist/layouts/NSASectionView.js.map +1 -1
- package/dist/layouts/NSASectionViewTabPage.d.ts +2 -3
- package/dist/layouts/NSASectionViewTabPage.js +45 -53
- package/dist/layouts/NSASectionViewTabPage.js.map +1 -1
- package/dist/main.d.ts +1 -1
- package/dist/main.js +1 -1
- package/dist/main.js.map +1 -1
- package/package.json +6 -5
- package/src/FieldCacheService.ts +39 -0
- package/src/components/{NSBoxSecret.tsx → NSABoxSecret.tsx} +6 -5
- package/src/components/NSATable.tsx +13 -14
- package/src/components/NSFBoxCategoryScope.tsx +53 -0
- package/src/components/NSFBoxField.tsx +38 -0
- package/src/components/NSFBoxSlot.tsx +72 -0
- package/src/components/NSFBoxWrapper.tsx +70 -0
- package/src/layouts/NSALayout.tsx +17 -68
- package/src/layouts/NSASectionEdit.tsx +9 -10
- package/src/layouts/NSASectionEditTabPage.tsx +79 -72
- package/src/layouts/NSASectionList.tsx +2 -3
- package/src/layouts/NSASectionView.tsx +2 -3
- package/src/layouts/NSASectionViewTabPage.tsx +52 -71
- package/src/main.ts +1 -1
- package/dist/components/NSBoxSecret.js.map +0 -1
- /package/dist/components/{NSBoxSecret.module.css → NSABoxSecret.module.css} +0 -0
- /package/src/components/{NSBoxSecret.module.css → NSABoxSecret.module.css} +0 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { FieldRow, SlotRow } from "namirasoft-field";
|
|
2
|
+
import { NSBoxDynamic } from "namirasoft-site-react";
|
|
3
|
+
import { Component, createRef } from "react";
|
|
4
|
+
import { NSFBoxSlot } from "./NSFBoxSlot";
|
|
5
|
+
|
|
6
|
+
export interface NSFBoxFieldProps
|
|
7
|
+
{
|
|
8
|
+
slot: SlotRow;
|
|
9
|
+
field: FieldRow;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
interface NSFBoxFieldState
|
|
13
|
+
{
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export class NSFBoxField extends Component<NSFBoxFieldProps, NSFBoxFieldState>
|
|
17
|
+
{
|
|
18
|
+
NSBoxDynamic_Ref = createRef<NSBoxDynamic>();
|
|
19
|
+
|
|
20
|
+
constructor(props: NSFBoxFieldProps)
|
|
21
|
+
{
|
|
22
|
+
super(props);
|
|
23
|
+
|
|
24
|
+
this.state = {};
|
|
25
|
+
}
|
|
26
|
+
override render()
|
|
27
|
+
{
|
|
28
|
+
return <NSBoxDynamic
|
|
29
|
+
key={`NSFBoxField_NSBoxDynamic_${this.props.field.id}`}
|
|
30
|
+
ref={this.NSBoxDynamic_Ref}
|
|
31
|
+
name={this.props.slot.id}
|
|
32
|
+
title={this.props.slot.name}
|
|
33
|
+
variable={this.props.field.type}
|
|
34
|
+
info={{ text: this.props.slot.description ?? this.props.field.description ?? "" }}
|
|
35
|
+
style={{ width: NSFBoxSlot.getSize(this.props.slot.size) }}
|
|
36
|
+
/>;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { CategoryScopeRow, FieldRow, SlotEntityType, SlotRow, SlotSize } from "namirasoft-field";
|
|
2
|
+
import { NSBox } from "namirasoft-site-react";
|
|
3
|
+
import { Component, createRef } from "react";
|
|
4
|
+
import { NSARouterMakerProps } from "../NSARouterMakerProps";
|
|
5
|
+
import { NSFBoxCategoryScope } from "./NSFBoxCategoryScope";
|
|
6
|
+
import { NSFBoxField } from "./NSFBoxField";
|
|
7
|
+
|
|
8
|
+
export interface NSFBoxSlotProps extends NSARouterMakerProps
|
|
9
|
+
{
|
|
10
|
+
slot: SlotRow;
|
|
11
|
+
getField: () => FieldRow;
|
|
12
|
+
getCategoryScope: () => CategoryScopeRow;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
interface NSFBoxSlotState
|
|
16
|
+
{
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export class NSFBoxSlot extends Component<NSFBoxSlotProps, NSFBoxSlotState>
|
|
20
|
+
{
|
|
21
|
+
static getSize(size: SlotSize)
|
|
22
|
+
{
|
|
23
|
+
if (size === SlotSize.Small)
|
|
24
|
+
return NSBox.width.one;
|
|
25
|
+
if (size === SlotSize.Medium)
|
|
26
|
+
return NSBox.width.double;
|
|
27
|
+
if (size === SlotSize.Big)
|
|
28
|
+
return NSBox.width.triple;
|
|
29
|
+
return "";
|
|
30
|
+
}
|
|
31
|
+
NSFBoxCategoryScope_Ref = createRef<NSFBoxCategoryScope>();
|
|
32
|
+
NSFBoxField_Ref = createRef<NSFBoxField>();
|
|
33
|
+
constructor(props: NSFBoxSlotProps)
|
|
34
|
+
{
|
|
35
|
+
super(props);
|
|
36
|
+
|
|
37
|
+
this.state = {};
|
|
38
|
+
|
|
39
|
+
this.getValue = this.getValue.bind(this);
|
|
40
|
+
this.setValue = this.setValue.bind(this);
|
|
41
|
+
}
|
|
42
|
+
getValue(checkError?: boolean)
|
|
43
|
+
{
|
|
44
|
+
if (this.props.slot.entity_type === SlotEntityType.CategoryScope)
|
|
45
|
+
return this.NSFBoxCategoryScope_Ref.current?.NSBoxEntity_Ref.current?.getValue(checkError);
|
|
46
|
+
if (this.props.slot.entity_type === SlotEntityType.Field)
|
|
47
|
+
return this.NSFBoxField_Ref.current?.NSBoxDynamic_Ref.current?.getValue(checkError);
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
setValue(value: any | null, callback: () => void)
|
|
51
|
+
{
|
|
52
|
+
if (this.props.slot.entity_type === SlotEntityType.CategoryScope)
|
|
53
|
+
return this.NSFBoxCategoryScope_Ref.current?.NSBoxEntity_Ref.current?.setValue(value, callback);
|
|
54
|
+
if (this.props.slot.entity_type === SlotEntityType.Field)
|
|
55
|
+
return this.NSFBoxField_Ref.current?.NSBoxDynamic_Ref.current?.setValue(value, callback);
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
override render()
|
|
59
|
+
{
|
|
60
|
+
if (this.props.slot.entity_type === SlotEntityType.CategoryScope)
|
|
61
|
+
return <NSFBoxCategoryScope
|
|
62
|
+
{...this.props}
|
|
63
|
+
category_scope={this.props.getCategoryScope()}
|
|
64
|
+
/>;
|
|
65
|
+
if (this.props.slot.entity_type === SlotEntityType.Field)
|
|
66
|
+
return <NSFBoxField
|
|
67
|
+
{...this.props}
|
|
68
|
+
field={this.props.getField()}
|
|
69
|
+
/>;
|
|
70
|
+
return <></>;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { SlotPositionSide, SlotRow } from "namirasoft-field";
|
|
2
|
+
import { Children, cloneElement, Component, isValidElement, ReactNode } from "react";
|
|
3
|
+
|
|
4
|
+
export interface NSFBoxWrapperProps
|
|
5
|
+
{
|
|
6
|
+
slots: SlotRow[];
|
|
7
|
+
renderSlot: (slot: SlotRow) => ReactNode;
|
|
8
|
+
children?: ReactNode;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
interface NSFBoxWrapperState
|
|
12
|
+
{
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export class NSFBoxWrapper extends Component<NSFBoxWrapperProps, NSFBoxWrapperState>
|
|
16
|
+
{
|
|
17
|
+
constructor(props: NSFBoxWrapperProps)
|
|
18
|
+
{
|
|
19
|
+
super(props);
|
|
20
|
+
|
|
21
|
+
this.state = {};
|
|
22
|
+
|
|
23
|
+
this.inject = this.inject.bind(this);
|
|
24
|
+
}
|
|
25
|
+
private inject(nodes: ReactNode, used: Set<string>): ReactNode
|
|
26
|
+
{
|
|
27
|
+
return Children.map(nodes, node =>
|
|
28
|
+
{
|
|
29
|
+
if (!isValidElement(node))
|
|
30
|
+
return node;
|
|
31
|
+
|
|
32
|
+
let title = (node.props as any)?.title;
|
|
33
|
+
|
|
34
|
+
let before: ReactNode[] = [];
|
|
35
|
+
let after: ReactNode[] = [];
|
|
36
|
+
if (typeof title === "string")
|
|
37
|
+
for (let slot of this.props.slots)
|
|
38
|
+
{
|
|
39
|
+
if (used.has(slot.id))
|
|
40
|
+
continue;
|
|
41
|
+
if (slot.position_target === title)
|
|
42
|
+
{
|
|
43
|
+
used.add(slot.id);
|
|
44
|
+
if (slot.position_side === SlotPositionSide.Before)
|
|
45
|
+
before.push(this.props.renderSlot(slot));
|
|
46
|
+
else
|
|
47
|
+
after.push(this.props.renderSlot(slot));
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
let children = (node.props as any)?.children;
|
|
52
|
+
let element = children !== undefined
|
|
53
|
+
? cloneElement(node, undefined, this.inject(children, used))
|
|
54
|
+
: node;
|
|
55
|
+
|
|
56
|
+
return <>{before}{element}{after}</>;
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
override render()
|
|
60
|
+
{
|
|
61
|
+
let used = new Set<string>();
|
|
62
|
+
let content = this.inject(this.props.children, used);
|
|
63
|
+
let leftovers = this.props.slots.filter(slot => !used.has(slot.id));
|
|
64
|
+
|
|
65
|
+
return <>
|
|
66
|
+
{content}
|
|
67
|
+
{leftovers.map(slot => this.props.renderSlot(slot))}
|
|
68
|
+
</>;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { NamirasoftAccountClient } from 'namirasoft-account-client';
|
|
2
2
|
import { ProductFullRow } from 'namirasoft-api-product';
|
|
3
|
-
import { CacheService,
|
|
4
|
-
import {
|
|
3
|
+
import { CacheService, EnvService, IStorageLocal, NamingConvention } from 'namirasoft-core';
|
|
4
|
+
import { EntityResolveResponseRow } from 'namirasoft-field';
|
|
5
5
|
import { NamirasoftMessageServer } from 'namirasoft-message';
|
|
6
6
|
import { NamirasoftMap } from 'namirasoft-site-map';
|
|
7
7
|
import { IBackgroundProps, IBaseComponentProps, IHeaderIconProps, IHeaderRightProps, NSBarActionProps, NSBarAlertProps, NSBarTitleProps, NSDialogDelete, NSLayout, NSLoading, ProductCacheService } from 'namirasoft-site-react';
|
|
@@ -15,6 +15,7 @@ import { NSAProductListDialog } from '../components/NSAProductListDialog';
|
|
|
15
15
|
import { NSATaskBar } from '../components/NSATaskBar';
|
|
16
16
|
import { NSAUserDialog } from '../components/NSAUserDialog';
|
|
17
17
|
import { NSAWorkspaceListDialog } from '../components/NSAWorkspaceListDialog';
|
|
18
|
+
import { FieldCacheService } from '../FieldCacheService';
|
|
18
19
|
import { IEntityInfo } from '../IEntityInfo';
|
|
19
20
|
import { NSACacheService } from '../NSACacheService';
|
|
20
21
|
import { NSARouterMakerProps } from '../NSARouterMakerProps';
|
|
@@ -110,8 +111,7 @@ interface NSALayoutState
|
|
|
110
111
|
showUserDialog: boolean;
|
|
111
112
|
showMasterMenu: boolean;
|
|
112
113
|
ctf_enabled: boolean;
|
|
113
|
-
|
|
114
|
-
ctf_fields: FieldRow[] | null;
|
|
114
|
+
ctf_rows: EntityResolveResponseRow | null;
|
|
115
115
|
}
|
|
116
116
|
|
|
117
117
|
export class NSALayout<RowType extends { id: string }, RowTypeInput = RowType> extends Component<NSALayoutProps<RowType, RowTypeInput>, NSALayoutState>
|
|
@@ -121,10 +121,7 @@ export class NSALayout<RowType extends { id: string }, RowTypeInput = RowType> e
|
|
|
121
121
|
private hasCFT: boolean;
|
|
122
122
|
private isLoggedIn: boolean;
|
|
123
123
|
private cache_product: CacheService<ProductFullRow>;
|
|
124
|
-
private
|
|
125
|
-
ctf_categories: CategoryRow[] | null;
|
|
126
|
-
ctf_fields: FieldRow[] | null;
|
|
127
|
-
}>;
|
|
124
|
+
private cache_field: CacheService<EntityResolveResponseRow>;
|
|
128
125
|
private cache_message: CacheService<number>;
|
|
129
126
|
private cache_master_menu: CacheService<{ open: boolean }>;
|
|
130
127
|
NSASectionList_Ref = createRef<NSASectionList<RowType, RowTypeInput>>();
|
|
@@ -154,52 +151,8 @@ export class NSALayout<RowType extends { id: string }, RowTypeInput = RowType> e
|
|
|
154
151
|
this.cache_product = ProductCacheService.get(this.props.product_id, console.error);
|
|
155
152
|
|
|
156
153
|
// Cache Fields
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
let key_field = `ns-fields-${user_id}-${props.pages?.entity?.product_id ?? "*"}-${props.pages?.entity?.name ?? "*"}`;
|
|
160
|
-
this.cache_fields = new CacheService<{
|
|
161
|
-
ctf_categories: CategoryRow[] | null;
|
|
162
|
-
ctf_fields: FieldRow[] | null;
|
|
163
|
-
}>(key_field, new IStorageLocal(), 24 * 60, async () =>
|
|
164
|
-
{
|
|
165
|
-
let service = new CookieService(document.cookie, "ns-field-version");
|
|
166
|
-
return (this.props.account?.token_manager?.getUserData(x => x.id, "") ?? "") + "" + service.getString();
|
|
167
|
-
}, async () =>
|
|
168
|
-
{
|
|
169
|
-
let REACT_APP_BASE_URL_FIELD = new EnvService("REACT_APP_BASE_URL_FIELD", true).getString();
|
|
170
|
-
let server = new NamirasoftFieldServer(REACT_APP_BASE_URL_FIELD, props.account.token_manager, props.notifier.onError);
|
|
171
|
-
let ans: {
|
|
172
|
-
ctf_categories: CategoryRow[] | null;
|
|
173
|
-
ctf_fields: FieldRow[] | null;
|
|
174
|
-
} = { ctf_categories: null, ctf_fields: null };
|
|
175
|
-
if (this.props.pages)
|
|
176
|
-
{
|
|
177
|
-
let meta = new NamirasoftFieldMetaDatabase();
|
|
178
|
-
try
|
|
179
|
-
{
|
|
180
|
-
let filters: FilterItem[] = [];
|
|
181
|
-
filters.push(new FilterItem(meta.tables.category, meta.tables.category.columns.product_id, false, FilterItemOperator.all.equals, this.props.pages.entity.product_id));
|
|
182
|
-
filters.push(new FilterItem(meta.tables.category, meta.tables.category.columns.entity, false, FilterItemOperator.all.equals, this.props.pages.entity.name));
|
|
183
|
-
let res = await server.category.List(filters, null, null, [], null);
|
|
184
|
-
ans.ctf_categories = res.rows;
|
|
185
|
-
} catch (error)
|
|
186
|
-
{
|
|
187
|
-
ans.ctf_categories = [];
|
|
188
|
-
}
|
|
189
|
-
try
|
|
190
|
-
{
|
|
191
|
-
let filters: FilterItem[] = [];
|
|
192
|
-
filters.push(new FilterItem(meta.tables.field, meta.tables.field.columns.product_id, false, FilterItemOperator.all.equals, this.props.pages.entity.product_id));
|
|
193
|
-
filters.push(new FilterItem(meta.tables.field, meta.tables.field.columns.entity, false, FilterItemOperator.all.equals, this.props.pages.entity.name));
|
|
194
|
-
let res = await server.field.List(filters, null, null, [], null);
|
|
195
|
-
ans.ctf_fields = res.rows;
|
|
196
|
-
} catch (error)
|
|
197
|
-
{
|
|
198
|
-
ans.ctf_fields = [];
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
return ans;
|
|
202
|
-
});
|
|
154
|
+
this.cache_field = FieldCacheService.get(this.props.account.token_manager, this.props.pages?.entity.product_id, this.props.pages?.entity.name, props.notifier.onError)
|
|
155
|
+
|
|
203
156
|
// Cache Message
|
|
204
157
|
this.cache_message = new CacheService<number>("ns-messsage-count", new IStorageLocal(), 15, async () => "1.0.0", async () =>
|
|
205
158
|
{
|
|
@@ -228,8 +181,7 @@ export class NSALayout<RowType extends { id: string }, RowTypeInput = RowType> e
|
|
|
228
181
|
showUserDialog: false,
|
|
229
182
|
showMasterMenu: false,
|
|
230
183
|
ctf_enabled: this.hasCFT,
|
|
231
|
-
|
|
232
|
-
ctf_categories: null,
|
|
184
|
+
ctf_rows: null
|
|
233
185
|
};
|
|
234
186
|
}
|
|
235
187
|
public reloadMessageCount(force: boolean)
|
|
@@ -299,9 +251,9 @@ export class NSALayout<RowType extends { id: string }, RowTypeInput = RowType> e
|
|
|
299
251
|
if (this.hasCFT)
|
|
300
252
|
if (this.props.pages?.entity)
|
|
301
253
|
{
|
|
302
|
-
this.
|
|
254
|
+
this.cache_field.get().then(res =>
|
|
303
255
|
{
|
|
304
|
-
this.setState(prev => { return { ...prev,
|
|
256
|
+
this.setState(prev => { return { ...prev, ctf_rows: res } });
|
|
305
257
|
});
|
|
306
258
|
}
|
|
307
259
|
|
|
@@ -575,10 +527,9 @@ export class NSALayout<RowType extends { id: string }, RowTypeInput = RowType> e
|
|
|
575
527
|
}}
|
|
576
528
|
ctf={{
|
|
577
529
|
enabled: this.state.ctf_enabled,
|
|
578
|
-
|
|
579
|
-
fields: this.state.ctf_fields
|
|
530
|
+
rows: this.state.ctf_rows
|
|
580
531
|
}}
|
|
581
|
-
deleteFieldCache={() => { this.
|
|
532
|
+
deleteFieldCache={() => { this.cache_field.del(); }}
|
|
582
533
|
>
|
|
583
534
|
{this.props.children}
|
|
584
535
|
</NSASectionList>
|
|
@@ -597,10 +548,9 @@ export class NSALayout<RowType extends { id: string }, RowTypeInput = RowType> e
|
|
|
597
548
|
entity={this.props.pages.entity}
|
|
598
549
|
ctf={{
|
|
599
550
|
enabled: this.state.ctf_enabled,
|
|
600
|
-
|
|
601
|
-
fields: this.state.ctf_fields
|
|
551
|
+
rows: this.state.ctf_rows
|
|
602
552
|
}}
|
|
603
|
-
deleteFieldCache={() => { this.
|
|
553
|
+
deleteFieldCache={() => { this.cache_field.del(); }}
|
|
604
554
|
onRowLoaded={(row) =>
|
|
605
555
|
{
|
|
606
556
|
this.setState(prev => ({ ...prev }), () =>
|
|
@@ -627,10 +577,9 @@ export class NSALayout<RowType extends { id: string }, RowTypeInput = RowType> e
|
|
|
627
577
|
entity={this.props.pages.entity}
|
|
628
578
|
ctf={{
|
|
629
579
|
enabled: this.state.ctf_enabled,
|
|
630
|
-
|
|
631
|
-
fields: this.state.ctf_fields
|
|
580
|
+
rows: this.state.ctf_rows
|
|
632
581
|
}}
|
|
633
|
-
deleteFieldCache={() => { this.
|
|
582
|
+
deleteFieldCache={() => { this.cache_field.del(); }}
|
|
634
583
|
onRowLoaded={(row) =>
|
|
635
584
|
{
|
|
636
585
|
this.setState(prev => ({ ...prev }), () =>
|
|
@@ -767,7 +716,7 @@ export class NSALayout<RowType extends { id: string }, RowTypeInput = RowType> e
|
|
|
767
716
|
<></>
|
|
768
717
|
</NSDialogDelete>}
|
|
769
718
|
{
|
|
770
|
-
(!this.state.ctf_enabled || (this.state.
|
|
719
|
+
(!this.state.ctf_enabled || (this.state.ctf_rows))
|
|
771
720
|
?
|
|
772
721
|
content
|
|
773
722
|
:
|
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { IStorageLocal, NamingConvention } from "namirasoft-core";
|
|
2
|
+
import { EntityResolveResponseRow } from "namirasoft-field";
|
|
3
|
+
import { IBaseComponentProps, NSButtonBlue, NSID, NSLine, NSLoading, NSPanel, NSSection, NSSpace, NSSpaceSizeType } from "namirasoft-site-react";
|
|
4
4
|
import { Component, createRef, FormHTMLAttributes, ReactNode } from "react";
|
|
5
|
+
import { NSANavigationGuard } from "../components/NSANavigationGuard";
|
|
5
6
|
import { IEntityInfo } from "../IEntityInfo";
|
|
6
|
-
import {
|
|
7
|
-
import { NSASectionViewTabPage, NSASectionViewTabPageUIProps } from "./NSASectionViewTabPage";
|
|
7
|
+
import { NSARouterMakerProps } from "../NSARouterMakerProps";
|
|
8
8
|
import { NSASectionEditTabPage, NSASectionEditTabPageEditorProps, NSASectionEditTabPageUIProps } from "./NSASectionEditTabPage";
|
|
9
|
-
import {
|
|
10
|
-
import { NSANavigationGuard } from "../components/NSANavigationGuard";
|
|
9
|
+
import { NSASectionViewTabPage, NSASectionViewTabPageUIProps } from "./NSASectionViewTabPage";
|
|
11
10
|
|
|
12
11
|
export interface NSASectionEditCustomProps<RowType extends { id: string }, RowTypeInput = RowType> extends NSARouterMakerProps, IBaseComponentProps
|
|
13
12
|
{
|
|
@@ -37,8 +36,7 @@ export interface NSASectionEditProps<RowType extends { id: string }, RowTypeInpu
|
|
|
37
36
|
entity: IEntityInfo<RowType, RowTypeInput>,
|
|
38
37
|
ctf: {
|
|
39
38
|
enabled: boolean;
|
|
40
|
-
|
|
41
|
-
categories: CategoryRow[] | null;
|
|
39
|
+
rows: EntityResolveResponseRow | null;
|
|
42
40
|
};
|
|
43
41
|
deleteFieldCache: () => void;
|
|
44
42
|
children: ReactNode;
|
|
@@ -221,7 +219,8 @@ export class NSASectionEdit<RowType extends { id: string }, RowTypeInput = RowTy
|
|
|
221
219
|
{...this.props.ui.form}
|
|
222
220
|
onInput={this.markDirty}
|
|
223
221
|
onChange={this.markDirty}
|
|
224
|
-
onSubmit={(e) =>
|
|
222
|
+
onSubmit={(e) =>
|
|
223
|
+
{
|
|
225
224
|
e.preventDefault()
|
|
226
225
|
}}
|
|
227
226
|
>
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { IBaseComponentProps,
|
|
3
|
-
import { Component, createRef, ReactNode } from "react";
|
|
1
|
+
import { EntityCategoryInputRow, EntityFieldInputRow, EntityResolveResponseRow, EntityTagInputRow, SlotEntityType, SlotRow } from "namirasoft-field";
|
|
2
|
+
import { IBaseComponentProps, NSColumn, NSRepeaterNSTag, NSRow, NSTabPage, NSTabPageTab } from "namirasoft-site-react";
|
|
3
|
+
import { Component, createRef, ReactNode, RefObject } from "react";
|
|
4
|
+
import { NSFBoxSlot } from "../components/NSFBoxSlot";
|
|
5
|
+
import { NSFBoxWrapper } from "../components/NSFBoxWrapper";
|
|
4
6
|
import { CTFRow } from "../CTFRow";
|
|
5
7
|
import { IEntityInfo } from "../IEntityInfo";
|
|
6
8
|
import { NSARouterMakerProps } from "../NSARouterMakerProps";
|
|
@@ -32,8 +34,7 @@ export interface NSASectionEditTabPageProps<RowType extends { id: string }, RowT
|
|
|
32
34
|
entity: IEntityInfo<RowType & { id: string }, RowTypeInput>;
|
|
33
35
|
ctf: {
|
|
34
36
|
enabled: boolean;
|
|
35
|
-
|
|
36
|
-
categories: CategoryRow[] | null;
|
|
37
|
+
rows: EntityResolveResponseRow | null;
|
|
37
38
|
}
|
|
38
39
|
model: {
|
|
39
40
|
id: string | null;
|
|
@@ -49,8 +50,7 @@ interface NSASectionEditTabPageState<RowType>
|
|
|
49
50
|
|
|
50
51
|
export class NSASectionEditTabPage<RowType extends { id: string }, RowTypeInput = RowType> extends Component<NSASectionEditTabPageProps<RowType, RowTypeInput>, NSASectionEditTabPageState<RowType>>
|
|
51
52
|
{
|
|
52
|
-
private
|
|
53
|
-
private Categories_Refs: { [group: string]: React.RefObject<NSBoxBooleans> } = {};
|
|
53
|
+
private Slots_Refs: { [id: string]: RefObject<NSFBoxSlot> } = {};
|
|
54
54
|
private Tags_Refs = createRef<NSRepeaterNSTag>();
|
|
55
55
|
|
|
56
56
|
constructor(props: NSASectionEditTabPageProps<RowType, RowTypeInput>)
|
|
@@ -60,14 +60,11 @@ export class NSASectionEditTabPage<RowType extends { id: string }, RowTypeInput
|
|
|
60
60
|
this.state = { row: props.model.row };
|
|
61
61
|
|
|
62
62
|
if (props.ctf.enabled)
|
|
63
|
-
|
|
64
|
-
props.ctf.fields?.forEach(field => this.Fields_Refs[field.id] = createRef<NSBoxDynamic>());
|
|
65
|
-
props.ctf.categories?.forEach(category =>
|
|
63
|
+
props.ctf.rows?.slots?.forEach(slot =>
|
|
66
64
|
{
|
|
67
|
-
if (!this.
|
|
68
|
-
this.
|
|
65
|
+
if (!this.Slots_Refs[slot.id])
|
|
66
|
+
this.Slots_Refs[slot.id] = createRef<NSFBoxSlot>();
|
|
69
67
|
});
|
|
70
|
-
}
|
|
71
68
|
|
|
72
69
|
this.reload = this.reload.bind(this);
|
|
73
70
|
this.getRow = this.getRow.bind(this);
|
|
@@ -113,19 +110,24 @@ export class NSASectionEditTabPage<RowType extends { id: string }, RowTypeInput
|
|
|
113
110
|
let categories: EntityCategoryInputRow[] = [];
|
|
114
111
|
let tags: EntityTagInputRow[] = [];
|
|
115
112
|
|
|
116
|
-
|
|
117
|
-
|
|
113
|
+
let rows = this.props.ctf.rows;
|
|
114
|
+
if (rows)
|
|
115
|
+
for (let slot of rows.slots)
|
|
118
116
|
{
|
|
119
|
-
let ref = this.
|
|
120
|
-
if (ref
|
|
121
|
-
|
|
117
|
+
let ref = this.Slots_Refs[slot.id];
|
|
118
|
+
if (!ref?.current)
|
|
119
|
+
continue;
|
|
120
|
+
let value = ref.current.getValue();
|
|
121
|
+
if (slot.entity_type === SlotEntityType.Field)
|
|
122
|
+
fields.push({ field_id: slot.entity_id, value });
|
|
123
|
+
else if (slot.entity_type === SlotEntityType.CategoryScope)
|
|
124
|
+
{
|
|
125
|
+
if (Array.isArray(value))
|
|
126
|
+
value.forEach(id => categories.push({ category_id: id }));
|
|
127
|
+
else if (value != null)
|
|
128
|
+
categories.push({ category_id: value });
|
|
129
|
+
}
|
|
122
130
|
}
|
|
123
|
-
for (let group in this.Categories_Refs)
|
|
124
|
-
{
|
|
125
|
-
let ref = this.Categories_Refs[group];
|
|
126
|
-
if (ref.current)
|
|
127
|
-
categories.push(...ref.current?.getValues().map(x => { return { category_id: x } }));
|
|
128
|
-
}
|
|
129
131
|
if (this.Tags_Refs.current)
|
|
130
132
|
tags = this.Tags_Refs.current.getValue().map(x => { return { name: x.name, value: x.value } });
|
|
131
133
|
|
|
@@ -133,18 +135,27 @@ export class NSASectionEditTabPage<RowType extends { id: string }, RowTypeInput
|
|
|
133
135
|
}
|
|
134
136
|
private setFields(ctf: CTFRow)
|
|
135
137
|
{
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
let
|
|
139
|
-
|
|
140
|
-
ref.
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
138
|
+
let rows = this.props.ctf.rows;
|
|
139
|
+
if (rows)
|
|
140
|
+
for (let slot of rows.slots)
|
|
141
|
+
{
|
|
142
|
+
let ref = this.Slots_Refs[slot.id];
|
|
143
|
+
if (!ref?.current)
|
|
144
|
+
continue;
|
|
145
|
+
if (slot.entity_type === SlotEntityType.Field)
|
|
146
|
+
{
|
|
147
|
+
let field = ctf.fields.find(x => x.field_id === slot.entity_id);
|
|
148
|
+
if (field)
|
|
149
|
+
ref.current.setValue(field.value, () => { });
|
|
150
|
+
}
|
|
151
|
+
else if (slot.entity_type === SlotEntityType.CategoryScope)
|
|
152
|
+
{
|
|
153
|
+
let ids = ctf.categories
|
|
154
|
+
.map(x => x.category_id)
|
|
155
|
+
.filter(id => rows.categories.find(category => category.id === id)?.category_scope_id === slot.entity_id);
|
|
156
|
+
ref.current.setValue(slot.multiple ? ids : (ids[0] ?? null), () => { });
|
|
157
|
+
}
|
|
158
|
+
}
|
|
148
159
|
if (this.Tags_Refs.current)
|
|
149
160
|
this.Tags_Refs.current.setValue(ctf.tags.map(x => { return { name: x.name, value: x.value ?? "" } }));
|
|
150
161
|
}
|
|
@@ -161,60 +172,56 @@ export class NSASectionEditTabPage<RowType extends { id: string }, RowTypeInput
|
|
|
161
172
|
}
|
|
162
173
|
override render()
|
|
163
174
|
{
|
|
164
|
-
|
|
165
|
-
|
|
175
|
+
const TAB_GENERAL = "General";
|
|
176
|
+
|
|
177
|
+
let rows = this.props.ctf.enabled ? this.props.ctf.rows : null;
|
|
178
|
+
let slots = rows?.slots ?? [];
|
|
179
|
+
|
|
180
|
+
let renderSlot = (slot: SlotRow) =>
|
|
181
|
+
{
|
|
182
|
+
if (!this.Slots_Refs[slot.id])
|
|
183
|
+
this.Slots_Refs[slot.id] = createRef<NSFBoxSlot>();
|
|
184
|
+
return <NSFBoxSlot
|
|
185
|
+
key={`NSASectionEditTabPage_NSFBoxSlot_${slot.id}`}
|
|
186
|
+
{...this.props}
|
|
187
|
+
ref={this.Slots_Refs[slot.id]}
|
|
188
|
+
slot={slot}
|
|
189
|
+
getField={() => rows!.fields.find(x => x.id === slot.entity_id)!}
|
|
190
|
+
getCategoryScope={() => rows!.category_scopes.find(x => x.id === slot.entity_id)!}
|
|
191
|
+
/>;
|
|
192
|
+
};
|
|
166
193
|
|
|
167
194
|
let tabs: NSTabPageTab[] = [{
|
|
168
|
-
title:
|
|
195
|
+
title: TAB_GENERAL,
|
|
169
196
|
clicked: true,
|
|
170
197
|
getContent: () => <NSColumn
|
|
171
198
|
{...this.props.ui?.tab_main}
|
|
172
199
|
>
|
|
173
|
-
|
|
200
|
+
<NSFBoxWrapper
|
|
201
|
+
slots={slots.filter(x => x.tab === TAB_GENERAL)}
|
|
202
|
+
renderSlot={renderSlot}
|
|
203
|
+
>
|
|
204
|
+
{this.props.children}
|
|
205
|
+
</NSFBoxWrapper>
|
|
174
206
|
</NSColumn>
|
|
175
207
|
}];
|
|
176
208
|
this.props.ui?.extra_tabs?.forEach(tab => tabs.push(tab));
|
|
177
209
|
if (this.props.ctf.enabled)
|
|
178
210
|
{
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
tabs.push({
|
|
182
|
-
title: group,
|
|
183
|
-
clicked: true,
|
|
184
|
-
getContent: () => <NSColumn
|
|
185
|
-
classList={[`${Styles.nsa_section_edit_tab_page}`]}
|
|
186
|
-
>
|
|
187
|
-
<NSRow>
|
|
188
|
-
{
|
|
189
|
-
this.props.ctf.fields?.filter(x => x.group === group).map((field, index) =>
|
|
190
|
-
<NSBoxDynamic
|
|
191
|
-
key={`NSASectionViewTabPage_NSBoxDynamic_${index}`}
|
|
192
|
-
ref={this.Fields_Refs[field.id]}
|
|
193
|
-
name={field.id}
|
|
194
|
-
title={field.name}
|
|
195
|
-
variable={field.type}
|
|
196
|
-
/>
|
|
197
|
-
)
|
|
198
|
-
}
|
|
199
|
-
</NSRow>
|
|
200
|
-
</NSColumn>
|
|
201
|
-
});
|
|
202
|
-
});
|
|
203
|
-
groups_categories.forEach(group =>
|
|
211
|
+
let tab_names = Array.from(new Set(slots.map(x => x.tab))).filter(tab => tab !== TAB_GENERAL);
|
|
212
|
+
tab_names.forEach(tab =>
|
|
204
213
|
{
|
|
205
|
-
let items = this.props.ctf.categories?.filter(x => x.group === group).map(category => { return { value: category.id, text: category.name } }) ?? [];
|
|
206
214
|
tabs.push({
|
|
207
|
-
title:
|
|
215
|
+
title: tab,
|
|
208
216
|
clicked: true,
|
|
209
217
|
getContent: () => <NSColumn
|
|
210
218
|
classList={[`${Styles.nsa_section_edit_tab_page}`]}
|
|
211
219
|
>
|
|
212
220
|
<NSRow>
|
|
213
|
-
<
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
></NSBoxBooleans>
|
|
221
|
+
<NSFBoxWrapper
|
|
222
|
+
slots={slots.filter(x => x.tab === tab)}
|
|
223
|
+
renderSlot={renderSlot}
|
|
224
|
+
/>
|
|
218
225
|
</NSRow>
|
|
219
226
|
</NSColumn>
|
|
220
227
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { EntityResolveResponseRow } from "namirasoft-field";
|
|
2
2
|
import { IBaseComponentProps, NSBoxCombo, NSRow, NSSpace, NSSpaceSizeType, NSSplitter } from "namirasoft-site-react";
|
|
3
3
|
import { Component, ReactNode, createRef } from "react";
|
|
4
4
|
import { IEntityInfo } from "../IEntityInfo";
|
|
@@ -23,8 +23,7 @@ export interface NSASectionListProps<RowType extends { id: string }, RowTypeInpu
|
|
|
23
23
|
entity: IEntityInfo<RowType, RowTypeInput>;
|
|
24
24
|
ctf: {
|
|
25
25
|
enabled: boolean;
|
|
26
|
-
|
|
27
|
-
categories: CategoryRow[] | null;
|
|
26
|
+
rows: EntityResolveResponseRow | null;
|
|
28
27
|
};
|
|
29
28
|
deleteFieldCache: () => void;
|
|
30
29
|
children?: ReactNode;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { EntityResolveResponseRow } from "namirasoft-field";
|
|
2
2
|
import { IBaseComponentProps, NSLoading } from "namirasoft-site-react";
|
|
3
3
|
import { Component, createRef, ReactNode } from "react";
|
|
4
4
|
import { IEntityInfo } from "../IEntityInfo";
|
|
@@ -21,8 +21,7 @@ export interface NSASectionViewProps<RowType extends { id: string }, RowTypeInpu
|
|
|
21
21
|
entity: IEntityInfo<RowType, RowTypeInput>;
|
|
22
22
|
ctf: {
|
|
23
23
|
enabled: boolean;
|
|
24
|
-
|
|
25
|
-
categories: CategoryRow[] | null;
|
|
24
|
+
rows: EntityResolveResponseRow | null;
|
|
26
25
|
};
|
|
27
26
|
model: {
|
|
28
27
|
id: string | null;
|