namirasoft-site-react 1.4.68 → 1.4.70

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 (51) hide show
  1. package/dist/components/NSBarAction.js +3 -2
  2. package/dist/components/NSBarAction.js.map +1 -1
  3. package/dist/components/NSBarTitle.js +2 -1
  4. package/dist/components/NSBarTitle.js.map +1 -1
  5. package/dist/components/NSBoxBooleans.js +2 -1
  6. package/dist/components/NSBoxBooleans.js.map +1 -1
  7. package/dist/components/NSFilterBox.js +2 -1
  8. package/dist/components/NSFilterBox.js.map +1 -1
  9. package/dist/components/NSGroupedList.js +2 -1
  10. package/dist/components/NSGroupedList.js.map +1 -1
  11. package/dist/components/NSHeader.js +3 -2
  12. package/dist/components/NSHeader.js.map +1 -1
  13. package/dist/components/NSLayout.js +2 -1
  14. package/dist/components/NSLayout.js.map +1 -1
  15. package/dist/components/NSLoading.js +2 -2
  16. package/dist/components/NSLoading.js.map +1 -1
  17. package/dist/components/NSLoading.module.css +2 -0
  18. package/dist/components/NSRange.js +2 -1
  19. package/dist/components/NSRange.js.map +1 -1
  20. package/dist/components/NSRepeater.js +2 -1
  21. package/dist/components/NSRepeater.js.map +1 -1
  22. package/dist/components/NSTabPage.d.ts +1 -1
  23. package/dist/components/NSTabPage.js +3 -2
  24. package/dist/components/NSTabPage.js.map +1 -1
  25. package/dist/components/NSTable.js +15 -14
  26. package/dist/components/NSTable.js.map +1 -1
  27. package/dist/components/NSTimelineMonthly.js +3 -2
  28. package/dist/components/NSTimelineMonthly.js.map +1 -1
  29. package/dist/main.d.ts +2 -1
  30. package/dist/main.js +2 -1
  31. package/dist/main.js.map +1 -1
  32. package/dist/utils/generateUniqId.d.ts +1 -0
  33. package/dist/utils/generateUniqId.js +2 -0
  34. package/dist/utils/generateUniqId.js.map +1 -0
  35. package/package.json +1 -1
  36. package/src/components/NSBarAction.tsx +4 -3
  37. package/src/components/NSBarTitle.tsx +2 -1
  38. package/src/components/NSBoxBooleans.tsx +3 -2
  39. package/src/components/NSFilterBox.tsx +3 -2
  40. package/src/components/NSGroupedList.tsx +22 -13
  41. package/src/components/NSHeader.tsx +215 -214
  42. package/src/components/NSLayout.tsx +4 -3
  43. package/src/components/NSLoading.module.css +2 -0
  44. package/src/components/NSLoading.tsx +9 -8
  45. package/src/components/NSRange.tsx +2 -1
  46. package/src/components/NSRepeater.tsx +2 -1
  47. package/src/components/NSTabPage.tsx +5 -4
  48. package/src/components/NSTable.tsx +12 -3
  49. package/src/components/NSTimelineMonthly.tsx +4 -3
  50. package/src/main.ts +2 -1
  51. package/src/utils/generateUniqId.ts +1 -0
@@ -9,243 +9,244 @@ import { IHeaderProps } from "../props/IHeaderProps";
9
9
  import { IStorageLocal, CacheService } from "namirasoft-core";
10
10
  import { EnvService } from 'namirasoft-core'
11
11
  import { INSRouterProps } from "../routing/INSRouterProps";
12
+ import { generateUniqId } from "../utils/generateUniqId";
12
13
  export interface INSHeaderProps extends IBaseComponentProps, INSRouterProps
13
14
  {
14
- scope: string;
15
- name: string;
16
- logo: string;
17
- nav?: IBaseComponentProps;
18
- header: IHeaderProps;
19
- isLoggedIn: () => boolean;
15
+ scope: string;
16
+ name: string;
17
+ logo: string;
18
+ nav?: IBaseComponentProps;
19
+ header: IHeaderProps;
20
+ isLoggedIn: () => boolean;
20
21
  }
21
22
 
22
23
  export interface NSHeaderState
