poi-plugin-item-improvement2-beta 1.0.95 → 1.0.96

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/README.md CHANGED
@@ -37,3 +37,9 @@ npm run publish:beta
37
37
  ```
38
38
 
39
39
  The beta script temporarily changes the package and runtime namespace to `poi-plugin-item-improvement2-beta-beta`, publishes it, and restores the source tree even when publication fails.
40
+
41
+ ## Interface
42
+
43
+ Both the improvement list and the improvement plan support local search. The user-facing planning entry is named **Improvement Plan**.
44
+
45
+ The toolbar also provides a persisted **Use new interface** option. The legacy interface remains available, while the new interface separates improvement search and planning into top-level modes. Existing saved plans keep using their original storage key and require no migration.
package/assets/main.css CHANGED
@@ -14,6 +14,8 @@
14
14
  display: flex;
15
15
  flex-direction: row;
16
16
  white-space: nowrap;
17
+ overflow-x: auto;
18
+ overflow-y: hidden;
17
19
  }
18
20
  #item-improvement .form-group {
19
21
  margin-bottom: 0px;
@@ -231,3 +233,64 @@
231
233
  .improvement-changelog-version li + li {
232
234
  margin-top: 6px;
233
235
  }
236
+
237
+ #item-improvement .interface-header {
238
+ flex: 0 0 auto;
239
+ width: 100%;
240
+ }
241
+
242
+ #item-improvement .new-interface-toolbar {
243
+ width: 100%;
244
+ padding: 4px 0;
245
+ }
246
+
247
+ #item-improvement .new-interface-toolbar .weekday-nav {
248
+ margin-top: 4px;
249
+ overflow-x: auto;
250
+ overflow-y: hidden;
251
+ }
252
+
253
+ #item-improvement .interface-mode-nav {
254
+ flex: 0 1 auto !important;
255
+ }
256
+
257
+ #item-improvement .new-interface-toggle {
258
+ flex: 0 0 auto;
259
+ margin: 0 4px 0 10px;
260
+ white-space: nowrap;
261
+ }
262
+
263
+ #item-improvement .new-interface-toggle label,
264
+ #item-improvement .new-interface-toggle input {
265
+ cursor: pointer;
266
+ }
267
+
268
+ #item-improvement .improvement-search-box {
269
+ display: flex;
270
+ align-items: center;
271
+ margin: 8px 0;
272
+ }
273
+
274
+ #item-improvement .improvement-search-box .input-group {
275
+ flex: 1;
276
+ margin-right: 8px;
277
+ }
278
+
279
+ #item-improvement .improvement-search-count {
280
+ flex: 0 0 auto;
281
+ min-width: 5em;
282
+ text-align: right;
283
+ white-space: nowrap;
284
+ opacity: 0.75;
285
+ }
286
+
287
+ #item-improvement .improvement-empty-state {
288
+ padding: 32px 12px;
289
+ text-align: center;
290
+ opacity: 0.7;
291
+ }
292
+
293
+ #item-improvement .list-container {
294
+ height: auto;
295
+ min-height: 0;
296
+ }
package/i18n/en-US.json CHANGED
@@ -43,7 +43,7 @@
43
43
  "Available": " (Available: %d)",
44
44
  "New equipment plan": "New equipment plan",
45
45
  "Expand only non-empty categories": "Expand only non-empty categories",
46
- "Starcraft": "Starcraft",
46
+ "Starcraft": "Improvement Plan",
47
47
  "Your personal planner for crafting stars": "Your personal planner for crafting stars",
48
48
  "What's New": "What's New",
49
49
  "Release Notes": "Release Notes",
@@ -59,5 +59,16 @@
59
59
  "changelog_1_0_21_stable_data": "Improvement information now loads and updates more reliably.",
60
60
  "changelog_1_0_21_separate_routes": "Improvement routes with different materials, costs, or upgrade targets are now shown in separate tables.",
61
61
  "changelog_1_0_21_tamanami_route": "Added Tamanami Kai Ni’s dedicated material route and kept it separate from the normal route.",
62
- "changelog_1_0_27_data_safety": "Improved data safety checks so incomplete or incompatible improvement information is rejected instead of being displayed incorrectly."
62
+ "changelog_1_0_27_data_safety": "Improved data safety checks so incomplete or incompatible improvement information is rejected instead of being displayed incorrectly.",
63
+ "Improvement Query": "Improvement Search",
64
+ "Use new interface": "Use new interface",
65
+ "Search improvement list": "Search equipment, assistant ships, or IDs",
66
+ "Search improvement plans": "Search planned equipment or categories",
67
+ "Clear search": "Clear search",
68
+ "Search results": "%d results",
69
+ "No matching equipment": "No matching equipment",
70
+ "No matching plans": "No matching planned equipment",
71
+ "changelog_1_0_30_plan_name": "“Starcraft” has been renamed to the clearer “Improvement Plan”.",
72
+ "changelog_1_0_30_search": "Search is now available in both the improvement list and the improvement plan.",
73
+ "changelog_1_0_30_new_interface": "Added a saved “Use new interface” option that separates improvement search from planning."
63
74
  }
package/i18n/ja-JP.json CHANGED
@@ -43,7 +43,7 @@
43
43
  "Available": " (利用可能: %d)",
44
44
  "New equipment plan": "新しい改修計画",
45
45
  "Expand only non-empty categories": "改修計画がある装備種類だけを展開",
46
- "Starcraft": "スタークラフト",
46
+ "Starcraft": "改修計画",
47
47
  "Your personal planner for crafting stars": "装備改修計画",
48
48
  "What's New": "更新履歴",
49
49
  "Release Notes": "更新履歴",
@@ -59,5 +59,16 @@
59
59
  "changelog_1_0_21_stable_data": "改修情報の読み込みと更新をより安定させました。",
60
60
  "changelog_1_0_21_separate_routes": "必要装備、資材、更新先が異なる改修ルートを別々の表で表示するようにしました。",
61
61
  "changelog_1_0_21_tamanami_route": "玉波改二専用の改修素材ルートを追加し、通常ルートと混在しないようにしました。",
62
- "changelog_1_0_27_data_safety": "不完全または互換性のない改修情報を誤って表示しないよう、データ確認を強化しました。"
62
+ "changelog_1_0_27_data_safety": "不完全または互換性のない改修情報を誤って表示しないよう、データ確認を強化しました。",
63
+ "Improvement Query": "改修検索",
64
+ "Use new interface": "新しい画面を使用",
65
+ "Search improvement list": "装備・二番艦・IDを検索",
66
+ "Search improvement plans": "計画装備・装備カテゴリを検索",
67
+ "Clear search": "検索をクリア",
68
+ "Search results": "%d 件",
69
+ "No matching equipment": "条件に一致する装備がありません",
70
+ "No matching plans": "条件に一致する計画装備がありません",
71
+ "changelog_1_0_30_plan_name": "「スタークラフト」を、分かりやすい「改修計画」に名称変更しました。",
72
+ "changelog_1_0_30_search": "改修一覧と改修計画の両方に検索を追加し、装備名やIDなどから素早く探せるようになりました。",
73
+ "changelog_1_0_30_new_interface": "保存可能な「新しい画面を使用」設定を追加し、改修検索と改修計画を別々の入口に整理しました。"
63
74
  }
package/i18n/zh-CN.json CHANGED
@@ -43,7 +43,7 @@
43
43
  "Available": " (可用: %d)",
44
44
  "New equipment plan": "新建装备计划",
45
45
  "Expand only non-empty categories": "仅展开内容非空的装备类别",
46
- "Starcraft": "星级争霸",
46
+ "Starcraft": "改修计划",
47
47
  "Your personal planner for crafting stars": "装备改修规划书",
48
48
  "What's New": "更新日志",
49
49
  "Release Notes": "更新日志",
@@ -59,5 +59,16 @@
59
59
  "changelog_1_0_21_stable_data": "改修信息的加载和更新更加稳定。",
60
60
  "changelog_1_0_21_separate_routes": "材料、资材或升级目标不同的改修路线现在会分表展示。",
61
61
  "changelog_1_0_21_tamanami_route": "补充玉波改二专属的改修材料路线,避免与普通路线混在一起。",
62
- "changelog_1_0_27_data_safety": "加强改修资料完整性检查,遇到不完整或不兼容的资料时会拒绝加载,避免显示错误内容。"
62
+ "changelog_1_0_27_data_safety": "加强改修资料完整性检查,遇到不完整或不兼容的资料时会拒绝加载,避免显示错误内容。",
63
+ "Improvement Query": "改修查询",
64
+ "Use new interface": "使用新版界面",
65
+ "Search improvement list": "搜索装备、二号舰或编号",
66
+ "Search improvement plans": "搜索计划装备或装备类型",
67
+ "Clear search": "清除搜索",
68
+ "Search results": "找到 %d 件",
69
+ "No matching equipment": "没有符合条件的装备",
70
+ "No matching plans": "没有符合条件的计划装备",
71
+ "changelog_1_0_30_plan_name": "“星级争霸”已更名为更易理解的“改修计划”。",
72
+ "changelog_1_0_30_search": "改修列表和改修计划都新增搜索,可按装备名称、编号及相关信息快速查找。",
73
+ "changelog_1_0_30_new_interface": "新增可保存的“使用新版界面”选项;新版将改修查询与改修计划分成独立入口。"
63
74
  }
package/i18n/zh-TW.json CHANGED
@@ -43,7 +43,7 @@
43
43
  "Available": " (可用: %d)",
44
44
  "New equipment plan": "新建裝備計劃",
45
45
  "Expand only non-empty categories": "僅展開內容非空的裝備類別",
46
- "Starcraft": "星海爭霸",
46
+ "Starcraft": "改修計畫",
47
47
  "Your personal planner for crafting stars": "裝備改修規劃書",
48
48
  "What's New": "更新日誌",
49
49
  "Release Notes": "更新日誌",
@@ -59,5 +59,16 @@
59
59
  "changelog_1_0_21_stable_data": "改修資訊的載入與更新更加穩定。",
60
60
  "changelog_1_0_21_separate_routes": "材料、資材或升級目標不同的改修路線現在會分表顯示。",
61
61
  "changelog_1_0_21_tamanami_route": "補充玉波改二專屬的改修材料路線,避免與一般路線混在一起。",
62
- "changelog_1_0_27_data_safety": "加強改修資料完整性檢查,遇到不完整或不相容的資料時會拒絕載入,避免顯示錯誤內容。"
62
+ "changelog_1_0_27_data_safety": "加強改修資料完整性檢查,遇到不完整或不相容的資料時會拒絕載入,避免顯示錯誤內容。",
63
+ "Improvement Query": "改修查詢",
64
+ "Use new interface": "使用新版介面",
65
+ "Search improvement list": "搜尋裝備、二號艦或編號",
66
+ "Search improvement plans": "搜尋計畫裝備或裝備類型",
67
+ "Clear search": "清除搜尋",
68
+ "Search results": "找到 %d 件",
69
+ "No matching equipment": "沒有符合條件的裝備",
70
+ "No matching plans": "沒有符合條件的計畫裝備",
71
+ "changelog_1_0_30_plan_name": "「星級爭霸」已更名為更容易理解的「改修計畫」。",
72
+ "changelog_1_0_30_search": "改修列表與改修計畫都新增搜尋,可依裝備名稱、編號及相關資訊快速查找。",
73
+ "changelog_1_0_30_new_interface": "新增可保存的「使用新版介面」選項;新版將改修查詢與改修計畫分成獨立入口。"
63
74
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "poi-plugin-item-improvement2-beta",
3
- "version": "1.0.95",
3
+ "version": "1.0.96",
4
4
  "description": "View KanColle equipment improvement schedules, routes, costs, and required materials in Poi",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -13,6 +13,9 @@ const CHANGELOG_BASELINE_VERSION = '1.0.20'; // Keep in-app notes focused on use
13
13
 
14
14
  exports.CHANGELOG_BASELINE_VERSION = CHANGELOG_BASELINE_VERSION;
15
15
  const CHANGELOG = [{
16
+ version: '1.0.30',
17
+ items: ['changelog_1_0_30_plan_name', 'changelog_1_0_30_search', 'changelog_1_0_30_new_interface']
18
+ }, {
16
19
  version: '1.0.27',
17
20
  items: ['changelog_1_0_27_data_safety']
18
21
  }, {
@@ -25,6 +25,12 @@ var _starcraftArea = require("./starcraft/starcraft-area");
25
25
 
26
26
  var _utils = require("./starcraft/utils");
27
27
 
28
+ var _searchBox = require("./search-box");
29
+
30
+ var _search = require("./search");
31
+
32
+ var _uiPreferences = require("./ui-preferences");
33
+
28
34
  var _selectors = require("./selectors");
29
35
 
30
36
  var _class, _temp2;
@@ -39,6 +45,7 @@ const {
39
45
  const {
40
46
  config
41
47
  } = window;
48
+ const PLAN_VIEW_KEY = 10;
42
49
 
43
50
  const getJSTDayofWeek = () => {
44
51
  const date = new Date();
@@ -51,6 +58,36 @@ const getJSTDayofWeek = () => {
51
58
  return day;
52
59
  };
53
60
 
61
+ const WeekdayNav = ({
62
+ activeKey,
63
+ onSelect
64
+ }) => _react.default.createElement(_reactBootstrap.Nav, {
65
+ className: "main-nav weekday-nav",
66
+ bsStyle: "pills",
67
+ activeKey: activeKey,
68
+ onSelect: onSelect
69
+ }, _react.default.createElement(_reactBootstrap.NavItem, {
70
+ eventKey: 0
71
+ }, __('Sunday')), _react.default.createElement(_reactBootstrap.NavItem, {
72
+ eventKey: 1
73
+ }, __('Monday')), _react.default.createElement(_reactBootstrap.NavItem, {
74
+ eventKey: 2
75
+ }, __('Tuesday')), _react.default.createElement(_reactBootstrap.NavItem, {
76
+ eventKey: 3
77
+ }, __('Wednesday')), _react.default.createElement(_reactBootstrap.NavItem, {
78
+ eventKey: 4
79
+ }, __('Thursday')), _react.default.createElement(_reactBootstrap.NavItem, {
80
+ eventKey: 5
81
+ }, __('Friday')), _react.default.createElement(_reactBootstrap.NavItem, {
82
+ eventKey: 6
83
+ }, __('Saturday')), _react.default.createElement(_reactBootstrap.NavItem, {
84
+ eventKey: -1
85
+ }, __('All')));
86
+
87
+ WeekdayNav.propTypes = {
88
+ activeKey: _propTypes.default.number.isRequired,
89
+ onSelect: _propTypes.default.func.isRequired
90
+ };
54
91
  const ItemInfoArea = (0, _reactRedux.connect)(state => ({
55
92
  plans: (0, _selectors.starCraftPlanSelector)(state),
56
93
  data: (0, _selectors.improvementDataSelector)(state),
@@ -65,6 +102,9 @@ const ItemInfoArea = (0, _reactRedux.connect)(state => ({
65
102
  writable: true,
66
103
  value: {
67
104
  day: getJSTDayofWeek(),
105
+ lastQueryDay: getJSTDayofWeek(),
106
+ listSearchQuery: '',
107
+ useNewInterface: (0, _uiPreferences.getUseNewInterface)(config),
68
108
  changelogEntries: [],
69
109
  showChangelog: false
70
110
  }
@@ -93,8 +133,38 @@ const ItemInfoArea = (0, _reactRedux.connect)(state => ({
93
133
  enumerable: true,
94
134
  writable: true,
95
135
  value: key => {
136
+ const day = Number(key);
137
+ this.setState(prevState => ({
138
+ day,
139
+ lastQueryDay: day < 7 ? day : prevState.lastQueryDay
140
+ }));
141
+ }
142
+ }), Object.defineProperty(this, "handleModeChange", {
143
+ configurable: true,
144
+ enumerable: true,
145
+ writable: true,
146
+ value: mode => {
147
+ this.setState(prevState => ({
148
+ day: mode === 'plan' ? PLAN_VIEW_KEY : prevState.lastQueryDay
149
+ }));
150
+ }
151
+ }), Object.defineProperty(this, "handleNewInterfaceChange", {
152
+ configurable: true,
153
+ enumerable: true,
154
+ writable: true,
155
+ value: event => {
156
+ const useNewInterface = (0, _uiPreferences.setUseNewInterface)(config, event.target.checked);
157
+ this.setState({
158
+ useNewInterface
159
+ });
160
+ }
161
+ }), Object.defineProperty(this, "handleListSearchChange", {
162
+ configurable: true,
163
+ enumerable: true,
164
+ writable: true,
165
+ value: listSearchQuery => {
96
166
  this.setState({
97
- day: key
167
+ listSearchQuery
98
168
  });
99
169
  }
100
170
  }), Object.defineProperty(this, "getRows", {
@@ -106,7 +176,114 @@ const ItemInfoArea = (0, _reactRedux.connect)(state => ({
106
176
  data,
107
177
  idByDay
108
178
  } = this.props;
109
- return _fp.default.flow(_fp.default.filter(row => day === -1 || (idByDay[day] || []).includes(row.id)), _fp.default.sortBy([row => -row.priority, row => row.api_type[2], row => row.api_type[3], row => row.api_name]))(data);
179
+
180
+ const rows = _fp.default.flow(_fp.default.filter(row => day === -1 || (idByDay[day] || []).includes(row.id)), _fp.default.sortBy([row => -row.priority, row => row.api_type[2], row => row.api_type[3], row => row.api_name]))(data);
181
+
182
+ return (0, _search.filterImprovementRows)(rows, this.state.listSearchQuery);
183
+ }
184
+ }), Object.defineProperty(this, "renderInterfaceSwitch", {
185
+ configurable: true,
186
+ enumerable: true,
187
+ writable: true,
188
+ value: () => _react.default.createElement(_reactBootstrap.Checkbox, {
189
+ inline: true,
190
+ className: "new-interface-toggle",
191
+ checked: this.state.useNewInterface,
192
+ onChange: this.handleNewInterfaceChange
193
+ }, __('Use new interface'))
194
+ }), Object.defineProperty(this, "renderLegacyToolbar", {
195
+ configurable: true,
196
+ enumerable: true,
197
+ writable: true,
198
+ value: () => _react.default.createElement("div", {
199
+ className: "improvement-toolbar"
200
+ }, _react.default.createElement(_reactBootstrap.Nav, {
201
+ className: "main-nav",
202
+ bsStyle: "pills",
203
+ activeKey: this.state.day,
204
+ onSelect: this.handleKeyChange
205
+ }, _react.default.createElement(_reactBootstrap.NavItem, {
206
+ eventKey: 0
207
+ }, __('Sunday')), _react.default.createElement(_reactBootstrap.NavItem, {
208
+ eventKey: 1
209
+ }, __('Monday')), _react.default.createElement(_reactBootstrap.NavItem, {
210
+ eventKey: 2
211
+ }, __('Tuesday')), _react.default.createElement(_reactBootstrap.NavItem, {
212
+ eventKey: 3
213
+ }, __('Wednesday')), _react.default.createElement(_reactBootstrap.NavItem, {
214
+ eventKey: 4
215
+ }, __('Thursday')), _react.default.createElement(_reactBootstrap.NavItem, {
216
+ eventKey: 5
217
+ }, __('Friday')), _react.default.createElement(_reactBootstrap.NavItem, {
218
+ eventKey: 6
219
+ }, __('Saturday')), _react.default.createElement(_reactBootstrap.NavItem, {
220
+ eventKey: -1
221
+ }, __('All')), _react.default.createElement(_reactBootstrap.NavItem, {
222
+ eventKey: PLAN_VIEW_KEY
223
+ }, __('Starcraft'))), this.renderInterfaceSwitch(), _react.default.createElement(_reactBootstrap.Button, {
224
+ bsSize: "small",
225
+ bsStyle: "link",
226
+ className: "changelog-button",
227
+ onClick: this.handleShowChangelog
228
+ }, __("What's New")))
229
+ }), Object.defineProperty(this, "renderNewToolbar", {
230
+ configurable: true,
231
+ enumerable: true,
232
+ writable: true,
233
+ value: () => {
234
+ const isPlan = this.state.day === PLAN_VIEW_KEY;
235
+ return _react.default.createElement("div", {
236
+ className: "new-interface-toolbar"
237
+ }, _react.default.createElement("div", {
238
+ className: "improvement-toolbar"
239
+ }, _react.default.createElement(_reactBootstrap.Nav, {
240
+ className: "main-nav interface-mode-nav",
241
+ bsStyle: "pills",
242
+ activeKey: isPlan ? 'plan' : 'query',
243
+ onSelect: this.handleModeChange
244
+ }, _react.default.createElement(_reactBootstrap.NavItem, {
245
+ eventKey: "query"
246
+ }, __('Improvement Query')), _react.default.createElement(_reactBootstrap.NavItem, {
247
+ eventKey: "plan"
248
+ }, __('Starcraft'))), this.renderInterfaceSwitch(), _react.default.createElement(_reactBootstrap.Button, {
249
+ bsSize: "small",
250
+ bsStyle: "link",
251
+ className: "changelog-button",
252
+ onClick: this.handleShowChangelog
253
+ }, __("What's New"))), !isPlan && _react.default.createElement(WeekdayNav, {
254
+ activeKey: this.state.day,
255
+ onSelect: this.handleKeyChange
256
+ }));
257
+ }
258
+ }), Object.defineProperty(this, "renderList", {
259
+ configurable: true,
260
+ enumerable: true,
261
+ writable: true,
262
+ value: () => {
263
+ const {
264
+ day,
265
+ listSearchQuery
266
+ } = this.state;
267
+ const {
268
+ plans
269
+ } = this.props;
270
+ const rows = this.getRows(day);
271
+ return _react.default.createElement("div", {
272
+ className: "improvement-list-content"
273
+ }, _react.default.createElement(_searchBox.SearchBox, {
274
+ value: listSearchQuery,
275
+ onChange: this.handleListSearchChange,
276
+ placeholder: __('Search improvement list'),
277
+ resultCount: rows.length
278
+ }), rows.map((row, index) => _react.default.createElement(_itemWrapper.ItemWrapper, {
279
+ index: index,
280
+ row: row,
281
+ key: row.id,
282
+ day: day,
283
+ plans: plans
284
+ })), rows.length === 0 && _react.default.createElement("div", {
285
+ className: "improvement-empty-state"
286
+ }, __('No matching equipment')));
110
287
  }
111
288
  }), _temp;
112
289
  }
@@ -126,20 +303,19 @@ const ItemInfoArea = (0, _reactRedux.connect)(state => ({
126
303
 
127
304
  render() {
128
305
  const {
129
- day
306
+ day,
307
+ useNewInterface
130
308
  } = this.state;
131
- const {
132
- plans
133
- } = this.props;
134
309
  return _react.default.createElement("div", {
135
- id: "item-improvement"
310
+ id: "item-improvement",
311
+ className: useNewInterface ? 'new-interface' : 'legacy-interface'
136
312
  }, _react.default.createElement("div", {
137
313
  className: "flex-column"
138
314
  }, _react.default.createElement("link", {
139
315
  rel: "stylesheet",
140
316
  href: (0, _pathExtra.join)(__dirname, '..', 'assets', 'main.css')
141
317
  }), _react.default.createElement(_reactBootstrap.Grid, {
142
- className: "vertical-center",
318
+ className: "vertical-center interface-header",
143
319
  style: {
144
320
  minHeight: 45
145
321
  }
@@ -148,45 +324,9 @@ const ItemInfoArea = (0, _reactRedux.connect)(state => ({
148
324
  style: {
149
325
  padding: 0
150
326
  }
151
- }, _react.default.createElement("div", {
152
- className: "improvement-toolbar"
153
- }, _react.default.createElement(_reactBootstrap.Nav, {
154
- className: "main-nav",
155
- bsStyle: "pills",
156
- activeKey: this.state.day,
157
- onSelect: this.handleKeyChange
158
- }, _react.default.createElement(_reactBootstrap.NavItem, {
159
- eventKey: 0
160
- }, __('Sunday')), _react.default.createElement(_reactBootstrap.NavItem, {
161
- eventKey: 1
162
- }, __('Monday')), _react.default.createElement(_reactBootstrap.NavItem, {
163
- eventKey: 2
164
- }, __('Tuesday')), _react.default.createElement(_reactBootstrap.NavItem, {
165
- eventKey: 3
166
- }, __('Wednesday')), _react.default.createElement(_reactBootstrap.NavItem, {
167
- eventKey: 4
168
- }, __('Thursday')), _react.default.createElement(_reactBootstrap.NavItem, {
169
- eventKey: 5
170
- }, __('Friday')), _react.default.createElement(_reactBootstrap.NavItem, {
171
- eventKey: 6
172
- }, __('Saturday')), _react.default.createElement(_reactBootstrap.NavItem, {
173
- eventKey: -1
174
- }, __('All')), _react.default.createElement(_reactBootstrap.NavItem, {
175
- eventKey: 10
176
- }, __('Starcraft'))), _react.default.createElement(_reactBootstrap.Button, {
177
- bsSize: "small",
178
- bsStyle: "link",
179
- className: "changelog-button",
180
- onClick: this.handleShowChangelog
181
- }, __("What's New"))))), _react.default.createElement(_reactBootstrap.Grid, {
327
+ }, useNewInterface ? this.renderNewToolbar() : this.renderLegacyToolbar())), _react.default.createElement(_reactBootstrap.Grid, {
182
328
  className: "list-container"
183
- }, this.state.day < 7 ? this.getRows(this.state.day).map((row, index) => _react.default.createElement(_itemWrapper.ItemWrapper, {
184
- index: index,
185
- row: row,
186
- key: row.id,
187
- day: day,
188
- plans: plans
189
- })) : _react.default.createElement(_starcraftArea.StarcraftArea, null))), _react.default.createElement(_changelogModal.ChangelogModal, {
329
+ }, day < 7 ? this.renderList() : _react.default.createElement(_starcraftArea.StarcraftArea, null))), _react.default.createElement(_changelogModal.ChangelogModal, {
190
330
  entries: this.state.changelogEntries,
191
331
  onHide: this.handleCloseChangelog,
192
332
  show: this.state.showChangelog
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+ exports.SearchBox = void 0;
5
+
6
+ var _react = _interopRequireDefault(require("react"));
7
+
8
+ var _propTypes = _interopRequireDefault(require("prop-types"));
9
+
10
+ var _reactBootstrap = require("react-bootstrap");
11
+
12
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
+
14
+ const {
15
+ __
16
+ } = window.i18n['poi-plugin-item-improvement2-beta'];
17
+
18
+ const SearchBox = ({
19
+ value,
20
+ onChange,
21
+ placeholder,
22
+ resultCount
23
+ }) => _react.default.createElement("div", {
24
+ className: "improvement-search-box"
25
+ }, _react.default.createElement(_reactBootstrap.InputGroup, null, _react.default.createElement(_reactBootstrap.InputGroup.Addon, null, _react.default.createElement("span", {
26
+ className: "glyphicon glyphicon-search",
27
+ "aria-hidden": "true"
28
+ })), _react.default.createElement(_reactBootstrap.FormControl, {
29
+ type: "search",
30
+ value: value,
31
+ placeholder: placeholder,
32
+ "aria-label": placeholder,
33
+ onChange: event => onChange(event.target.value)
34
+ }), value && _react.default.createElement(_reactBootstrap.InputGroup.Button, null, _react.default.createElement(_reactBootstrap.Button, {
35
+ "aria-label": __('Clear search'),
36
+ title: __('Clear search'),
37
+ onClick: () => onChange('')
38
+ }, _react.default.createElement("span", {
39
+ className: "glyphicon glyphicon-remove",
40
+ "aria-hidden": "true"
41
+ })))), typeof resultCount === 'number' && _react.default.createElement("span", {
42
+ className: "improvement-search-count"
43
+ }, __('Search results').replace('%d', resultCount)));
44
+
45
+ exports.SearchBox = SearchBox;
46
+ SearchBox.propTypes = {
47
+ value: _propTypes.default.string.isRequired,
48
+ onChange: _propTypes.default.func.isRequired,
49
+ placeholder: _propTypes.default.string.isRequired,
50
+ resultCount: _propTypes.default.number
51
+ };
52
+ SearchBox.defaultProps = {
53
+ resultCount: undefined
54
+ };
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+ exports.normalizeSearchText = exports.filterPlanEquipTypes = exports.filterImprovementRows = exports.matchesSearchQuery = void 0;
5
+
6
+ function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
7
+
8
+ const normalizeSearchText = value => String(value == null ? '' : value).normalize('NFKC').toLocaleLowerCase().replace(/\s+/g, ' ').trim();
9
+
10
+ exports.normalizeSearchText = normalizeSearchText;
11
+
12
+ const compactSearchValues = values => values.reduce((result, value) => {
13
+ if (Array.isArray(value)) {
14
+ return result.concat(compactSearchValues(value));
15
+ }
16
+
17
+ if (value !== undefined && value !== null && value !== '') {
18
+ result.push(value);
19
+ }
20
+
21
+ return result;
22
+ }, []);
23
+
24
+ const matchesSearchQuery = (values, query) => {
25
+ const normalizedQuery = normalizeSearchText(query);
26
+
27
+ if (!normalizedQuery) {
28
+ return true;
29
+ }
30
+
31
+ const haystack = normalizeSearchText(compactSearchValues(values).join(' '));
32
+ return normalizedQuery.split(' ').filter(Boolean).every(token => haystack.includes(token));
33
+ };
34
+
35
+ exports.matchesSearchQuery = matchesSearchQuery;
36
+
37
+ const improvementSearchValues = row => {
38
+ const routeValues = (row.improvementList || []).map(route => [route.routeType, route.routeId, (route.assistantList || []).map(assistant => [assistant.displayText, assistant.sourceText, assistant.shipIds]), (route.stageList || []).map(stage => [stage.stageText, stage.targetWeapon && stage.targetWeapon.id, stage.targetWeapon && stage.targetWeapon.name, (stage.consumables || []).map(consumable => [consumable.id, consumable.name])])]);
39
+ return [row.id, row.api_id, row.api_name, row.name, Object.keys(row.assistantTextByDay || {}).map(key => row.assistantTextByDay[key]), routeValues];
40
+ };
41
+
42
+ const filterImprovementRows = (rows, query) => (rows || []).filter(row => matchesSearchQuery(improvementSearchValues(row), query));
43
+
44
+ exports.filterImprovementRows = filterImprovementRows;
45
+
46
+ const equipmentSearchValues = (equip, equipType) => [equip && equip.id, equip && equip.api_id, equip && equip.name, equip && equip.api_name, equipType && equipType.api_id, equipType && equipType.api_name];
47
+
48
+ const filterPlanEquipTypes = (equipTypes, query) => {
49
+ const normalizedQuery = normalizeSearchText(query);
50
+
51
+ if (!normalizedQuery) {
52
+ return equipTypes || {};
53
+ }
54
+
55
+ return Object.keys(equipTypes || {}).reduce((result, key) => {
56
+ const equipType = equipTypes[key];
57
+ const categoryMatches = matchesSearchQuery([equipType.api_id, equipType.api_name], normalizedQuery);
58
+ const equips = categoryMatches ? equipType.equips : (equipType.equips || []).filter(equip => matchesSearchQuery(equipmentSearchValues(equip, equipType), normalizedQuery));
59
+
60
+ if (equips.length > 0) {
61
+ result[key] = _extends({}, equipType, {
62
+ equips
63
+ });
64
+ }
65
+
66
+ return result;
67
+ }, {});
68
+ };
69
+
70
+ exports.filterPlanEquipTypes = filterPlanEquipTypes;
@@ -29,6 +29,10 @@ var _divider = require("../divider");
29
29
 
30
30
  var _selectors = require("../selectors");
31
31
 
32
+ var _searchBox = require("../search-box");
33
+
34
+ var _search = require("../search");
35
+
32
36
  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } }
33
37
 
34
38
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@@ -38,6 +42,9 @@ function _extends() { _extends = Object.assign || function (target) { for (var i
38
42
  const {
39
43
  $
40
44
  } = window;
45
+ const {
46
+ __
47
+ } = window.i18n['poi-plugin-item-improvement2-beta'];
41
48
  window.store = _createStore.store;
42
49
  $('#fontawesome-css').setAttribute('href', require.resolve('font-awesome/css/font-awesome.css'));
43
50
 
@@ -121,6 +128,16 @@ class Starcraft extends _react.Component {
121
128
  this.viewRef = newRef;
122
129
  }
123
130
  });
131
+ Object.defineProperty(this, "handleSearchChange", {
132
+ configurable: true,
133
+ enumerable: true,
134
+ writable: true,
135
+ value: searchQuery => {
136
+ this.setState({
137
+ searchQuery
138
+ });
139
+ }
140
+ });
124
141
  Object.defineProperty(this, "handleRefToImage", {
125
142
  configurable: true,
126
143
  enumerable: true,
@@ -134,7 +151,8 @@ class Starcraft extends _react.Component {
134
151
  }
135
152
  });
136
153
  this.state = _extends({}, Starcraft.prepareAutoCollapse(props), {
137
- viewMode: false
154
+ viewMode: false,
155
+ searchQuery: ''
138
156
  });
139
157
  this.viewRef = null;
140
158
  }
@@ -175,8 +193,23 @@ class Starcraft extends _react.Component {
175
193
  } = this.props;
176
194
  const {
177
195
  equipTypeCollapsed,
178
- viewMode
196
+ viewMode,
197
+ searchQuery
179
198
  } = this.state;
199
+ const searchedEquipTypes = (0, _search.filterPlanEquipTypes)(equipTypes, searchQuery);
200
+ const visibleEquipTypes = viewMode ? Object.keys(searchedEquipTypes).reduce((result, key) => {
201
+ const equipType = searchedEquipTypes[key];
202
+ const equips = equipType.equips.filter(equip => plans[equip.id]);
203
+
204
+ if (equips.length > 0) {
205
+ result[key] = _extends({}, equipType, {
206
+ equips
207
+ });
208
+ }
209
+
210
+ return result;
211
+ }, {}) : searchedEquipTypes;
212
+ const resultCount = Object.keys(visibleEquipTypes).reduce((count, key) => count + visibleEquipTypes[key].equips.length, 0);
180
213
  return _react.default.createElement("div", {
181
214
  id: "starcraft-root",
182
215
  style: {
@@ -187,19 +220,26 @@ class Starcraft extends _react.Component {
187
220
  onToggleViewMode: this.handleToggleViewMode,
188
221
  onControlAction: this.handleControlAction,
189
222
  onExportAsImage: this.handleRefToImage
223
+ }), _react.default.createElement(_searchBox.SearchBox, {
224
+ value: searchQuery,
225
+ onChange: this.handleSearchChange,
226
+ placeholder: __('Search improvement plans'),
227
+ resultCount: resultCount
190
228
  }), _react.default.createElement(_divider.Divider, null), _react.default.createElement("div", {
191
229
  ref: this.updateRef
192
- }, Object.keys(equipTypes).map(k => {
193
- const et = equipTypes[k];
230
+ }, Object.keys(visibleEquipTypes).map(k => {
231
+ const et = visibleEquipTypes[k];
194
232
  return _react.default.createElement(_equipCategoryView.EquipCategoryView, {
195
233
  viewMode: viewMode,
196
234
  key: et.api_id,
197
- collapsed: Boolean(equipTypeCollapsed[k]),
235
+ collapsed: searchQuery ? false : Boolean(equipTypeCollapsed[k]),
198
236
  onToggle: this.handleToggle(k),
199
237
  equipType: et,
200
238
  plans: plans
201
239
  });
202
- })));
240
+ }), resultCount === 0 && _react.default.createElement("div", {
241
+ className: "improvement-empty-state"
242
+ }, __('No matching plans'))));
203
243
  }
204
244
 
205
245
  }
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+ exports.setUseNewInterface = exports.getUseNewInterface = exports.NEW_INTERFACE_CONFIG_KEY = void 0;
5
+ const NEW_INTERFACE_CONFIG_KEY = 'poi-plugin-item-improvement2-beta.useNewInterface';
6
+ exports.NEW_INTERFACE_CONFIG_KEY = NEW_INTERFACE_CONFIG_KEY;
7
+
8
+ const getUseNewInterface = config => config.get(NEW_INTERFACE_CONFIG_KEY, false) === true;
9
+
10
+ exports.getUseNewInterface = getUseNewInterface;
11
+
12
+ const setUseNewInterface = (config, enabled) => {
13
+ const value = Boolean(enabled);
14
+ config.set(NEW_INTERFACE_CONFIG_KEY, value);
15
+ return value;
16
+ };
17
+
18
+ exports.setUseNewInterface = setUseNewInterface;