@ihabdevteam/core 0.150.0 โ 0.151.0
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/CHANGELOG.md +51 -0
- package/dist/components.cjs.js +199 -186
- package/dist/components.esm.css +5 -5
- package/dist/hooks.cjs.js +5 -1
- package/dist/i18n.cjs.js +3 -3
- package/dist/ihabdevteam-core-tokens.css +1 -1
- package/dist/ihabdevteam-core.cjs.js +200 -187
- package/dist/ihabdevteam-core.css +1 -1
- package/dist/ihabdevteam-core.d.ts +405 -67
- package/dist/packages/core/src/components/Accordion.d.ts +6 -0
- package/dist/packages/core/src/components/Accordion.js +5 -2
- package/dist/packages/core/src/components/Alert.d.ts +7 -1
- package/dist/packages/core/src/components/Alert.js +12 -3
- package/dist/packages/core/src/components/BarChart.js +7 -2
- package/dist/packages/core/src/components/Board.d.ts +5 -2
- package/dist/packages/core/src/components/Board.js +9 -3
- package/dist/packages/core/src/components/BottomNav.js +5 -4
- package/dist/packages/core/src/components/Breadcrumb.css +9 -0
- package/dist/packages/core/src/components/Breadcrumb.d.ts +12 -1
- package/dist/packages/core/src/components/Breadcrumb.js +8 -2
- package/dist/packages/core/src/components/BulkBar.css +2 -0
- package/dist/packages/core/src/components/BulkBar.js +21 -2
- package/dist/packages/core/src/components/Button.d.ts +12 -2
- package/dist/packages/core/src/components/Button.js +70 -13
- package/dist/packages/core/src/components/Calendar.d.ts +6 -1
- package/dist/packages/core/src/components/Calendar.js +3 -3
- package/dist/packages/core/src/components/DatePicker.d.ts +7 -1
- package/dist/packages/core/src/components/DatePicker.js +25 -15
- package/dist/packages/core/src/components/Dropdown.d.ts +1 -0
- package/dist/packages/core/src/components/Dropdown.js +7 -5
- package/dist/packages/core/src/components/Effect/EffectPartyPopperHost.d.ts +12 -1
- package/dist/packages/core/src/components/Effect/EffectPartyPopperHost.js +25 -8
- package/dist/packages/core/src/components/EmptyState.d.ts +5 -1
- package/dist/packages/core/src/components/EmptyState.js +4 -1
- package/dist/packages/core/src/components/ErrorState.d.ts +5 -2
- package/dist/packages/core/src/components/ErrorState.js +3 -1
- package/dist/packages/core/src/components/FileUpload.d.ts +9 -1
- package/dist/packages/core/src/components/FileUpload.js +8 -2
- package/dist/packages/core/src/components/FilterSectionInfo.js +14 -2
- package/dist/packages/core/src/components/Header.js +8 -5
- package/dist/packages/core/src/components/HearingDeviceInfo.js +2 -1
- package/dist/packages/core/src/components/Icon.d.ts +2 -1
- package/dist/packages/core/src/components/Icon.js +4 -1
- package/dist/packages/core/src/components/Loader.css +28 -0
- package/dist/packages/core/src/components/Loader.d.ts +5 -1
- package/dist/packages/core/src/components/Loader.js +4 -2
- package/dist/packages/core/src/components/NoticeBox.d.ts +1 -1
- package/dist/packages/core/src/components/NoticeBox.js +15 -6
- package/dist/packages/core/src/components/PanelRow.js +2 -1
- package/dist/packages/core/src/components/PassCard/PassCard.d.ts +8 -2
- package/dist/packages/core/src/components/PassCard/PassCard.js +25 -10
- package/dist/packages/core/src/components/PassCard/passCardProduct.d.ts +1 -1
- package/dist/packages/core/src/components/PassCard/passCardProduct.js +11 -2
- package/dist/packages/core/src/components/Popup/ConfirmPopup.d.ts +11 -2
- package/dist/packages/core/src/components/Popup/ConfirmPopup.js +18 -3
- package/dist/packages/core/src/components/Popup/DeviceSideTable.js +10 -8
- package/dist/packages/core/src/components/Popup/ListPopup.js +6 -6
- package/dist/packages/core/src/components/Popup/LoadTablePopup.css +7 -0
- package/dist/packages/core/src/components/Popup/LoadTablePopup.js +27 -5
- package/dist/packages/core/src/components/Popup/Popup.d.ts +8 -0
- package/dist/packages/core/src/components/Popup/Popup.js +6 -3
- package/dist/packages/core/src/components/Popup/SaveTablePopup.d.ts +5 -1
- package/dist/packages/core/src/components/Popup/TrainingResultPopup.css +3 -0
- package/dist/packages/core/src/components/Popup/TrainingResultPopup.d.ts +5 -0
- package/dist/packages/core/src/components/Popup/TrainingResultPopup.js +10 -4
- package/dist/packages/core/src/components/Popup/WordDataUpdatePopup.css +9 -0
- package/dist/packages/core/src/components/ProgressIndicator.css +5 -0
- package/dist/packages/core/src/components/ProgressIndicator.d.ts +3 -1
- package/dist/packages/core/src/components/ProgressIndicator.js +5 -3
- package/dist/packages/core/src/components/PromoBannerBg/promoBannerBg.d.ts +4 -1
- package/dist/packages/core/src/components/PromoBannerBg/promoBannerBg.js +27 -15
- package/dist/packages/core/src/components/Rating.d.ts +8 -2
- package/dist/packages/core/src/components/Rating.js +22 -8
- package/dist/packages/core/src/components/Report/ReportDocument.d.ts +10 -7
- package/dist/packages/core/src/components/Report/ReportDocument.js +39 -13
- package/dist/packages/core/src/components/RingChart.d.ts +1 -1
- package/dist/packages/core/src/components/RingChart.js +1 -1
- package/dist/packages/core/src/components/SegmentedControl.d.ts +4 -0
- package/dist/packages/core/src/components/SegmentedControl.js +9 -1
- package/dist/packages/core/src/components/ShortcutBadge.css +16 -1
- package/dist/packages/core/src/components/ShortcutBadge.d.ts +1 -0
- package/dist/packages/core/src/components/SideNav.js +8 -2
- package/dist/packages/core/src/components/SummaryStrip.d.ts +1 -1
- package/dist/packages/core/src/components/SummaryStrip.js +2 -2
- package/dist/packages/core/src/components/Table.d.ts +1 -1
- package/dist/packages/core/src/components/Table.js +4 -1
- package/dist/packages/core/src/components/Tabs.d.ts +1 -0
- package/dist/packages/core/src/components/Tabs.js +4 -1
- package/dist/packages/core/src/components/TextField.css +5 -6
- package/dist/packages/core/src/components/TextField.js +46 -3
- package/dist/packages/core/src/components/Toast.js +16 -2
- package/dist/packages/core/src/components/Tooltip/Tooltip.css +3 -1
- package/dist/packages/core/src/components/Tooltip/Tooltip.js +5 -2
- package/dist/packages/core/src/components/Tooltip/tooltipConstants.d.ts +10 -2
- package/dist/packages/core/src/components/Tooltip/tooltipConstants.js +10 -2
- package/dist/packages/core/src/components/TopBanner.d.ts +1 -1
- package/dist/packages/core/src/components/TopBanner.js +66 -8
- package/dist/packages/core/src/components/Training/AudioPlayerWaveForm.d.ts +1 -0
- package/dist/packages/core/src/components/Training/AudioPlayerWaveForm.js +65 -15
- package/dist/packages/core/src/components/Training/NoisePlayerContext.d.ts +3 -2
- package/dist/packages/core/src/components/Training/NoisePlayerContext.js +10 -4
- package/dist/packages/core/src/components/Training/TrainingBlockButton.css +7 -0
- package/dist/packages/core/src/components/Training/TrainingBlockButton.js +3 -1
- package/dist/packages/core/src/components/Training/TrainingPagePopup.d.ts +18 -5
- package/dist/packages/core/src/components/Training/TrainingPagePopup.js +93 -28
- package/dist/packages/core/src/components/Training/TrainingPagePopupBottom.d.ts +1 -0
- package/dist/packages/core/src/components/Training/TrainingPagePopupBottom.js +16 -3
- package/dist/packages/core/src/components/Training/TrainingStepAudioPlayer.js +25 -9
- package/dist/packages/core/src/components/Training/TrainingStepCard.js +19 -3
- package/dist/packages/core/src/components/Training/TrainingStepTitle.js +15 -1
- package/dist/packages/core/src/components/Training/TrainingWordCard.css +16 -0
- package/dist/packages/core/src/components/Training/TrainingWordCard.d.ts +6 -0
- package/dist/packages/core/src/components/Training/TrainingWordCard.js +7 -2
- package/dist/packages/core/src/components/Training/trainingBlockButtonTypes.d.ts +2 -2
- package/dist/packages/core/src/components/Training/trainingMissStats.d.ts +10 -0
- package/dist/packages/core/src/components/Training/trainingMissStats.js +19 -1
- package/dist/packages/core/src/components/Training/useFloatingFocus.d.ts +13 -0
- package/dist/packages/core/src/components/Training/useFloatingFocus.js +59 -0
- package/dist/packages/core/src/components/Training/useNoiseFade.js +20 -11
- package/dist/packages/core/src/components/Training/useProgressTicker.d.ts +0 -18
- package/dist/packages/core/src/components/Training/useProgressTicker.js +59 -14
- package/dist/packages/core/src/components/Training/useTTSPlayback.d.ts +1 -1
- package/dist/packages/core/src/components/Training/useTTSPlayback.js +56 -25
- package/dist/packages/core/src/components/Training/useWaveReady.d.ts +4 -1
- package/dist/packages/core/src/components/Training/useWaveReady.js +17 -8
- package/dist/packages/core/src/components/UpdateAlert.css +4 -2
- package/dist/packages/core/src/components/UpdateAlert.d.ts +3 -1
- package/dist/packages/core/src/components/UpdateAlert.js +21 -1
- package/dist/packages/core/src/components/Word/PhonemeSelectBlock.d.ts +2 -0
- package/dist/packages/core/src/components/Word/PhonemeSelectBlock.js +12 -4
- package/dist/packages/core/src/components/Word/WordSearchResultBlock.d.ts +6 -0
- package/dist/packages/core/src/components/Word/WordSearchResultBlock.js +26 -13
- package/dist/packages/core/src/components/Word/WordTableBlock.js +24 -21
- package/dist/packages/core/src/components/Word/WordTableThumbnail.js +1 -1
- package/dist/packages/core/src/components/Word/useWordTableDisplaySettings.js +7 -10
- package/dist/packages/core/src/components/Word/useWordTablePrint.d.ts +1 -1
- package/dist/packages/core/src/components/Word/useWordTablePrint.js +9 -3
- package/dist/packages/core/src/components/Word/wordScoreStats.d.ts +14 -1
- package/dist/packages/core/src/components/Word/wordScoreStats.js +7 -3
- package/dist/packages/core/src/components/Word/wordTablePrint.js +15 -3
- package/dist/packages/core/src/components/Word/wordTableReview.d.ts +58 -1
- package/dist/packages/core/src/components/Word/wordTableReview.js +75 -17
- package/dist/packages/core/src/components/Word/wordTableSettings.d.ts +9 -0
- package/dist/packages/core/src/components/Word/wordTableSettings.js +11 -0
- package/dist/packages/core/src/components/WordTable.css +10 -0
- package/dist/packages/core/src/components/WordTable.js +39 -26
- package/dist/packages/core/src/components/barChartTypes.d.ts +2 -2
- package/dist/packages/core/src/components/buttonTypes.d.ts +8 -0
- package/dist/packages/core/src/components/updateAlertStack.d.ts +2 -0
- package/dist/packages/core/src/components/updateAlertStack.js +68 -0
- package/dist/packages/core/src/components/useCalendarMonth.d.ts +4 -1
- package/dist/packages/core/src/components/useCalendarMonth.js +6 -3
- package/dist/packages/core/src/components/useComboboxSuggestions.d.ts +7 -0
- package/dist/packages/core/src/components/useComboboxSuggestions.js +21 -2
- package/dist/packages/core/src/components/wordTableLayout.d.ts +4 -0
- package/dist/packages/core/src/components/wordTableLayout.js +6 -0
- package/dist/packages/core/src/components.d.ts +2 -1
- package/dist/packages/core/src/components.js +1 -1
- package/dist/packages/core/src/hooks/bodyScrollLock.js +8 -2
- package/dist/packages/core/src/hooks/focusReturn.d.ts +12 -0
- package/dist/packages/core/src/hooks/focusReturn.js +49 -0
- package/dist/packages/core/src/hooks/touchToggle.d.ts +22 -0
- package/dist/packages/core/src/hooks/touchToggle.js +114 -0
- package/dist/packages/core/src/hooks/useAnchoredMenu.d.ts +12 -3
- package/dist/packages/core/src/hooks/useAnchoredMenu.js +37 -3
- package/dist/packages/core/src/hooks/useDailyTrainingSelection.d.ts +4 -2
- package/dist/packages/core/src/hooks/useDailyTrainingSelection.js +23 -11
- package/dist/packages/core/src/hooks/useIcon.js +29 -5
- package/dist/packages/core/src/hooks/useLucideIcon.d.ts +4 -0
- package/dist/packages/core/src/hooks/useLucideIcon.js +4 -0
- package/dist/packages/core/src/hooks/usePendingPress.d.ts +9 -0
- package/dist/packages/core/src/hooks/usePendingPress.js +26 -0
- package/dist/packages/core/src/hooks/usePrefersReducedMotion.d.ts +15 -0
- package/dist/packages/core/src/hooks/usePrefersReducedMotion.js +26 -0
- package/dist/packages/core/src/hooks/useTablePaging.d.ts +27 -2
- package/dist/packages/core/src/hooks/useTablePaging.js +37 -5
- package/dist/packages/core/src/hooks/useWordAttributeFilter.d.ts +7 -0
- package/dist/packages/core/src/hooks/useWordAttributeFilter.js +25 -0
- package/dist/packages/core/src/i18n/index.js +9 -1
- package/dist/packages/core/src/i18n/locales/en.json +24 -2
- package/dist/packages/core/src/i18n/locales/ko.json +24 -2
- package/dist/packages/core/src/tokens.css +5 -0
- package/dist/packages/core/src/types/wordSearch.d.ts +12 -0
- package/dist/packages/core/src/utils/csv.d.ts +7 -2
- package/dist/packages/core/src/utils/csv.js +12 -5
- package/dist/packages/core/src/utils/dailySelectionUtils.js +44 -14
- package/dist/packages/core/src/utils/date.d.ts +8 -0
- package/dist/packages/core/src/utils/date.js +44 -10
- package/dist/packages/core/src/utils/format.d.ts +1 -1
- package/dist/packages/core/src/utils/format.js +6 -7
- package/dist/packages/core/src/utils/noiseSettingsStore.d.ts +7 -3
- package/dist/packages/core/src/utils/phonemeConvert.d.ts +9 -0
- package/dist/packages/core/src/utils/phonemeConvert.js +11 -0
- package/dist/packages/core/src/utils/phonemePairSearch.d.ts +7 -1
- package/dist/packages/core/src/utils/phonemePairSearch.js +45 -21
- package/dist/packages/core/src/utils/safeHref.d.ts +8 -0
- package/dist/packages/core/src/utils/safeHref.js +24 -0
- package/dist/packages/core/src/utils/savedWordTables.d.ts +19 -3
- package/dist/packages/core/src/utils/savedWordTables.js +27 -19
- package/dist/packages/core/src/utils/textSort.d.ts +9 -0
- package/dist/packages/core/src/utils/textSort.js +37 -1
- package/dist/packages/core/src/utils/wordAttributeFilterCodes.d.ts +31 -0
- package/dist/packages/core/src/utils/wordAttributeFilterCodes.js +163 -0
- package/dist/packages/core/src/utils/wordContrast.d.ts +4 -2
- package/dist/packages/core/src/utils/wordContrast.js +8 -2
- package/dist/packages/core/src/utils/wordTrainingGenerators.d.ts +5 -2
- package/dist/packages/core/src/utils/wordTrainingGenerators.js +52 -2
- package/dist/packages/core/src/utils/wordTrainingPool.js +2 -2
- package/dist/packages/core/src/utils/wordTrainingRuntime.js +15 -7
- package/dist/packages/core/src/utils/wordTrainingRuntimeTypes.d.ts +1 -1
- package/dist/packages/core/src/utils/wordTrainingRuntimeTypes.js +5 -4
- package/dist/packages/core/src/utils/wornDate.d.ts +12 -0
- package/dist/packages/core/src/utils/wornDate.js +15 -0
- package/dist/packages/core/src/version.d.ts +1 -1
- package/dist/packages/core/src/version.js +1 -1
- package/dist/utils.cjs.js +2 -2
- package/package.json +1 -1
|
@@ -10,9 +10,15 @@ export interface WordSearchResultGroup {
|
|
|
10
10
|
/** @public */
|
|
11
11
|
export interface WordSearchResultBlockProps {
|
|
12
12
|
titleIcon?: string;
|
|
13
|
+
/**
|
|
14
|
+
* ๊ฒ์ ๊ฒฐ๊ณผ ์ โ ์ ๋ชฉ "์ด N๊ฐ" ์ ์ด๋ค. **๊ฒ์ ํ๋ฉด์ด๋ผ๋ ํ์์ด๊ธฐ๋ ํ๋ค**: ์ด๊ฒ๋ `searchQuery` ๋ ์ฃผ์ง ์์ผ๋ฉด
|
|
15
|
+
* ์ ์ฅ๋ ๋ชฉ๋ก์ ๋ณด์ฌ ์ฃผ๋ ๊ฒ์ผ๋ก ๋ณด๊ณ (๊ณต์ ์ด๋) ๋ฐ์ ์์๋ฅผ ๊ธฐ๋ณธ ์ ๋ ฌ๋ก ๋๋ค('๋ฐ์ ์์' ์ ํ์ง๊ฐ ์๊ธด๋ค).
|
|
16
|
+
*/
|
|
13
17
|
resultCount?: number;
|
|
14
18
|
resultUnit?: string;
|
|
19
|
+
/** ๊ฒ์์ด โ ํ ๋ฑ๋ง์ด๋ฉด '์์ ์ฐ์ ' ์ ๊ธฐ๋ณธ ์ ๋ ฌ๋ก ์ด๋ค */
|
|
15
20
|
searchQuery?: string;
|
|
21
|
+
/** ๋ณด์ผ ํญ๋ชฉ. ๊ฒ์์ดยท๊ฒฐ๊ณผ ์ ์์ด ์ด๊ฒ๋ง ์ฃผ๋ฉด ๋ฐ์ ์์ ๊ทธ๋๋ก๊ฐ ๊ธฐ๋ณธ์ด๋ค */
|
|
16
22
|
items: WordSearchResultItem[];
|
|
17
23
|
groups?: WordSearchResultGroup[];
|
|
18
24
|
selected?: string[];
|
|
@@ -37,31 +37,38 @@ export default function WordSearchResultBlock({ titleIcon, resultCount, resultUn
|
|
|
37
37
|
const rawQuery = (searchQuery ?? '').trim();
|
|
38
38
|
const q = /^[^,[\]\s]+$/.test(rawQuery) ? rawQuery : '';
|
|
39
39
|
const hasQuery = q.length > 0;
|
|
40
|
+
/* **๊ฒ์์ด๋ ๊ฒฐ๊ณผ ์๋ ์์ด items ๋ง ๋ฐ์ผ๋ฉด ๊ฒ์ ๊ฒฐ๊ณผ๊ฐ ์๋๋ผ ์ ์ฅ๋ ๋ชฉ๋ก์ ๋ณด์ฌ ์ฃผ๋ ๊ฒ**(๋ง๊ท ๊ณต์ ๋งํฌ ์ด๋ โ
|
|
41
|
+
์น๋ฃ์ฌ๊ฐ ํ์์ ๋์ด ์ฎ๊ธด ์์๊ฐ ์ ์ฅ๋ผ ์๋ค). ๊ทธ๋๋ ๋ฐ์ ์์๋ฅผ ๊ธฐ๋ณธ์ผ๋ก ๋๋ค โ ๊ฐ๋๋ค๋ก ๋ค์ ๋์ด์
|
|
42
|
+
ํ์ ์นธ ์์๊ฐ ์ฌ๋ผ์ก๋ค. ๊ฒ์ ํ๋ฉด๋ค์ ๊ฒฐ๊ณผ ์(resultCount)๋ฅผ ๋ ์ฃผ๋ฏ๋ก ์ง๊ธ์ฒ๋ผ ๊ฐ๋๋ค ยท ์์ ์ฐ์ ์ด๋ค. */
|
|
43
|
+
const ์ด๋ = searchQuery === undefined && resultCount === undefined;
|
|
44
|
+
const ๊ธฐ๋ณธ์ ๋ ฌ = hasQuery ? 'match' : ์ด๋ ? 'original' : 'ganada';
|
|
40
45
|
// ์ฒซ ๋ ๋์ ์ด๋ฏธ ๊ฒ์์ด๊ฐ ์์ด๋ '์์ ์ฐ์ '์ผ๋ก ์์ํ๋ค โ ์๋ ์กฐ์ ์ ๊ฒ์์ด ์ ๋ฌด๊ฐ **๋ฐ๋ ๋**๋ง ๋์์,
|
|
41
46
|
// ์ด๊น๊ฐ์ 'ganada' ๋ก ๊ณ ์ ํ๋ฉด ๊ฒ์์ด๋ฅผ ๋ค๊ณ ๋ง์ดํธํ ํ๋ฉด์ ๊ฐ๋๋ค์์ ๋จธ๋ฌผ๋ ๋ค.
|
|
42
|
-
const [sortKey, setSortKey] = useState(() =>
|
|
47
|
+
const [sortKey, setSortKey] = useState(() => ๊ธฐ๋ณธ์ ๋ ฌ);
|
|
43
48
|
const [pageSizeStr, setPageSizeStr] = useState('50');
|
|
44
49
|
const [page, setPage] = useState(1);
|
|
45
50
|
// ๊ฒ์์ด ์ ๋ฌด๊ฐ ๋ฐ๋๋ฉด ๊ทธ์ ๋ง๋ ๊ธฐ๋ณธ ์ ๋ ฌ๋ก ๋๋๋ฆฐ๋ค(๋ ๋ ์ค ์ํ ์กฐ์ ).
|
|
46
51
|
const [prevHasQuery, setPrevHasQuery] = useState(hasQuery);
|
|
47
52
|
if (prevHasQuery !== hasQuery) {
|
|
48
53
|
setPrevHasQuery(hasQuery);
|
|
49
|
-
setSortKey(
|
|
54
|
+
setSortKey(๊ธฐ๋ณธ์ ๋ ฌ);
|
|
50
55
|
}
|
|
51
|
-
const effectiveSortKey = (sortKey === 'match' && !hasQuery)
|
|
56
|
+
const effectiveSortKey = (sortKey === 'match' && !hasQuery) || (sortKey === 'original' && !์ด๋) ? ๊ธฐ๋ณธ์ ๋ ฌ : sortKey;
|
|
52
57
|
const sortOptions = useMemo(() => [
|
|
53
58
|
...(hasQuery ? [{ value: 'match', label: t('wordSearch.sort.match', { defaultValue: '์์ ์ฐ์ ' }) }] : []),
|
|
59
|
+
...(์ด๋ ? [{ value: 'original', label: t('wordSearch.sort.original', { defaultValue: '๋ฐ์ ์์' }) }] : []),
|
|
54
60
|
{ value: 'ganada', label: t('wordSearch.sort.ganada', { defaultValue: '๊ฐ๋๋ค์ โ' }) },
|
|
55
61
|
{ value: 'ganada_desc', label: t('wordSearch.sort.ganadaDesc', { defaultValue: '๊ฐ๋๋ค์ โ' }) },
|
|
56
62
|
{ value: 'syllable', label: t('wordSearch.sort.syllable', { defaultValue: '์์ ์ โ' }) },
|
|
57
63
|
{ value: 'syllable_desc', label: t('wordSearch.sort.syllableDesc', { defaultValue: '์์ ์ โ' }) },
|
|
58
64
|
{ value: 'grade', label: t('wordSearch.sort.grade', { defaultValue: '๋ฑ๊ธ์ โ' }) },
|
|
59
65
|
{ value: 'grade_desc', label: t('wordSearch.sort.gradeDesc', { defaultValue: '๋ฑ๊ธ์ โ' }) },
|
|
60
|
-
], [t, hasQuery]);
|
|
66
|
+
], [t, hasQuery, ์ด๋]);
|
|
61
67
|
const pageSizeOptions = useMemo(() => ['10', '25', '50', '100'].map(v => ({
|
|
62
68
|
value: v, label: t('wordSearch.pageSize', { count: Number(v), defaultValue: `${v}๊ฐ์ฉ ๋ณด๊ธฐ` }),
|
|
63
69
|
})), [t]);
|
|
64
|
-
|
|
70
|
+
/* ์ ์ฅ์์์ ์จ ํญ๋ชฉ์ words ๊ฐ ๋น ์ ธ ์์ ์ ์๋ค({ id }) โ ์ด ํ์ผ์ ๋ฑ๋ง์ ๋ `?? []` ๋ก ์ฝ๋๋ค */
|
|
71
|
+
const firstWord = (it) => it.words?.[0];
|
|
65
72
|
/* '์์ ์ฐ์ ' ์์๋ ๊ฒ์์ด๊ฐ ๋ฐ๋ ๋ ํ๋ณ๊ธฐ๋ฅผ ํ ๋ฒ ๋ง๋ค๊ณ ํญ๋ชฉ๋ง๋ค ํ ๋ฒ๋ง ์ผ๋ค โ ๋น๊ตํ ๋๋ง๋ค ๊ฒ์์ด๋ฅผ ๋ค์ ํผ์น๊ณ
|
|
66
73
|
localeCompare ๋ฅผ ๋ถ๋ฌ ๊ฒฐ๊ณผ๊ฐ ๋ฐ๋ ๋ 23k ๊ฐ์ 38ms ๊ฑธ๋ ธ๋ค. */
|
|
67
74
|
const ์์์์ = useMemo(() => {
|
|
@@ -71,7 +78,7 @@ export default function WordSearchResultBlock({ titleIcon, resultCount, resultUn
|
|
|
71
78
|
return (it) => {
|
|
72
79
|
let r = memo.get(it);
|
|
73
80
|
if (r === undefined) {
|
|
74
|
-
r = m((it.words[0]?.label ?? '').slice(0, qLen)) ? 0 : 1;
|
|
81
|
+
r = m((it.words?.[0]?.label ?? '').slice(0, qLen)) ? 0 : 1;
|
|
75
82
|
memo.set(it, r);
|
|
76
83
|
}
|
|
77
84
|
return r;
|
|
@@ -81,7 +88,12 @@ export default function WordSearchResultBlock({ titleIcon, resultCount, resultUn
|
|
|
81
88
|
const sortCompare = useCallback((a, b) => {
|
|
82
89
|
const label = (it) => firstWord(it)?.label ?? '';
|
|
83
90
|
const syll = (it) => firstWord(it)?.syllables ?? [...label(it)].length;
|
|
84
|
-
|
|
91
|
+
/* ๋ฑ๊ธ์ **์นธ์ ๋ฑ๋ง ์ค ๋ฎ์(์ซ์๊ฐ ์์) ๋ฑ๊ธ** โ ๋๋ฆฝ์์ ์ฒซ ๋ฑ๋ง๋ง ๋ณด๋ฉด ๋์งธ๊ฐ 1๋ฑ๊ธ์ธ ์์ด 3ยท3 ์ ๋ค๋ก ๊ฐ๋ค.
|
|
92
|
+
์์ง ๊ธฐ๋ณธ ์ ๋ ฌ(searchPairs ๊ฒฐ๊ณผ)๊ณผ ๊ฐ์ ์
์ด๋ผ, ๋ฑ๊ธ์์ ๊ณ ๋ฅด๋ ์๊ฐ ์ฐจ๋ก๊ฐ ๋ค๋ฐ๋์ง ์๋๋ค. ๋ฑ๊ธ ์๋ ๋ฑ๋ง์ ๋งจ ๋ค. */
|
|
93
|
+
const grade = (it) => (it.words ?? []).reduce((min, w) => {
|
|
94
|
+
const n = parseInt(w.grade ?? '', 10);
|
|
95
|
+
return Number.isFinite(n) && n < min ? n : min;
|
|
96
|
+
}, 999);
|
|
85
97
|
switch (effectiveSortKey) {
|
|
86
98
|
// ์์ ์ฐ์ โ ๊ฒ์์ด๋ก ์์ํ๋ ๋จ์ด๋ฅผ ์๋ก. ์ q ๊ธ์๋ง ์๋ผ ๋งค์นญํ๋ฉด "์ฒซ ์์ ๋ถํฐ ์ผ์น"๋ง
|
|
87
99
|
// ๋จ๋๋ค(์ด์ฑ ๊ฒ์๋ ๋์ผ: 'ใด' โ '๋๋ฌด'๊ฐ ์). ๋์์๋ ๊ฐ๋๋ค.
|
|
@@ -94,6 +106,7 @@ export default function WordSearchResultBlock({ titleIcon, resultCount, resultUn
|
|
|
94
106
|
case 'syllable_desc': return syll(b) - syll(a) || label(a).localeCompare(label(b), 'ko');
|
|
95
107
|
case 'grade': return grade(a) - grade(b) || label(a).localeCompare(label(b), 'ko');
|
|
96
108
|
case 'grade_desc': return grade(b) - grade(a) || label(a).localeCompare(label(b), 'ko');
|
|
109
|
+
// ๋ฐ์ ์์ โ Array.prototype.sort ๋ ์์ ์ ๋ ฌ์ด๋ผ 0 ์ด๋ฉด ๋ฐ์ ์ฐจ๋ก๊ฐ ๋จ๋๋ค
|
|
97
110
|
default: return 0;
|
|
98
111
|
}
|
|
99
112
|
}, [effectiveSortKey, ์์์์]);
|
|
@@ -149,17 +162,17 @@ export default function WordSearchResultBlock({ titleIcon, resultCount, resultUn
|
|
|
149
162
|
const isSelected = selected.includes(item.id);
|
|
150
163
|
return (_jsx("div", { onMouseEnter: e => {
|
|
151
164
|
openHover(e.currentTarget);
|
|
152
|
-
setHoverWords(item.words);
|
|
153
|
-
}, onMouseLeave: handleHoverLeave, children: _jsx(Button, { htmlType: "button", size: "word", align: "grid", label: item.words.map(w => w.label), subLabel: item.words.
|
|
154
|
-
? item.words.map(w => w.subLabel)
|
|
165
|
+
setHoverWords(item.words ?? []);
|
|
166
|
+
}, onMouseLeave: handleHoverLeave, children: _jsx(Button, { htmlType: "button", size: "word", align: "grid", label: (item.words ?? []).map(w => w.label), subLabel: (item.words ?? []).some(w => w.subLabel)
|
|
167
|
+
? (item.words ?? []).map(w => w.subLabel)
|
|
155
168
|
: undefined, selected: isSelected, onClick: () => handleClick(item.id), minWidth: 200 }) }, item.id));
|
|
156
169
|
}) }) }, group.label)))) : (_jsx("div", { className: "word-search-result-block__items", children: pagedItems.map((item) => {
|
|
157
170
|
const isSelected = selected.includes(item.id);
|
|
158
171
|
return (_jsx("div", { onMouseEnter: e => {
|
|
159
172
|
openHover(e.currentTarget);
|
|
160
|
-
setHoverWords(item.words);
|
|
161
|
-
}, onMouseLeave: handleHoverLeave, children: _jsx(Button, { htmlType: "button", size: "word", align: "grid", label: item.words.map(w => w.label), subLabel: item.words.
|
|
162
|
-
? item.words.map(w => w.subLabel)
|
|
173
|
+
setHoverWords(item.words ?? []);
|
|
174
|
+
}, onMouseLeave: handleHoverLeave, children: _jsx(Button, { htmlType: "button", size: "word", align: "grid", label: (item.words ?? []).map(w => w.label), subLabel: (item.words ?? []).some(w => w.subLabel)
|
|
175
|
+
? (item.words ?? []).map(w => w.subLabel)
|
|
163
176
|
: undefined, selected: isSelected, onClick: () => handleClick(item.id), minWidth: 200 }) }, item.id));
|
|
164
177
|
}) })), hoverWords && hoverAnchorRect && (_jsx(WordImageTooltip, { words: hoverWords, anchorRect: hoverAnchorRect }))] }), totalPages > 1 && (_jsx("div", { className: "word-search-result-block__pagination-bottom", children: _jsx(Pagination, { page: pageClamped, totalPages: totalPages, onChange: setPage }) })), (onClearSelection || onPrint) && (_jsxs("div", { className: "word-search-result-block__actions", children: [onClearSelection && (_jsx(Button, { htmlType: "button", size: "56", type: "bar", label: t('common.resetSelection', '์ ํ ์ด๊ธฐํ'), selected: false, disabled: selected.length === 0, onClick: selected.length === 0 ? undefined : onClearSelection })), onPrint && (_jsx("div", { onClick: selected.length === 0 ? onPrintEmpty : undefined, children: _jsx(Button, { htmlType: "button", size: "56", type: "bar", variant: "main", label: t('wordTable.title', '๋จ์ด ํ ๋ง๋ค๊ธฐ'), disabled: selected.length === 0, onClick: selected.length === 0 ? undefined : onPrint }) }))] }))] }));
|
|
165
178
|
}
|
|
@@ -12,7 +12,7 @@ import Popup from '../Popup/Popup';
|
|
|
12
12
|
import WordTable, { WORD_TABLE_PAPER } from '../WordTable';
|
|
13
13
|
import { chunkItems } from '../wordTableLayout';
|
|
14
14
|
import TableFilterPanel from './TableFilterPanel';
|
|
15
|
-
import { buildItemsPerPageSection, buildPageNumberSection, PAGE_NUM_POSITION_VALUE, parsePageNumberPosition } from './wordTableSettings';
|
|
15
|
+
import { buildItemsPerPageSection, buildPageNumberSection, PAGE_NUM_POSITION_VALUE, parsePageNumberPosition, itemsPerPageFromChoice } from './wordTableSettings';
|
|
16
16
|
import Toast from '../Toast';
|
|
17
17
|
import { useToastState } from '../../hooks/useToastState';
|
|
18
18
|
import { getImageResolver, checkImageExists } from '../../utils/imageConfig';
|
|
@@ -20,7 +20,7 @@ import { formatYmd, getTodayKst } from '../../utils/date';
|
|
|
20
20
|
import { getSavedTables } from '../../utils/savedWordTables';
|
|
21
21
|
import { devWarnOnce } from '../../utils/devWarn';
|
|
22
22
|
import { useWordTablePrint } from './useWordTablePrint';
|
|
23
|
-
import { CELL_COUNTS
|
|
23
|
+
import { CELL_COUNTS } from './wordTableBlockTypes';
|
|
24
24
|
// โโ ์ปดํฌ๋ํธ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
25
25
|
/** @public */
|
|
26
26
|
/** ํธ์ง ์นธ์ ๋ฑ๋ง โ ์ ์ฅ ํญ๋ชฉ์ ๋ฑ๋ง. ํธ์ง ์นธ์์ ๋ณด์ด๋ ๊ตฌ์ด์ฒด ๋ฐ์ยท๋ฑ๊ธยทํ์ฌยท์ ํ์ ๊ทธ๋๋ก ์ฎ๊ธด๋ค. */
|
|
@@ -102,19 +102,15 @@ export default function WordTableBlock({ title, titleIcon, disc, items, onSaveCo
|
|
|
102
102
|
if (onAddItem && !isEditable && !showCellCount) {
|
|
103
103
|
devWarnOnce('word-table-block-add-without-cell-count', '[WordTableBlock] ํ์ ๋ชจ๋์์ onAddItem ์ showCellCount ์ ํจ๊ป ์ค์ผ "์ถ๊ฐํ๊ธฐ" ์นธ์ด ์๊ธด๋ค.');
|
|
104
104
|
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
if (!isEditable)
|
|
110
|
-
setDisplayCellCount(prev => Math.max(prev, items?.length ?? 1));
|
|
111
|
-
}, [items?.length, isEditable]);
|
|
112
|
-
/* eslint-enable react-hooks/set-state-in-effect */
|
|
105
|
+
/* display ๋ชจ๋์์ ์นธ ์ ์กฐ์ ์ฉ ์ํ (showCellCount์ผ ๋๋ง ์ฌ์ฉ) โ **๊ณ ๋ฅธ ๊ฐ๋ง** ๋ ๋ค. ๋ณด์ด๋ ์นธ ์๋
|
|
106
|
+
max(๊ณ ๋ฅธ ๊ฐ, ํญ๋ชฉ ์) ๋ก ๊ทธ๋๊ทธ๋ ๋ธ๋ค. ์ ์๋ ๊ณ ๋ฅผ ๋์ ํญ๋ชฉ์ด ๋ ๋ max ๋ก ๊ตณํ, 6์นธ์ ๊ณจ๋ผ ๋ ํ์ 8๊ฐ๋ฅผ
|
|
107
|
+
๋ด์๋ค 3๊ฐ๋ก ์ค์ฌ๋ 8์นธ์ด ๋จ์๋ค. ์ฒ์ ๊ฐ์ ์ฒ์ ํญ๋ชฉ ์ โ ๊ณ ๋ฅด๊ธฐ ์ ์ ํ๋๋ฅผ ๋นผ๋ ํ๊ฐ ํ ์นธ ์ค์ด ํ๋ค๋ฆฌ์ง ์๊ฒ. */
|
|
108
|
+
const [chosenCellCount, setChosenCellCount] = useState(() => Math.max(items?.length ?? 1, 1));
|
|
113
109
|
// ๋ ์ด์์ ์นธ ์
|
|
114
110
|
const count = isEditable
|
|
115
111
|
? cellCount
|
|
116
112
|
: showCellCount
|
|
117
|
-
? Math.max(
|
|
113
|
+
? Math.max(chosenCellCount, items?.length ?? 1, 1)
|
|
118
114
|
: Math.max(items?.length ?? 0, 1);
|
|
119
115
|
const { width, height } = WORD_TABLE_PAPER[orientation];
|
|
120
116
|
// ํ์ด์ง ๋ถํ โ ํธ์ง/์นธ์์กฐ์ (showCellCount) ๋ชจ๋์์๋ ์ ์ฉํ์ง ์๊ณ , ์์ฑ๋ ํ์ ๋ชจ๋์์๋ง ์ ์ฉ
|
|
@@ -128,7 +124,7 @@ export default function WordTableBlock({ title, titleIcon, disc, items, onSaveCo
|
|
|
128
124
|
const isPaginated = !!pages && pages.length > 1;
|
|
129
125
|
const hasPairs = isEditable
|
|
130
126
|
? visibleCells.some(c => c !== null && c.length > 1)
|
|
131
|
-
: (items ?? []).some(item => item.words.length > 1);
|
|
127
|
+
: (items ?? []).some(item => (item.words ?? []).length > 1);
|
|
132
128
|
// PDF๋ก ์ ์ฅํ ๋ OS๊ฐ ์ ์ํ๋ ๊ธฐ๋ณธ ํ์ผ๋ช
. ์ ์ฅ๋ ํ ์ด๋ฆ์ด ์์ผ๋ฉด ๊ทธ๋๋ก, ์์ผ๋ฉด "์ค๋ ๋ ์ง + ๋จ์ดํ/๋๋ฆฝ์ํ"
|
|
133
129
|
const printFileName = tableName?.trim()
|
|
134
130
|
|| `${formatYmd(getTodayKst())} ${hasPairs ? t('wordTable.printFileNamePair', '๋๋ฆฝ์ํ') : t('wordTable.printFileNameSingle', '๋จ์ดํ')}`;
|
|
@@ -164,7 +160,7 @@ export default function WordTableBlock({ title, titleIcon, disc, items, onSaveCo
|
|
|
164
160
|
};
|
|
165
161
|
const hasColloquial = isEditable
|
|
166
162
|
? visibleCells.some(c => c?.some(e => !!e.colloquialPronunciation))
|
|
167
|
-
: (items ?? []).some(item => item.words.some(w => !!w.colloquialLabel));
|
|
163
|
+
: (items ?? []).some(item => (item.words ?? []).some(w => !!w.colloquialLabel));
|
|
168
164
|
// ํ์ ์ค์ ๋ก ์ด๋ฏธ์ง๊ฐ ์๋์ง โ resolver(word)๋ ์กด์ฌ ์ฌ๋ถ์ ๋ฌด๊ดํ๊ฒ ํญ์ URL์ ๋ง๋ค์ด ๋ฐํํ๋ฏ๋ก
|
|
169
165
|
// ๊ทธ truthiness๋ง์ผ๋ก๋ ํ์ ํ ์ ์๋ค(ํญ์ true๊ฐ ๋์ด ์ด๋ฏธ์ง ์๋ ํ์์๋ '์ด๋ฏธ์ง' ํ ๊ธ์ด
|
|
170
166
|
// ํ์ฑํ๋๋ ๋ฌธ์ ๊ฐ ์์๋ค). checkImageExists๋ก ์ค์ HEAD ์์ฒญ(+์บ์) ํ์ธ์ ๊ฑฐ์น๋ค.
|
|
@@ -176,7 +172,7 @@ export default function WordTableBlock({ title, titleIcon, disc, items, onSaveCo
|
|
|
176
172
|
return [];
|
|
177
173
|
return isEditable
|
|
178
174
|
? cells.slice(0, cellCount).flatMap(c => (c ?? []).map(e => [e.word, e.homonum]))
|
|
179
|
-
: (items ?? []).flatMap(item => item.words.map(w => [w.label, w.homonum]));
|
|
175
|
+
: (items ?? []).flatMap(item => (item.words ?? []).map(w => [w.label, w.homonum]));
|
|
180
176
|
}, [isEditable, cells, cellCount, items]);
|
|
181
177
|
/* ์ค์ ๋ก ํ์ผ์ด ์๋์ง๋ ๋ฌผ์ด๋ด์ผ ์๋ค(HEAD ์์ฒญ + ์บ์). ๊ทธ ๋ต๋ง ์ํ๋ก ๋ ๋ค.
|
|
182
178
|
`imagePairs` ๊ฐ ๋น๋ฉด ๋ฌผ์ด๋ณผ ๊ฒ๋ ์์ผ๋ฏ๋ก ์๋ ์ ๋์์ ๊ณง๋ฐ๋ก false ๊ฐ ๋๋ค. */
|
|
@@ -209,15 +205,13 @@ export default function WordTableBlock({ title, titleIcon, disc, items, onSaveCo
|
|
|
209
205
|
if (sectionLabel === t('wordTable.filter.columns', '์นธ ์')) {
|
|
210
206
|
if (isEditable)
|
|
211
207
|
handleCellCountChange(parseInt(value));
|
|
212
|
-
|
|
208
|
+
/* ๊ณ ๋ฅธ ๊ฐ์ ๊ทธ๋๋ก ๊ธฐ์ตํ๋ค โ ํญ๋ชฉ ์๋ณด๋ค ์ ๊ฒ ๊ณจ๋ผ๋ ๋ณด์ด๋ ์นธ ์(count)๋ max ๋ก ํญ๋ชฉ ์๋ฅผ ์งํค๊ณ ,
|
|
209
|
+
ํญ๋ชฉ์ด ์ค๋ฉด ๊ณ ๋ฅธ ๊ฐ์ผ๋ก ๋์๊ฐ๋ค */
|
|
213
210
|
else
|
|
214
|
-
|
|
211
|
+
setChosenCellCount(parseInt(value));
|
|
215
212
|
}
|
|
216
213
|
else if (sectionLabel === t(hasPairs ? 'wordTable.filter.itemsPerPagePair' : 'wordTable.filter.itemsPerPageWord')) {
|
|
217
|
-
|
|
218
|
-
์ ํ์ง([20, 8, 4, 2, 1])์ ์์ด ์ผ์ง ์นธ์ด ์๋๋ฐ ํ๋ 10๊ฐ์ฉ ๋๋์๋ค. */
|
|
219
|
-
const n = parseInt(value);
|
|
220
|
-
setItemsPerPageSetting(ITEMS_PER_PAGE_OPTIONS.includes(n) ? n : Number.POSITIVE_INFINITY);
|
|
214
|
+
setItemsPerPageSetting(itemsPerPageFromChoice(parseInt(value), itemCount));
|
|
221
215
|
}
|
|
222
216
|
else if (sectionLabel === t('wordTable.filter.pageNumber', 'ํ์ด์ง ๋ฒํธ')) {
|
|
223
217
|
setPageNumberPosition(parsePageNumberPosition(value));
|
|
@@ -230,6 +224,12 @@ export default function WordTableBlock({ title, titleIcon, disc, items, onSaveCo
|
|
|
230
224
|
words: c.map(ํญ๋ชฉ๋ฑ๋ง),
|
|
231
225
|
})))
|
|
232
226
|
: items ?? [];
|
|
227
|
+
/* ์ ์ฅํ ๋ค์๋ **์จ์ ์นธ(cellCount ๋ค)์ ๋น์ด๋ค** โ 2์นธ์ผ๋ก ์ค์ฌ ์ ์ฅํ ํ๋ฅผ 4์นธ์ผ๋ก ๋๋ฆฌ๋ฉด ์ ์ฅ๋ณธ์ ์๋
|
|
228
|
+
์
์งธยท๋ท์งธ ๋ฑ๋ง์ด ๋ค์ ๋ , ์ ์ฅํ ๊ฒ๊ณผ ํ๋ฉด์ด ๋ฌ๋๋ค. ์ ์ฅํ์ง ์๊ณ ์ค์๋ค ๋๋ฆฌ๋ ๋์์๋ ๊ทธ๋๋ก ๋ค๊ณ ์๋๋ค. */
|
|
229
|
+
const ์จ์์นธ๋น์ฐ๊ธฐ = () => {
|
|
230
|
+
if (isEditable)
|
|
231
|
+
setCells(prev => (prev.length > cellCount ? prev.slice(0, cellCount) : prev));
|
|
232
|
+
};
|
|
233
233
|
const handleSave = (asNew = false) => {
|
|
234
234
|
setSaveAsNew(asNew);
|
|
235
235
|
// ์ธ๋ผ์ธ ์ด๋ฆยท์ค๋ช
๋ชจ๋: ํ์
์์ด ํ๋ฉด์ ์ด๋ฆยท์ค๋ช
์ผ๋ก ์ฆ์ ์ ์ฅ(๋ฎ์ด์ฐ๊ธฐ). ๋น ๊ฐ์ ์ ์(placeholder)์ผ๋ก ๋์ฒด.
|
|
@@ -240,11 +240,13 @@ export default function WordTableBlock({ title, titleIcon, disc, items, onSaveCo
|
|
|
240
240
|
if (savedLower)
|
|
241
241
|
setSavedNames(prev => prev.includes(savedLower) ? prev : [...prev, savedLower]);
|
|
242
242
|
onSaveComplete(trimmedName, saveItems, trimmedDescription || undefined, asNew);
|
|
243
|
+
์จ์์นธ๋น์ฐ๊ธฐ();
|
|
243
244
|
return;
|
|
244
245
|
}
|
|
245
246
|
// saveOnly: ์ด๋ฆ ์
๋ ฅ ํ์
์์ด ๋ฐ๋ก ์ ์ฅ(์ด๋ฆ์ ์์์์ ์ฒ๋ฆฌ)
|
|
246
247
|
if (saveOnly && onSaveComplete) {
|
|
247
248
|
onSaveComplete('', saveItems, undefined, asNew);
|
|
249
|
+
์จ์์นธ๋น์ฐ๊ธฐ();
|
|
248
250
|
return;
|
|
249
251
|
}
|
|
250
252
|
if (onSaveComplete) {
|
|
@@ -267,6 +269,7 @@ export default function WordTableBlock({ title, titleIcon, disc, items, onSaveCo
|
|
|
267
269
|
if (!saveAsTrimmed || saveAsCollides || !onSaveComplete)
|
|
268
270
|
return;
|
|
269
271
|
onSaveComplete(saveAsTrimmed, saveItems, trimmedDescription || undefined, true);
|
|
272
|
+
์จ์์นธ๋น์ฐ๊ธฐ();
|
|
270
273
|
setShowSaveAsPopup(false);
|
|
271
274
|
};
|
|
272
275
|
// ์ ์ฅ ๋ฒํผ ํ์ฑ ์กฐ๊ฑด โ ์ธ๋ผ์ธ ๋ชจ๋์์ ์ด๋ฆ ํ์ยท์ค๋ณต(others) ๋ถ๊ฐ. ํญ๋ชฉ์ด ๋น์ด๋ ๋ถ๊ฐ.
|
|
@@ -294,7 +297,7 @@ export default function WordTableBlock({ title, titleIcon, disc, items, onSaveCo
|
|
|
294
297
|
items: saveItems,
|
|
295
298
|
existingNames: getSavedTables().map(tb => tb.name),
|
|
296
299
|
saveAsNew,
|
|
297
|
-
onSave: (name, description) => { onSaveComplete(name, saveItems, description, saveAsNew); setShowSavePopup(false); },
|
|
300
|
+
onSave: (name, description) => { onSaveComplete(name, saveItems, description, saveAsNew); ์จ์์นธ๋น์ฐ๊ธฐ(); setShowSavePopup(false); },
|
|
298
301
|
onCancel: () => setShowSavePopup(false),
|
|
299
302
|
}), (isEditable || onAddItem) && activeCell !== null && renderWordSearch?.({
|
|
300
303
|
cellIndex: activeCell,
|
|
@@ -16,6 +16,6 @@ export default function WordTableThumbnail({ items, className }) {
|
|
|
16
16
|
const item = items[i];
|
|
17
17
|
if (!item)
|
|
18
18
|
return _jsx("div", { className: "word-table-thumb__cell word-table-thumb__cell--empty" }, i);
|
|
19
|
-
return (_jsx("div", { className: "word-table-thumb__cell", children: (item.words
|
|
19
|
+
return (_jsx("div", { className: "word-table-thumb__cell", children: (item.words?.length ? item.words : [{ label: item.id }]).map((w, wi) => (_jsxs(Fragment, { children: [wi > 0 && _jsx("span", { className: "word-table-thumb__divider" }), _jsx("span", { className: "word-table-thumb__word body-3", children: w.label })] }, wi))) }, i));
|
|
20
20
|
}) }));
|
|
21
21
|
}
|
|
@@ -2,9 +2,8 @@
|
|
|
2
2
|
import { useMemo, useState, useCallback, useEffect } from 'react';
|
|
3
3
|
import { useTranslation } from 'react-i18next';
|
|
4
4
|
import { chunkItems } from '../wordTableLayout';
|
|
5
|
-
import { ITEMS_PER_PAGE_OPTIONS } from './wordTableBlockTypes';
|
|
6
5
|
import { getImageResolver, checkImageExists } from '../../utils/imageConfig';
|
|
7
|
-
import { buildCompositionSection, buildOrientationSection, buildBorderSection, buildCutLineSection, buildDivLineSection, buildItemsPerPageSection, buildPageNumberSection, buildTableSettingsSelected, applyTableSettingsSelect, PAGE_NUM_POSITION_VALUE, parsePageNumberPosition, } from './wordTableSettings';
|
|
6
|
+
import { buildCompositionSection, buildOrientationSection, buildBorderSection, buildCutLineSection, buildDivLineSection, buildItemsPerPageSection, buildPageNumberSection, buildTableSettingsSelected, applyTableSettingsSelect, PAGE_NUM_POSITION_VALUE, parsePageNumberPosition, itemsPerPageFromChoice, } from './wordTableSettings';
|
|
8
7
|
/**
|
|
9
8
|
* ํ์ ์ ์ฉ ๋จ์ดํ(ํธ์ง ์์)์ 'ํ ์ค์ ' FilterPanel ์ํยท์น์
์ ์ ๊ณตํ๋ ํ
.
|
|
10
9
|
* ๊ตฌ์ฑยท์ฉ์ง ๋ฐฉํฅยท์ธ๊ณฝ์ , ๋ด์ฉ์ด ์์ผ๋ฉด ํ์ด์ง๋น ๊ฐ์, 2ํ์ด์ง ์ด์์ด๋ฉด ํ์ด์ง ๋ฒํธ, ํญ๋ชฉ์ด 2๊ฐ ์ด์์ด๋ฉด
|
|
@@ -22,8 +21,9 @@ export function useWordTableDisplaySettings(items) {
|
|
|
22
21
|
const [itemsPerPageSetting, setItemsPerPageSetting] = useState(8);
|
|
23
22
|
const [pageNumberPosition, setPageNumberPosition] = useState('right');
|
|
24
23
|
const itemCount = items.length;
|
|
25
|
-
|
|
26
|
-
const
|
|
24
|
+
// ์ ์ฅ์์์ ์จ ํญ๋ชฉ์ words ๊ฐ ๋น ์ ธ ์์ ์ ์๋ค({ id }) โ ๋น ๋ฑ๋ง๋ก ๋ณธ๋ค
|
|
25
|
+
const hasPairs = items.some(item => (item.words ?? []).length > 1);
|
|
26
|
+
const hasColloquial = items.some(item => (item.words ?? []).some(w => !!w.colloquialLabel));
|
|
27
27
|
// ํ์ด์ง ๋ถํ โ ํ์ด์ง๋น ๊ฐ์(๊ธฐ๋ณธ 8, ์ค์ ๊ฐ์๋ณด๋ค ํฌ๋ฉด ์ ์ฒด๋ก ํด๋จํ)๋ก ๋๋๋ค. ํญ๋ชฉ์ด ์์ผ๋ฉด 1์นธ์ง๋ฆฌ ๋น ํ.
|
|
28
28
|
const effectiveItemsPerPage = Math.min(itemsPerPageSetting, Math.max(itemCount, 1));
|
|
29
29
|
const pages = useMemo(() => chunkItems(items, effectiveItemsPerPage), [items, effectiveItemsPerPage]);
|
|
@@ -41,7 +41,7 @@ export function useWordTableDisplaySettings(items) {
|
|
|
41
41
|
setHasImage(false);
|
|
42
42
|
return;
|
|
43
43
|
}
|
|
44
|
-
Promise.all(items.flatMap(item => item.words.map(w => checkImageExists(w.label, w.homonum))))
|
|
44
|
+
Promise.all(items.flatMap(item => (item.words ?? []).map(w => checkImageExists(w.label, w.homonum))))
|
|
45
45
|
.then(results => { if (!cancelled)
|
|
46
46
|
setHasImage(results.some(Boolean)); }, () => { }); // ๊ฑฐ์ ์ ์ด๋ฏธ์ง ์์์ผ๋ก ๋๋ค
|
|
47
47
|
return () => { cancelled = true; };
|
|
@@ -69,15 +69,12 @@ export function useWordTableDisplaySettings(items) {
|
|
|
69
69
|
if (applyTableSettingsSelect(t, value, sectionLabel, { setContentTypes, setOrientation, setShowOutline, setCutLine, setShowDivLine }))
|
|
70
70
|
return;
|
|
71
71
|
if (sectionLabel === t('wordTable.filter.itemsPerPagePair', 'ํ์ด์ง๋น ๋๋ฆฝ์ ์') || sectionLabel === t('wordTable.filter.itemsPerPageWord', 'ํ์ด์ง๋น ๋จ์ด ์')) {
|
|
72
|
-
|
|
73
|
-
์ ํ์ง([20, 8, 4, 2, 1])์ ์์ด ์ผ์ง ์นธ์ด ์๋๋ฐ ํ๋ 10๊ฐ์ฉ ๋๋์๋ค. */
|
|
74
|
-
const n = parseInt(value);
|
|
75
|
-
setItemsPerPageSetting(ITEMS_PER_PAGE_OPTIONS.includes(n) ? n : Number.POSITIVE_INFINITY);
|
|
72
|
+
setItemsPerPageSetting(itemsPerPageFromChoice(parseInt(value), itemCount));
|
|
76
73
|
}
|
|
77
74
|
else if (sectionLabel === t('wordTable.filter.pageNumber', 'ํ์ด์ง ๋ฒํธ')) {
|
|
78
75
|
setPageNumberPosition(parsePageNumberPosition(value));
|
|
79
76
|
}
|
|
80
|
-
}, [t]);
|
|
77
|
+
}, [t, itemCount]);
|
|
81
78
|
return {
|
|
82
79
|
settings: { orientation, contentTypes, cutLine, showOutline, showDivLine, count },
|
|
83
80
|
filterSections, filterSelected, handleSelect,
|
|
@@ -20,7 +20,7 @@ export interface UseWordTablePrintResult {
|
|
|
20
20
|
print: () => void;
|
|
21
21
|
/** ์ ํญ์ ๋จ์ดํ๋ฅผ ์ด์ด ์ฌ์ฉ์๊ฐ ์ง์ ์ธ์/์ ์ฅํ๊ฒ ํ๋ค. */
|
|
22
22
|
openNewWindow: () => void;
|
|
23
|
-
/** ๋จ์ดํ๋ฅผ ์ ์ HTML ํ์ผ๋ก ๋ค์ด๋ก๋ํ๋ค. */
|
|
23
|
+
/** ๋จ์ดํ๋ฅผ ์ ์ HTML ํ์ผ๋ก ๋ค์ด๋ก๋ํ๋ค. ํ์ผ๋ช
์ด ๋น๋ฉด(๊ฑธ๋ฌ ๋ด๊ณ ๋จ๋ ๊ธ์๊ฐ ์์ผ๋ฉด) ๊ธฐ๋ณธ ์ด๋ฆ('๋จ์ดํ'). */
|
|
24
24
|
downloadHtml: () => void;
|
|
25
25
|
}
|
|
26
26
|
/**
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { useCallback } from 'react';
|
|
3
|
+
import { useTranslation } from 'react-i18next';
|
|
3
4
|
import { captureHtml, printWordTableElements, sanitizeFileName } from './wordTablePrint';
|
|
5
|
+
/** ๋ด๋ ค๋ฐ๊ธฐ๋ฅผ ๋๋ฅธ ๋ค Blob ์ฃผ์๋ฅผ ํ์ํ๊ธฐ๊น์ง(utils/csv ์ ๊ฐ์ ๊ฐ) */
|
|
6
|
+
const BLOB_REVOKE_DELAY_MS = 1000;
|
|
4
7
|
/**
|
|
5
8
|
* ๋จ์ดํ ์ธ์/์์ฐฝ/๋ค์ด๋ก๋ ์ก์
์ ํ ๊ณณ์์ ์ ๊ณตํ๋ ํ
. WordTableBlockยทWordTablePopup ๋ฑ
|
|
6
9
|
* ๋จ์ดํ๋ฅผ ๋ณด์ฌ์ฃผ๋ ์ปดํฌ๋ํธ๊ฐ ๊ณต์ฉ์ผ๋ก ์ด๋ค. ์ค์ ๋ฌธ์ ์์ฑ์ wordTablePrint์ ์์ ํจ์๊ฐ,
|
|
@@ -8,6 +11,7 @@ import { captureHtml, printWordTableElements, sanitizeFileName } from './wordTab
|
|
|
8
11
|
* @public
|
|
9
12
|
*/
|
|
10
13
|
export function useWordTablePrint({ getElements, paperW, paperH, fileName = '', onPopupBlocked, header = '', }) {
|
|
14
|
+
const { t } = useTranslation();
|
|
11
15
|
const print = useCallback(() => {
|
|
12
16
|
printWordTableElements(getElements(), paperW, paperH, fileName, header);
|
|
13
17
|
}, [getElements, paperW, paperH, fileName, header]);
|
|
@@ -32,12 +36,14 @@ export function useWordTablePrint({ getElements, paperW, paperH, fileName = '',
|
|
|
32
36
|
const url = URL.createObjectURL(blob);
|
|
33
37
|
// fileName์ ์ฌ์ฉ์๊ฐ ์ง์ ํ ๋จ์ดํ ์ด๋ฆ ๋ฑ์์ ์ฌ ์ ์์ด, ํ์ผ์์คํ
์์ ๋ฌธ์ ๋๋
|
|
34
38
|
// ๋ฌธ์(\/:*?"<>|)๋ฅผ ์นํํ์ง ์์ผ๋ฉด ๋ค์ด๋ก๋ ํ์ผ๋ช
์ด ๊นจ์ง๊ฑฐ๋ ์ ์ฅ์ด ์คํจํ ์ ์๋ค.
|
|
35
|
-
|
|
39
|
+
/* ์ด๋ฆ์ด ๋น๋ฉด ๊ธฐ๋ณธ ์ด๋ฆ โ ๊ทธ๋๋ก ๋๋ฉด '.html' ์ด๋ผ๋ ์ด๋ฆ ์๋(์จ๊น) ํ์ผ์ด ๋ด๋ ค์๋ค. */
|
|
40
|
+
const safeFileName = (fileName ? sanitizeFileName(fileName) : '') || t('wordTable.printFileNameSingle', '๋จ์ดํ');
|
|
36
41
|
const a = Object.assign(document.createElement('a'), { href: url, download: `${safeFileName}.html` });
|
|
37
42
|
document.body.appendChild(a);
|
|
38
43
|
a.click();
|
|
39
44
|
document.body.removeChild(a);
|
|
40
|
-
|
|
41
|
-
|
|
45
|
+
/* ๊ณง๋ฐ๋ก ํ์ํ๋ฉด Safari ๊ฐ ๋ด๋ ค๋ฐ๊ธฐ๋ฅผ ์์ํ๊ธฐ ์ ์ ์ฃผ์๊ฐ ์ฌ๋ผ์ ธ ๋น ํ์ผยท์คํจ๊ฐ ๋๋ค โ ์กฐ๊ธ ๋ฆ์ถ๋ค */
|
|
46
|
+
setTimeout(() => URL.revokeObjectURL(url), BLOB_REVOKE_DELAY_MS);
|
|
47
|
+
}, [getElements, paperW, paperH, fileName, header, t]);
|
|
42
48
|
return { print, openNewWindow, downloadHtml };
|
|
43
49
|
}
|
|
@@ -13,12 +13,22 @@ export interface ScoreRecord {
|
|
|
13
13
|
tableId: string | null;
|
|
14
14
|
/** ์นธ ๋ฒํธ โ ํ์ */
|
|
15
15
|
marks: Record<string, ScoreMark>;
|
|
16
|
-
/**
|
|
16
|
+
/**
|
|
17
|
+
* ์นธ ๋ฒํธ โ ๊ทธ๋ ๋ณด์ธ ๋ฑ๋ง. ์ ๊ธฐ๋ก์๋ ์์ ์ ์๋ค.
|
|
18
|
+
* `cellKey` ๋ก ๋ํ์ด ๋ฒํธ๊น์ง ์ ์ด ๋๋ฉด(`๋ฐฐ#2`) `weakItems` ๊ฐ ๋ํ์ด๋ฅผ ๋ฐ๋ก ์ผ๋ค.
|
|
19
|
+
*/
|
|
17
20
|
labels: Record<string, string>;
|
|
18
21
|
}
|
|
19
22
|
/** ๋ฑ๋ง ํ๋์ ๋ํด ์์ธ ์ฑ์ . */
|
|
20
23
|
export interface WeakItem {
|
|
24
|
+
/** ๋ณด์ด๋ ๋ฑ๋ง โ ๋ํ์ด ๋ฒํธ๋ฅผ ๋ ๊ธ์(`๋ฐฐ`, `๋ฐฐ / ํจ`) */
|
|
21
25
|
label: string;
|
|
26
|
+
/**
|
|
27
|
+
* ๋ฌถ์ ์ด์ โ ์ ์ฅ๋ ์นธ ๋ฑ๋ง ๊ทธ๋๋ก. ๋ํ์ด ๋ฒํธ๊ฐ ์ ์ฅ๋ ๊ธฐ๋ก์ด๋ฉด `๋ฐฐ#2` ์ฒ๋ผ ๋ฒํธ๊ฐ ๋ถ๊ณ ,
|
|
28
|
+
* ์๋ ์ ๊ธฐ๋ก์ด๋ฉด `label` ๊ณผ ๊ฐ๋ค. ๊ฐ์ `label` ์ด ๋ ์ด์ ๋์ฌ ์ ์์ผ๋ ์ค ์ด์ ๋ก๋ ์ด๊ฒ์ ์ด๋ค.
|
|
29
|
+
* `weakItems` ๋ ๋ ์ฑ์ด๋ค โ ์ ํ ํ๋์ธ ๊ฒ์ ์ด ๋ชจ์์ ์์ผ๋ก ์ง๋ ์ชฝ(์ํ ๋ฑ)์ ๊นจ์ง ์์ผ๋ ค๋ ๊ฒ๋ฟ์ด๋ค.
|
|
30
|
+
*/
|
|
31
|
+
key?: string;
|
|
22
32
|
/** ์ด ๋ฑ๋ง์ ๋งค๊ธด ํ์ */
|
|
23
33
|
tried: number;
|
|
24
34
|
o: number;
|
|
@@ -40,6 +50,9 @@ export interface WeakItem {
|
|
|
40
50
|
*
|
|
41
51
|
* **๋ฑ๋ง์ด ์ ๋จ์ ์ ๊ธฐ๋ก์ ๊ฑด๋๋ด๋ค.** ์นธ ๋ฒํธ๋ก ํ๋ฅผ ๋์ง์ผ๋ฉด ๊ทธ ํ๊ฐ ๊ทธ๋์ ๋ฐ๋์์ ๋
|
|
42
52
|
* ์๋ฑํ ๋ฑ๋ง์ ๊ธฐ๋ก์ด ๋๋ค โ ์กฐ์ฉํ ํ๋ฆฌ๋๋ ๋นผ๋ ํธ์ด ๋ซ๋ค.
|
|
53
|
+
*
|
|
54
|
+
* **๋ํ์ด๋ ์ ์ฅ๋ ๋ฑ๋ง์ ๋ฒํธ๊ฐ ์์ ๋๋ง ๋ฐ๋ก ๋ฌถ๋๋ค**(`๋ฐฐ#1`ยท`๋ฐฐ#2`, `cellKey`). ๋ฒํธ ์์ด ์ ์ฅ๋ ์ ๊ธฐ๋ก์
|
|
55
|
+
* ์ง๊ธ์ฒ๋ผ ๊ธ์๋ก ๋ฌถ๋๋ค โ ๊ทธ๋์ ๊ฐ์ '๋ฐฐ' ๊ฐ ์ ๊ธฐ๋ก ํ ์คยท๋ฒํธ ์๋ ๊ธฐ๋ก ํ ์ค๋ก ๋๋์ด ๋ณด์ผ ์ ์๋ค.
|
|
43
56
|
*/
|
|
44
57
|
export declare function weakItems(records: readonly ScoreRecord[]): WeakItem[];
|
|
45
58
|
/** ํ ํ ๊ฐ์ ๋ํ ํ๋ฆ โ ๊ฐ์ ํ๋ฅผ ์ฌ๋ฌ ๋ฒ ๋๋ ธ์ ๋ ๋์์ง๊ณ ์๋๊ฐ. */
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ํ๊ธ์ } from '../../utils/textSort';
|
|
2
|
+
import { labelOfCellKey } from './wordTableReview';
|
|
2
3
|
/** โณ ๋ฅผ ๋ฐ ์ ์ผ๋ก ์น๋ ์
โ ์ ์ฅํ ๋ ์๋ฒ๊ฐ ์ฐ๋ ๊ท์น๊ณผ ๊ฐ๋ค. */
|
|
3
4
|
function ์ ์(o, triangle, marked) {
|
|
4
5
|
return marked === 0 ? 0 : (o + triangle * 0.5) / marked;
|
|
@@ -12,6 +13,9 @@ function ์ ์(o, triangle, marked) {
|
|
|
12
13
|
*
|
|
13
14
|
* **๋ฑ๋ง์ด ์ ๋จ์ ์ ๊ธฐ๋ก์ ๊ฑด๋๋ด๋ค.** ์นธ ๋ฒํธ๋ก ํ๋ฅผ ๋์ง์ผ๋ฉด ๊ทธ ํ๊ฐ ๊ทธ๋์ ๋ฐ๋์์ ๋
|
|
14
15
|
* ์๋ฑํ ๋ฑ๋ง์ ๊ธฐ๋ก์ด ๋๋ค โ ์กฐ์ฉํ ํ๋ฆฌ๋๋ ๋นผ๋ ํธ์ด ๋ซ๋ค.
|
|
16
|
+
*
|
|
17
|
+
* **๋ํ์ด๋ ์ ์ฅ๋ ๋ฑ๋ง์ ๋ฒํธ๊ฐ ์์ ๋๋ง ๋ฐ๋ก ๋ฌถ๋๋ค**(`๋ฐฐ#1`ยท`๋ฐฐ#2`, `cellKey`). ๋ฒํธ ์์ด ์ ์ฅ๋ ์ ๊ธฐ๋ก์
|
|
18
|
+
* ์ง๊ธ์ฒ๋ผ ๊ธ์๋ก ๋ฌถ๋๋ค โ ๊ทธ๋์ ๊ฐ์ '๋ฐฐ' ๊ฐ ์ ๊ธฐ๋ก ํ ์คยท๋ฒํธ ์๋ ๊ธฐ๋ก ํ ์ค๋ก ๋๋์ด ๋ณด์ผ ์ ์๋ค.
|
|
15
19
|
*/
|
|
16
20
|
export function weakItems(records) {
|
|
17
21
|
const ๋ชจ์ = new Map();
|
|
@@ -38,11 +42,11 @@ export function weakItems(records) {
|
|
|
38
42
|
}
|
|
39
43
|
}
|
|
40
44
|
const out = [];
|
|
41
|
-
for (const [
|
|
45
|
+
for (const [key, v] of ๋ชจ์) {
|
|
42
46
|
const tried = v.o + v.triangle + v.x;
|
|
43
|
-
out.push({ label, tried, o: v.o, triangle: v.triangle, x: v.x, rate: ์ ์(v.o, v.triangle, tried), latest: v.latest, latestAt: v.latestAt });
|
|
47
|
+
out.push({ label: labelOfCellKey(key), key, tried, o: v.o, triangle: v.triangle, x: v.x, rate: ์ ์(v.o, v.triangle, tried), latest: v.latest, latestAt: v.latestAt });
|
|
44
48
|
}
|
|
45
|
-
out.sort((a, b) => a.rate - b.rate || b.tried - a.tried || ํ๊ธ์(a.label, b.label));
|
|
49
|
+
out.sort((a, b) => a.rate - b.rate || b.tried - a.tried || ํ๊ธ์(a.label, b.label) || ํ๊ธ์(a.key ?? a.label, b.key ?? b.label));
|
|
46
50
|
return out;
|
|
47
51
|
}
|
|
48
52
|
/**
|
|
@@ -229,19 +229,31 @@ export function captureHtml(els, paperW, paperH, autoPrint = false, fileName = '
|
|
|
229
229
|
${autoPrint ? `
|
|
230
230
|
// document.write ์งํ ๋ฐ๋ก window.print()๋ฅผ ๋ถ๋ฅด๋ฉด ์ด๋ฏธ์ง(๋น๋๊ธฐ ๋ก๋)์
|
|
231
231
|
// ๋ ์ด์์์ด ์์ง ๋ฐ์๋๊ธฐ ์ ์ด๋ผ ๋น ํ์ด์ง๋ก ์ธ์๋๋ ๊ฒฝ์ฐ๊ฐ ์์ด,
|
|
232
|
-
// ๋ชจ๋ <img> ๋ก๋ ์๋ฃ + rAF 2ํฑ(๋ ์ด์์/ํ์ธํธ ํ์ ) ์ดํ์ ์ธ์ํ๋ค.
|
|
232
|
+
// ๋ชจ๋ <img> ๋ก๋ ์๋ฃ + ๊ธ๊ผด ์ค๋น(์ต๋ 1์ด) + rAF 2ํฑ(๋ ์ด์์/ํ์ธํธ ํ์ ) ์ดํ์ ์ธ์ํ๋ค.
|
|
233
|
+
// ๊ธ๊ผด์ ์ ๊ธฐ๋ค๋ฆฌ๋ฉด ์น ๊ธ๊ผด์ด ์ค๊ธฐ ์ ์ ์ธ์๋ผ ๊ธฐ๋ณธ ๊ธ๊ผด ์ข
์ด๊ฐ ๋์๋ค(document.fonts ๊ฐ ์์ผ๋ฉด ๊ธฐ๋ค๋ฆฌ์ง ์๋๋ค).
|
|
233
234
|
(function () {
|
|
234
235
|
var MAX_WAIT_MS = 3000;
|
|
236
|
+
var FONT_WAIT_MS = 1000;
|
|
235
237
|
var timedOut = false;
|
|
238
|
+
var printed = false;
|
|
236
239
|
var timer = setTimeout(function () { timedOut = true; afterReady(); }, MAX_WAIT_MS);
|
|
237
240
|
var pending = Array.prototype.filter.call(document.images, function (img) { return !img.complete; });
|
|
238
241
|
var remaining = pending.length;
|
|
239
|
-
function
|
|
240
|
-
if (
|
|
242
|
+
function printNow() {
|
|
243
|
+
if (printed) return;
|
|
244
|
+
printed = true;
|
|
241
245
|
requestAnimationFrame(function () {
|
|
242
246
|
requestAnimationFrame(function () { window.print(); });
|
|
243
247
|
});
|
|
244
248
|
}
|
|
249
|
+
function afterReady() {
|
|
250
|
+
if (timer) { clearTimeout(timer); timer = null; }
|
|
251
|
+
var fonts = null;
|
|
252
|
+
try { fonts = document.fonts && document.fonts.ready; } catch (e) { fonts = null; }
|
|
253
|
+
if (!fonts || typeof fonts.then !== 'function') { printNow(); return; }
|
|
254
|
+
setTimeout(printNow, FONT_WAIT_MS);
|
|
255
|
+
fonts.then(printNow, printNow);
|
|
256
|
+
}
|
|
245
257
|
if (remaining === 0) { afterReady(); return; }
|
|
246
258
|
pending.forEach(function (img) {
|
|
247
259
|
function done() { if (timedOut) return; remaining--; if (remaining <= 0) afterReady(); }
|
|
@@ -14,14 +14,53 @@ import type { ScoreMark } from './wordTableScoring';
|
|
|
14
14
|
* ์ด๋ฏธ ์๋ ํ์ ๋ฎ์ ์๋ ํธ์ด ์ฐ๊ธฐ์๋ ๋ซ๋ค.
|
|
15
15
|
*/
|
|
16
16
|
export declare function reviewCells<T>(items: readonly T[], marks: Record<string, ScoreMark | null | undefined>): T[];
|
|
17
|
+
/**
|
|
18
|
+
* ๋ณต์ตํ ์๋ ํ โ ์ด๋ฆ๊ณผ, ์์ผ๋ฉด **๋ณต์ต ๋ฉํ**.
|
|
19
|
+
*
|
|
20
|
+
* ์ด๋ฆ๋ง์ผ๋ก๋ ํ์ฐจ๋ฅผ ํ๋ฆฌ๊ฒ ์ฝ์ ๋๊ฐ ์๋ค. `์์
3์ฐจ` ๋ผ๋ ํ์ ๋ณต์ต(`์์
3์ฐจ ๋ณต์ต 09.15`)๊ณผ
|
|
21
|
+
* `์์
` ์ 3์ฐจ ๋ณต์ต(`์์
3์ฐจ ๋ณต์ต 09.15`)์ด **๊ฐ์ ์ด๋ฆ**์ด๋ผ, ๋ค์ ๋ณต์ตํ๋ฉด ๋ ๋ค `์์
4์ฐจ ๋ณต์ต` ์ด ๋๋ค.
|
|
22
|
+
* ๋ณต์ตํ๋ฅผ ์ ์ฅํ ๋ {@link reviewMeta} ์ ๊ฐ์ ํจ๊ป ๋จ๊ฒจ ๋๋ฉด ์ด๋ฆ์ ํ์ฑํ์ง ์๊ณ ๊ทธ ๊ฐ์ ์ด๋ค.
|
|
23
|
+
* ๋ฉํ๊ฐ ์๋ ์ ํ๋ ์ง๊ธ์ฒ๋ผ ์ด๋ฆ์ ํ์ฑํ๋ค.
|
|
24
|
+
*
|
|
25
|
+
* @public
|
|
26
|
+
*/
|
|
27
|
+
export interface ReviewSource {
|
|
28
|
+
/** ํ ์ด๋ฆ */
|
|
29
|
+
name: string;
|
|
30
|
+
/** ํ id โ ์ด ํ๊ฐ ์๋ณธ์ด๋ฉด ๋ณต์ตํ์ `reviewOf` ๊ฐ ๋๋ค */
|
|
31
|
+
id?: string;
|
|
32
|
+
/** ์ด ํ๊ฐ ๋ณต์ตํ๋ฉด **๋งจ ์ฒ์ ์๋ณธ ํ**์ id */
|
|
33
|
+
reviewOf?: string | null;
|
|
34
|
+
/**
|
|
35
|
+
* ์ด ํ๊ฐ ๋ช ๋ฒ์งธ ๋ณต์ต์ธ๊ฐ(1๋ถํฐ). `0` ์ "๋ณต์ตํ๊ฐ ์๋๋ค" โ ์ด๋ฆ์ด `โฆ ๋ณต์ต 09.01` ๊ผด์ด์ด๋ ๊ผฌ๋ฆฌ๋ก ๋ผ์ง ์๋๋ค.
|
|
36
|
+
* ์์ผ๋ฉด(`undefined`ยท`null`) ์ ํ๋ก ๋ณด๊ณ ์ด๋ฆ์ ํ์ฑํ๋ค.
|
|
37
|
+
*/
|
|
38
|
+
reviewRound?: number | null;
|
|
39
|
+
}
|
|
17
40
|
/**
|
|
18
41
|
* ๋ณต์ตํ ์ด๋ฆ.
|
|
19
42
|
*
|
|
20
43
|
* ์๋ ์ด๋ฆ์ ์์ ๋์ด **๋ชฉ๋ก์์ ๋๋ํ ๋ถ์ด ๋ณด์ด๊ฒ** ํ๋ค(๋๊ฐ ์ด๋ฆ์ยท์ต์ ์์ผ๋ก ๋ณธ๋ค).
|
|
21
44
|
* ๋ ์ง๋ฅผ ๋ถ์ด๋ ๊ฒ์ ๊ฐ์ ํ๋ฅผ ์ฌ๋ฌ ๋ฒ ๋๋ฆฌ๊ธฐ ๋๋ฌธ์ด๋ค โ ์์ผ๋ฉด ๊ฐ์ ์ด๋ฆ์ด ์์ฌ
|
|
22
45
|
* ์ด๋ ๊ฒ์ด ์ด๋ฒ ๊ฒ์ธ์ง ์ ์ ์๋ค.
|
|
46
|
+
*
|
|
47
|
+
* ์ด๋ฆ ํ์(`๋ฐํ [N์ฐจ ]๋ณต์ต MM.DD`)์ ์ ์ฅ๋ ์ด๋ฆยทํ์ฑ๊ณผ ๋ง์ถ๋๋ผ ๋ฐ๊พธ์ง ์๋๋ค.
|
|
48
|
+
* ์๋ ํ๋ฅผ {@link ReviewSource} ๋ก ๋๊ธฐ๋ฉด ๋ณต์ต ๋ฉํ(`reviewRound`)๋ฅผ ์ด๋ฆ ํ์ฑ๋ณด๋ค ๋จผ์ ์ด๋ค โ
|
|
49
|
+
* ์ ๋ณต์ตํ๋ฅผ ์ ์ฅํ ๋๋ {@link reviewMeta} ์ ๊ฐ์ ํจ๊ป ๋จ๊ธด๋ค. ๊ธ์๋ง ๋๊ธฐ๋ฉด ์ง๊ธ์ฒ๋ผ ์ด๋ฆ์ ํ์ฑํ๋ค.
|
|
50
|
+
*/
|
|
51
|
+
export declare function reviewTableName(original: string | ReviewSource, today: Date): string;
|
|
52
|
+
/**
|
|
53
|
+
* ์๋ก ๋ง๋ค ๋ณต์ตํ์ **ํจ๊ป ์ ์ฅํ ๋ฉํ** โ ๋งจ ์ฒ์ ์๋ณธ ํ id ์ ์ด๋ฒ์ด ๋ช ๋ฒ์งธ ๋ณต์ต์ธ์ง.
|
|
54
|
+
*
|
|
55
|
+
* `reviewOf` ๋ ์๋ ํ๊ฐ ๋ณต์ตํ๋ฉด ๊ทธ ํ์ `reviewOf` ๋ฅผ, ์๋๋ฉด ์๋ ํ์ `id` ๋ฅผ ์๋๋ค(๋ ๋ค ์์ผ๋ฉด `undefined`).
|
|
56
|
+
* `reviewRound` ๋ {@link reviewTableName} ์ด ์ด๋ฆ์ ์ ๋ ํ์ฐจ์ ๊ฐ๋ค(1 = ์ฒซ ๋ณต์ต).
|
|
57
|
+
*
|
|
58
|
+
* @public
|
|
23
59
|
*/
|
|
24
|
-
export declare function
|
|
60
|
+
export declare function reviewMeta(source: ReviewSource): {
|
|
61
|
+
reviewOf: string | undefined;
|
|
62
|
+
reviewRound: number;
|
|
63
|
+
};
|
|
25
64
|
/**
|
|
26
65
|
* ์นธ ๋ฒํธ โ ๊ทธ๋ ๋ณด์ธ ๋ฑ๋ง. ์ฑ์ ๊ณผ **ํจ๊ป ์ ์ฅํ๋ค.**
|
|
27
66
|
*
|
|
@@ -37,6 +76,24 @@ export declare function labelsForSave(labels: readonly string[], marks: Record<s
|
|
|
37
76
|
export declare function cellLabel(words: readonly {
|
|
38
77
|
label: string;
|
|
39
78
|
}[]): string;
|
|
79
|
+
/**
|
|
80
|
+
* ํ ์นธ์ ๋ฑ๋ง๋ค์ **๋ํ์ด ๋ฒํธ๊น์ง** ํ ์ค๋ก โ `๋ฐฐ#2 / ํจ`. ๋ฒํธ๊ฐ ์๋ ๋ฑ๋ง์ {@link cellLabel} ๊ณผ ๊ฐ๋ค.
|
|
81
|
+
*
|
|
82
|
+
* ์ฑ์ ๊ณผ ํจ๊ป ์ ์ฅํ๋ ์นธ ๋ฑ๋ง(`labelsForSave` ์ ๋๊ธธ ๊ฒ)๋ก ์ฐ๋ฉด `weakItems` ๊ฐ '๋ฐฐ'(1)ยท'๋ฐฐ'(2) ๋ฅผ ๋ฐ๋ก ์ผ๋ค.
|
|
83
|
+
* ๊ธ์๋ง(`cellLabel`) ์ ์ฅํ๋ฉด ๋์ ์ฑ์ ์ด ํ ์ค๋ก ํฉ์ณ์ง๋ค. ํ๋ฉด์ ๋ณด์ผ ๊ธ์๋ {@link labelOfCellKey} ๋ก ๋๋๋ฆฐ๋ค.
|
|
84
|
+
*
|
|
85
|
+
* @public
|
|
86
|
+
*/
|
|
87
|
+
export declare function cellKey(words: readonly {
|
|
88
|
+
label: string;
|
|
89
|
+
homonum?: number | null;
|
|
90
|
+
}[]): string;
|
|
91
|
+
/**
|
|
92
|
+
* {@link cellKey} ๋ก ๋ง๋ ์นธ ๋ฑ๋ง์์ ๋ํ์ด ๋ฒํธ๋ฅผ ๋ ๋ณด์ด๋ ๊ธ์ โ `๋ฐฐ#2 / ํจ` โ `๋ฐฐ / ํจ`. ๋ฒํธ๊ฐ ์์ผ๋ฉด ๊ทธ๋๋ก.
|
|
93
|
+
*
|
|
94
|
+
* @public
|
|
95
|
+
*/
|
|
96
|
+
export declare function labelOfCellKey(key: string): string;
|
|
40
97
|
/**
|
|
41
98
|
* ์ฑ์ ํ ํ๋ฅผ ์ธ์ํ ๋ ์ข
์ด ๋งจ ์์ ์ฐ๋ ํ ์ค.
|
|
42
99
|
*
|