Skip to content

Commit fab3088

Browse files
committed
Close #537 implement alphabetical sort in output
1 parent 22c8566 commit fab3088

File tree

3 files changed

+37
-6
lines changed

3 files changed

+37
-6
lines changed

src/app/components/generator/SourcePanel.tsx

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import { DataModel } from '@mcschema/core'
22
import { useCallback, useEffect, useRef, useState } from 'preact/hooks'
33
import { useLocale } from '../../contexts/index.js'
4-
import { useModel } from '../../hooks/index.js'
4+
import { useLocalStorage, useModel } from '../../hooks/index.js'
55
import { getOutput } from '../../schema/transformOutput.js'
66
import type { BlockStateRegistry } from '../../services/index.js'
7-
import { getSourceFormats, getSourceIndent, getSourceIndents, parseSource, stringifySource } from '../../services/index.js'
7+
import { getSourceFormats, getSourceIndent, getSourceIndents, parseSource, sortData, stringifySource } from '../../services/index.js'
88
import { Store } from '../../Store.js'
99
import { message } from '../../Utils.js'
1010
import { Btn, BtnMenu } from '../index.js'
@@ -30,6 +30,7 @@ export function SourcePanel({ name, model, blockStates, doCopy, doDownload, doIm
3030
const { locale } = useLocale()
3131
const [indent, setIndent] = useState(Store.getIndent())
3232
const [format, setFormat] = useState(Store.getFormat())
33+
const [sort, setSort] = useLocalStorage('misode_output_sort', 'schema')
3334
const [highlighting, setHighlighting] = useState(Store.getHighlighting())
3435
const [braceLoaded, setBraceLoaded] = useState(false)
3536
const download = useRef<HTMLAnchorElement>(null)
@@ -40,9 +41,12 @@ export function SourcePanel({ name, model, blockStates, doCopy, doDownload, doIm
4041
const editor = useRef<Editor>()
4142

4243
const getSerializedOutput = useCallback((model: DataModel, blockStates: BlockStateRegistry) => {
43-
const data = getOutput(model, blockStates)
44+
let data = getOutput(model, blockStates)
45+
if (sort === 'alphabetically') {
46+
data = sortData(data)
47+
}
4448
return stringifySource(data, format, indent)
45-
}, [indent, format])
49+
}, [indent, format, sort])
4650

4751
useEffect(() => {
4852
retransform.current = () => {
@@ -80,7 +84,7 @@ export function SourcePanel({ name, model, blockStates, doCopy, doDownload, doIm
8084
console.error(e)
8185
}
8286
}
83-
}, [model, blockStates, indent, format, highlighting])
87+
}, [model, blockStates, indent, format, sort, highlighting])
8488

8589
useEffect(() => {
8690
if (highlighting) {
@@ -156,7 +160,7 @@ export function SourcePanel({ name, model, blockStates, doCopy, doDownload, doIm
156160
editor.current.configure(indent, format === 'snbt' ? 'yaml' : format)
157161
retransform.current()
158162
}
159-
}, [indent, format, highlighting, braceLoaded])
163+
}, [indent, format, sort, highlighting, braceLoaded])
160164

161165
useEffect(() => {
162166
if (doCopy && model && blockStates) {
@@ -210,6 +214,8 @@ export function SourcePanel({ name, model, blockStates, doCopy, doDownload, doIm
210214
<Btn label={locale(`format.${key}`)} active={format === key}
211215
onClick={() => changeFormat(key)} />)}
212216
<hr />
217+
<Btn icon={sort === 'alphabetically' ? 'square_fill' : 'square'} label={locale('sort_alphabetically')}
218+
onClick={() => setSort(sort === 'alphabetically' ? 'schema' : 'alphabetically')} />
213219
<Btn icon={highlighting ? 'square_fill' : 'square'} label={locale('highlighting')}
214220
onClick={() => changeHighlighting(!highlighting)} />
215221
</BtnMenu>

src/app/services/Source.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,27 @@ export function getSourceIndents() {
6060
export function getSourceFormats() {
6161
return Object.keys(FORMATS)
6262
}
63+
64+
export function sortData(data: any): any {
65+
if (typeof data !== 'object' || data === null) {
66+
return data
67+
}
68+
if (Array.isArray(data)) {
69+
return data.map(sortData)
70+
}
71+
const ordered = Object.create(null)
72+
for (const symbol of Object.getOwnPropertySymbols(data)) {
73+
ordered[symbol] = data[symbol]
74+
}
75+
const orderedKeys = Object.keys(data).sort(customOrder)
76+
for (const key of orderedKeys) {
77+
ordered[key] = sortData(data[key])
78+
}
79+
return ordered
80+
}
81+
82+
const priority = ['type', 'parent']
83+
function customOrder(a: string, b: string) {
84+
return (priority.indexOf(a) + 1 || Infinity) - (priority.indexOf(b) + 1 || Infinity)
85+
|| a.localeCompare(b)
86+
}

src/locales/en.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@
235235
"show_output": "Show output",
236236
"show_preview": "Show preview",
237237
"show_project": "Show project",
238+
"sort_alphabetically": "Sort alphabetically",
238239
"sounds.add_sound": "Add sound",
239240
"sounds.copy_command": "Copy command",
240241
"sounds.delay": "Delay",

0 commit comments

Comments
 (0)