23
24
  {
24
- filters: FilterLinkFullRow[];
25
- selected: FilterLinkFullRow | null;
26
- showNavbar: boolean;
25
+ filters: FilterLinkFullRow[];
26
+ selected: FilterLinkFullRow | null;
27
+ showNavbar: boolean;
27
28
  }
28
29
 
29
30
  export class NSHeader extends React.Component<INSHeaderProps, NSHeaderState>
30
31
  {
31
- private cache: CacheService<{
32
- rows: FilterLinkFullRow[];
33
- count: number;
34
- }>;
32
+ private cache: CacheService<{
33
+ rows: FilterLinkFullRow[];
34
+ count: number;
35
+ }>;
35
36
 
36
- constructor(props: INSHeaderProps)
37
- {
38
- super(props);
39
- this.state = {
40
- filters: [],
41
- selected: null,
42
- showNavbar: false
43
- };
44
- this.hasChild = this.hasChild.bind(this);
45
- this.onMenuItemToggled = this.onMenuItemToggled.bind(this);
46
- this.render_menu = this.render_menu.bind(this);
47
- this.render_menuItem = this.render_menuItem.bind(this);
48
- this.handleShowNavbar = this.handleShowNavbar.bind(this);
49
- this.cache = new CacheService<{
50
- rows: FilterLinkFullRow[];
51
- count: number;
52
- }>("ns-header", 720, new IStorageLocal(), async () =>
53
- {
54
- let REACT_APP_BASE_URL_API_LINK = new EnvService("REACT_APP_BASE_URL_API_LINK", true).getString();
55
- let server = new NamirasoftAPILinkServer(REACT_APP_BASE_URL_API_LINK, props.notifier.onError);
56
- return server.filter.ListFilterLinks(this.props.scope, this.props.name, null, null, null);
57
- }, () => { });
58
- }
59
- override componentDidMount(): void
60
- {
61
- this.cache.get().then(filters =>
62
- {
63
- this.setState({ filters: filters.rows });
64
- }).catch(() => { });
65
- }
66
- private onMenuItemToggled(checked: boolean, selected: FilterLinkFullRow)
67
- {
68
- if (checked)
69
- this.setState({ selected });
70
- }
71
- private getFilters(): FilterLinkFullRow[]
72
- {
73
- let loggedin = this.props.isLoggedIn();
74
- let ans = this.state.filters?.filter(f =>
75
- {
76
- if (f.link)
77
- {
78
- if (loggedin)
79
- return f.link.private;
80
- return f.link.public;
81
- }
82
- return true;
83
- }) ?? [];
37
+ constructor(props: INSHeaderProps)
38
+ {
39
+ super(props);
40
+ this.state = {
41
+ filters: [],
42
+ selected: null,
43
+ showNavbar: false
44
+ };
45
+ this.hasChild = this.hasChild.bind(this);
46
+ this.onMenuItemToggled = this.onMenuItemToggled.bind(this);
47
+ this.render_menu = this.render_menu.bind(this);
48
+ this.render_menuItem = this.render_menuItem.bind(this);
49
+ this.handleShowNavbar = this.handleShowNavbar.bind(this);
50
+ this.cache = new CacheService<{
51
+ rows: FilterLinkFullRow[];
52
+ count: number;
53
+ }>("ns-header", 720, new IStorageLocal(), async () =>
54
+ {
55
+ let REACT_APP_BASE_URL_API_LINK = new EnvService("REACT_APP_BASE_URL_API_LINK", true).getString();
56
+ let server = new NamirasoftAPILinkServer(REACT_APP_BASE_URL_API_LINK, props.notifier.onError);
57
+ return server.filter.ListFilterLinks(this.props.scope, this.props.name, null, null, null);
58
+ }, () => { });
59
+ }
60
+ override componentDidMount(): void
61
+ {
62
+ this.cache.get().then(filters =>
63
+ {
64
+ this.setState({ filters: filters.rows });
65
+ }).catch(() => { });
66
+ }
67
+ private onMenuItemToggled(checked: boolean, selected: FilterLinkFullRow)
68
+ {
69
+ if (checked)
70
+ this.setState({ selected });
71
+ }
72
+ private getFilters(): FilterLinkFullRow[]
73
+ {
74
+ let loggedin = this.props.isLoggedIn();
75
+ let ans = this.state.filters?.filter(f =>
76
+ {
77
+ if (f.link)
78
+ {
79
+ if (loggedin)
80
+ return f.link.private;
81
+ return f.link.public;
82
+ }
83
+ return true;
84
+ }) ?? [];
84
85
 
85
- while (true)
86
- {
87
- let old_length = ans.length;
88
- let old = ans;
89
- ans = ans.filter(f =>
90
- {
91
- if (f.link?.url)
92
- return true;
93
- return old.filter(x => x.parent_id === f.id).length > 0;
94
- });
95
- let new_length = ans.length;
96
- if (old_length === new_length)
97
- break;
98
- }
86
+ while (true)
87
+ {
88
+ let old_length = ans.length;
89
+ let old = ans;
90
+ ans = ans.filter(f =>
91
+ {
92
+ if (f.link?.url)
93
+ return true;
94
+ return old.filter(x => x.parent_id === f.id).length > 0;
95
+ });
96
+ let new_length = ans.length;
97
+ if (old_length === new_length)
98
+ break;
99
+ }
99
100
 
100
- return ans;
101
- }
102
- private hasChild(id: number): boolean
103
- {
104
- return this.getFilters().filter(f => f.parent_id === id).length > 0;
105
- }
106
- handleShowNavbar(): void
107
- {
108
- this.setState({ showNavbar: !this.state.showNavbar });
109
- }
110
- override render()
111
- {
112
- let nav: IBaseComponentProps | undefined = this.props.nav;
113
- if (!nav)
114
- nav = { style: {} };
115
- if (!nav.style)
116
- nav.style = {};
117
- if (!nav.style?.backgroundColor)
118
- nav.style.backgroundColor = "rgba(20, 27, 92, 1)";
119
- return (
120
- <header id={this.props.id}
121
- className={`${Styles.ns_header} ${this.props.classList?.join(" ")}`}
122
- style={this.props.style}
123
- >
124
- <nav
125
- id={this.props.nav?.id}
126
- className={`${Styles.ns_navbar} ${this.props.nav?.classList?.join(" ")}`}
127
- style={nav?.style}
128
- >
129
- <div className={`${Styles.ns_navbar_parent_content} container`}>
130
- <a className="me-2" href="/">
131
- <img
132
- src={this.props.logo}
133
- alt="Logo"
134
- width={48}
135
- height={48}
136
- />
101
+ return ans;
102
+ }
103
+ private hasChild(id: number): boolean
104
+ {
105
+ return this.getFilters().filter(f => f.parent_id === id).length > 0;
106
+ }
107
+ handleShowNavbar(): void
108
+ {
109
+ this.setState({ showNavbar: !this.state.showNavbar });
110
+ }
111
+ override render()
112
+ {
113
+ let nav: IBaseComponentProps | undefined = this.props.nav;
114
+ if (!nav)
115
+ nav = { style: {} };
116
+ if (!nav.style)
117
+ nav.style = {};
118
+ if (!nav.style?.backgroundColor)
119
+ nav.style.backgroundColor = "rgba(20, 27, 92, 1)";
120
+ return (
121
+ <header id={this.props.id}
122
+ className={`${Styles.ns_header} ${this.props.classList?.join(" ")}`}
123
+ style={this.props.style}
124
+ >
125
+ <nav
126
+ id={this.props.nav?.id}
127
+ className={`${Styles.ns_navbar} ${this.props.nav?.classList?.join(" ")}`}
128
+ style={nav?.style}
129
+ >
130
+ <div className={`${Styles.ns_navbar_parent_content} container`}>
131
+ <a className="me-2" href="/">
132
+ <img
133
+ src={this.props.logo}
134
+ alt="Logo"
135
+ width={48}
136
+ height={48}
137
+ />
137
138
  </a>
138
- { this.props.header.logo_title &&
139
+ {this.props.header.logo_title &&
139
140
  <h2 className={`${Styles.ns_navbar_title} mb-0 flex-shrink-0`}>
140
141
  {this.props.header.logo_title}
141
- </h2>
142
+ </h2>
142
143
  }
143
144
  <div className={`${Styles.ns_navbar_content} `} >
144
- <div className={`${Styles.ns_navbar_elements} ${this.state.showNavbar && Styles.ns_navbar_active}`}>
145
- {this.render_menu(0, null)}
146
- </div>
147
- {
148
- this.props.header &&
149
- <div className="d-flex gap-3 align-items-center">
150
- <span className={Styles.ns_navbar_title}>{this.props.header?.title}</span>
151
- {
152
- this.props.header.icons.map((icon, index) =>
145
+ <div className={`${Styles.ns_navbar_elements} ${this.state.showNavbar && Styles.ns_navbar_active}`}>
146
+ {this.render_menu(0, null)}
147
+ </div>
148
+ {
149
+ this.props.header &&
150
+ <div className="d-flex gap-3 align-items-center">
151
+ <span className={Styles.ns_navbar_title}>{this.props.header?.title}</span>
152
+ {
153
+ this.props.header.icons.map((icon) =>
153
154
  <div
154
- key={index}
155
+ key={generateUniqId()}
155
156
  title={icon.tooltip}
156
- className={Styles.ns_header_icon}
157
+ className={Styles.ns_header_icon}
157
158
  >
158
- <img
159
- src={icon.src}
160
- alt={icon.alt}
161
- width={20}
162
- height={20}
159
+ <img
160
+ src={icon.src}
161
+ alt={icon.alt}
162
+ width={20}
163
+ height={20}
163
164
  onClick={() => icon.onClicked(icon)}
164
- />
165
- {
166
- icon.count !== 0 && icon.count &&
165
+ />
166
+ {
167
+ icon.count !== 0 && icon.count &&
167
168
  <div
168
169
  className={Styles.ns_navbar_notification_count}
169
170
  onClick={() => icon.onClicked(icon)}
170
- >
171
- {
172
- icon.count < 100 ? icon.count : "+99"
173
- }
174
- </div>
175
- }
176
- {
177
- icon.children
178
- }
179
- </div>
180
- )
181
- }
182
- </div>
183
- }
184
- <div className={Styles.ns_navbar_menu_icon} onClick={this.handleShowNavbar}>
185
- <img
186
- src=
187
- {
188
- this.state.showNavbar ?
189
- "https://static.namirasoft.com/image/concept/close/white.svg"
190
- : "https://static.namirasoft.com/image/concept/menu/burger-white.svg"
191
- }
192
- alt="Menu Icon"
193
- width={24}
194
- height={24}
195
- />
196
- </div>
197
- </div>
198
- </div>
199
- </nav>
200
- </header>
201
- );
202
- }
203
- private render_menu(level: number, parent_id: number | null)
204
- {
205
- let fs: FilterLinkFullRow[] = this.getFilters().filter(f => f.parent_id === parent_id);
206
- return (
207
- <div className={`me-auto nav ${Styles.ns_navbar_items_container}`} >
208
- {(fs?.map(f => this.render_menuItem(level, f)))}
209
- </div>
210
- );
211
- }
212
- private render_menuItem(level: number, filter: FilterLinkFullRow)
213
- {
214
- if (this.hasChild(filter.id))
215
- {
216
- let sub_menus = <></>;
217
- if (level === 0)
218
- if (this.state.selected)
219
- {
220
- sub_menus =
221
- <div
222
- id={`dropdown_items${filter.id}`}>
223
- {this.render_menu(1, this.state.selected.id)}
224
- </div >
225
- }
226
- return <NavDropdown
227
- onToggle={(checked) => this.onMenuItemToggled(checked, filter)}
228
- className={level === 0 ? Styles.ns_navbar_first_level_item : Styles.ns_navbar_second_level_item}
229
- title={filter.name}
230
- key={filter.id}
231
- id={`dropdown_parent${filter.id}`}>
232
- {sub_menus}
233
- </NavDropdown >;
234
- }
235
- else
236
- {
237
- let href = filter.link?.url;
238
- if (process.env.REACT_APP_STANDALONE)
239
- if (href)
240
- {
241
- let url = new URL(href);
242
- url.host = window.location.host;
243
- url.protocol = window.location.protocol;
244
- href = url.toString();
245
- }
246
- return (
247
- <a key={filter.id} className={`${Styles.ns_navbar_items_link} ${level === 0 ? Styles.ns_navbar_first_level_item : Styles.ns_navbar_second_level_item}`} href={href}>{filter.name}</a>
248
- );
249
- }
250
- }
171
+ >
172
+ {
173
+ icon.count < 100 ? icon.count : "+99"
174
+ }
175
+ </div>
176
+ }
177
+ {
178
+ icon.children
179
+ }
180
+ </div>
181
+ )
182
+ }
183
+ </div>
184
+ }
185
+ <div className={Styles.ns_navbar_menu_icon} onClick={this.handleShowNavbar}>
186
+ <img
187
+ src=
188
+ {
189
+ this.state.showNavbar ?
190
+ "https://static.namirasoft.com/image/concept/close/white.svg"
191
+ : "https://static.namirasoft.com/image/concept/menu/burger-white.svg"
192
+ }
193
+ alt="Menu Icon"
194
+ width={24}
195
+ height={24}
196
+ />
197
+ </div>
198
+ </div>
199
+ </div>
200
+ </nav>
201
+ </header>
202
+ );
203
+ }
204
+ private render_menu(level: number, parent_id: number | null)
205
+ {
206
+ let fs: FilterLinkFullRow[] = this.getFilters().filter(f => f.parent_id === parent_id);
207
+ return (
208
+ <div className={`me-auto nav ${Styles.ns_navbar_items_container}`} >
209
+ {(fs?.map(f => this.render_menuItem(level, f)))}
210
+ </div>
211
+ );
212
+ }
213
+ private render_menuItem(level: number, filter: FilterLinkFullRow)
214
+ {
215
+ if (this.hasChild(filter.id))
216
+ {
217
+ let sub_menus = <></>;
218
+ if (level === 0)
219
+ if (this.state.selected)
220
+ {
221
+ sub_menus =
222
+ <div
223
+ id={`dropdown_items${filter.id}`}>
224
+ {this.render_menu(1, this.state.selected.id)}
225
+ </div >
226
+ }
227
+ return <NavDropdown
228
+ onToggle={(checked) => this.onMenuItemToggled(checked, filter)}
229
+ className={level === 0 ? Styles.ns_navbar_first_level_item : Styles.ns_navbar_second_level_item}
230
+ title={filter.name}
231
+ key={filter.id}
232
+ id={`dropdown_parent${filter.id}`}>
233
+ {sub_menus}
234
+ </NavDropdown >;
235
+ }
236
+ else
237
+ {
238
+ let href = filter.link?.url;
239
+ if (process.env.REACT_APP_STANDALONE)
240
+ if (href)
241
+ {
242
+ let url = new URL(href);
243
+ url.host = window.location.host;
244
+ url.protocol = window.location.protocol;
245
+ href = url.toString();
246
+ }
247
+ return (
248
+ <a key={filter.id} className={`${Styles.ns_navbar_items_link} ${level === 0 ? Styles.ns_navbar_first_level_item : Styles.ns_navbar_second_level_item}`} href={href}>{filter.name}</a>
249
+ );
250
+ }
251
+ }
251
252
  }
@@ -11,6 +11,7 @@ import { INSBarTitleProps, NSBarTitle } from './NSBarTitle';
11
11
  import { NSSpace, NSSpaceSizeType } from './NSSpace';
12
12
  import { INSRouterProps } from '../routing/INSRouterProps';
13
13
  import { INSBarAlertProps, NSBarAlert } from './NSBarAlert';
14
+ import { generateUniqId } from '../utils/generateUniqId';
14
15
 
15
16
  export interface INSLayoutProps extends IBaseComponentProps, INSRouterProps
16
17
  {
@@ -70,8 +71,8 @@ export function NSLayout(props: INSLayoutProps)
70
71
  props.notifications.length !== 0 &&
71
72
  <>
72
73
  {
73
- props.notifications.map((notification, index) =>
74
- <Fragment key={index}>
74
+ props.notifications.map((notification) =>
75
+ <Fragment key={generateUniqId()}>
75
76
  <NSBarNotification {...notification} />
76
77
  </Fragment>
77
78
  )
@@ -79,7 +80,7 @@ export function NSLayout(props: INSLayoutProps)
79
80
  </>
80
81
  }
81
82
  {
82
- alerts.length !== 0 && alerts.map((alert, index) => <NSBarAlert key={index} {...alert} />)
83
+ alerts.length !== 0 && alerts.map((alert) => <NSBarAlert key={generateUniqId()} {...alert} />)
83
84
  }
84
85
  {
85
86
  isValidAction(props.action) && <NSBarAction {...props.action} />
@@ -22,6 +22,8 @@
22
22
  radial-gradient(farthest-side, #0000 calc(100% - 9px), #000 calc(100% - 8px));
23
23
  -webkit-mask-composite: destination-in;
24
24
  mask-composite: intersect;
25
+ mask: repeating-conic-gradient(#0000 0deg, #000 1deg 20deg, #0000 21deg 36deg),
26
+ radial-gradient(farthest-side, #0000 calc(100% - 9px), #000 calc(100% - 8px));
25
27
  animation: s4 1s infinite steps(10);
26
28
  }
27
29
 
@@ -1,5 +1,4 @@
1
1
  import Styles from './NSLoading.module.css';
2
- import { NSSection } from './NSSection';
3
2
  import { IBaseComponentProps } from "../props/IBaseComponentProps";
4
3
 
5
4
  export interface INSLoadingProps extends IBaseComponentProps
@@ -9,12 +8,14 @@ export interface INSLoadingProps extends IBaseComponentProps
9
8
  export function NSLoading(props: INSLoadingProps)
10
9
  {
11
10
  return (
12
- <NSSection {...props}>
13
- <div className={Styles.ns_loading_parent}>
14
- <h5>Loading</h5>
15
- <div className={Styles.ns_loader}></div>
16
- <p>Please wait ...</p>
17
- </div>
18
- </NSSection>
11
+ <div
12
+ id={props.id}
13
+ className={`${Styles.ns_loading_parent} ${props.classList?.join(" ")} `}
14
+ style={props.style}
15
+ >
16
+ <h5>Loading</h5>
17
+ <span className={Styles.ns_loader}></span>
18
+ <p>Please wait ...</p>
19
+ </div>
19
20
  );
20
21
  }
@@ -3,6 +3,7 @@ import Styles from './NSRange.module.css';
3
3
  import { IBaseComponentProps } from '../props/IBaseComponentProps';
4
4
 
5
5
  import { Color } from "../Color";
6
+ import { generateUniqId } from '../utils/generateUniqId';
6
7
 
7
8
  export interface NSRangeRow
8
9
  {
@@ -60,7 +61,7 @@ export function NSRange(props: INSRangeProps)
60
61
  {
61
62
  props.data?.map((data, index) =>
62
63
  <span
63
- key={index}
64
+ key={generateUniqId()}
64
65
  className={Styles.ns_range_time_line}
65
66
  style={{
66
67
  background: Color.getColor(data?.percentage),
@@ -1,4 +1,5 @@
1
1
  import { Component, createRef, Fragment, ReactNode } from 'react';
2
+ import { generateUniqId } from '../utils/generateUniqId';
2
3
 
3
4
  export interface NSRepeaterProps<ItemType, ValueType>
4
5
  {
@@ -166,7 +167,7 @@ export class NSRepeater<ItemType, ValueType> extends Component<NSRepeaterProps<I
166
167
  {
167
168
  if (this.state.items[index])
168
169
  return this.props.createItem(i++, ref, this.onChange, this.onDelete);
169
- return <Fragment key={index}></Fragment>;
170
+ return <Fragment key={generateUniqId()}></Fragment>;
170
171
  }
171
172
  )
172
173
  }
@@ -1,7 +1,8 @@
1
1
  "use client";
2
- import Styles from './NSTabPage.module.css';
3
- import { IBaseComponentProps } from "../props/IBaseComponentProps";
4
2
  import { Component } from "react";
3
+ import { IBaseComponentProps } from "../props/IBaseComponentProps";
4
+ import { generateUniqId } from '../utils/generateUniqId';
5
+ import Styles from './NSTabPage.module.css';
5
6
 
6
7
  export interface NSTabPageTab
7
8
  {
@@ -46,7 +47,7 @@ export class NSTabPage extends Component<NSTabPageProps, NSTabPageState>
46
47
  {
47
48
  this.props.tabs.map((tab, index) => (
48
49
  <li
49
- key={index}
50
+ key={generateUniqId()}
50
51
  className={this.state.activeTabIndex === index ? Styles.active : ''}
51
52
  onClick={() =>
52
53
  {
@@ -63,7 +64,7 @@ export class NSTabPage extends Component<NSTabPageProps, NSTabPageState>
63
64
  {
64
65
  this.props.tabs.map((tab, index) => (
65
66
  <div
66
- key={index}
67
+ key={generateUniqId()}
67
68
  className={this.props.grid ? Styles.ns_tab_content_grid : Styles.ns_tab_content_column}
68
69
  style={{ display: index === this.state.activeTabIndex ? "flex" : "none" }}
69
70
  >
@@ -265,13 +265,21 @@ export class NSTable<RowType> extends Component<INSTableProps<RowType>, NSTableS
265
265
  if (this.state.rows === null)
266
266
  {
267
267
  content = (
268
- <NSLoading />
268
+ <tr>
269
+ <td>
270
+ <NSLoading />
271
+ </td>
272
+ </tr>
269
273
  );
270
274
  }
271
275
  else if (this.state.rows.length === 0)
272
276
  {
273
277
  content = (
274
- <NSNoData lable='No Data' />
278
+ <tr>
279
+ <td>
280
+ <NSNoData lable='No Data' />
281
+ </td>
282
+ </tr>
275
283
  );
276
284
  }
277
285
  else
@@ -282,7 +290,8 @@ export class NSTable<RowType> extends Component<INSTableProps<RowType>, NSTableS
282
290
  return <tr
283
291
  key={this.props.getRowKey(row)} onClick={(e) => { onRowClick(e, row); }}>
284
292
  {
285
- this.props.checkbox && <td >
293
+ this.props.checkbox &&
294
+ <td >
286
295
  <label htmlFor={`checkbox_device_${this.props.getRowKey(row)}`} className={Styles.ns_checkbox_label}>
287
296
  <input className={Styles.ns_td_input} id={`checkbox_device_${this.props.getRowKey(row)}`} type="checkbox" checked={this.state.selectedIDs.includes(this.props.getRowKey(row))} onChange={(e) =>
288
297
  {
@@ -1,6 +1,7 @@
1
- import Styles from './NSTimelineMonthly.module.css';
2
1
  import { IBaseComponentProps } from "../props/IBaseComponentProps";
3
2
  import { Color } from "../Color"
3
+ import { generateUniqId } from '../utils/generateUniqId';
4
+ import Styles from './NSTimelineMonthly.module.css';
4
5
  export interface NSdata
5
6
  {
6
7
  title: string;
@@ -26,8 +27,8 @@ export function NSTimelineMonthly(props: INSNSTimelineMonthlyProps)
26
27
  <h5 className={Styles.ns_time_line_title}>{props.title}</h5>
27
28
  <div className={Styles.ns_time_line_monthly}>
28
29
  {
29
- props.data.map((card, index) => (
30
- <div className={Styles.ns_time_line_monthly_card} key={index}>
30
+ props.data.map((card) => (
31
+ <div className={Styles.ns_time_line_monthly_card} key={generateUniqId()}>
31
32
  <h5 className={Styles.ns_time_line_monthly_card_week_day}>{card.title}</h5>
32
33
  <span className={Styles.ns_time_line_cards_hour}>{card.value}</span>
33
34
  <div className={Styles.ns_time_line_monthly_card_parent_chart}>
package/src/main.ts CHANGED
@@ -102,6 +102,7 @@ export * from "./formatter/StringFormatter";
102
102
  export * from "./formatter/TimeFormatter";
103
103
  export * from "./formatter/UnknowFormatter";
104
104
  export * from "./pages/NSNotFoundPage";
105
+ export * from "./pages/NSUpdating";
105
106
  export * from "./props/IBaseComponentProps";
106
107
  export * from "./props/IHeaderIconProps";
107
108
  export * from "./props/IHeaderProps";
@@ -116,4 +117,4 @@ export * from "./routing/INSRouterProps";
116
117
  export * from "./routing/INSRouterState";
117
118
  export * from "./routing/Notifier";
118
119
  export * from "./routing/NSRouterMaker";
119
- export * from "./pages/NSUpdating";
120
+ export * from "./utils/generateUniqId";