diff --git a/packages/ui-default/components/autocomplete/CustomSelectAutoComplete.tsx b/packages/ui-default/components/autocomplete/CustomSelectAutoComplete.tsx new file mode 100644 index 000000000..501a6949d --- /dev/null +++ b/packages/ui-default/components/autocomplete/CustomSelectAutoComplete.tsx @@ -0,0 +1,60 @@ +import { assign } from 'lodash'; +import React from 'react'; +import ReactDOM from 'react-dom/client'; +import DOMAttachedObject from 'vj/components/DOMAttachedObject'; +import AutoComplete, { AutoCompleteOptions } from '.'; +import CustomSelectAutoCompleteFC from './components/CustomSelectAutoComplete'; + +interface CustomSelectOptions { + data: any[] +} + +const Component = React.forwardRef((props, ref) => { + const [value, setValue] = React.useState(props.value); + return ( + i.trim()).filter((i) => i)} + onChange={(v) => { + setValue(v); + props.onChange(v); + }} + data={props.data} + multi={props.multi} + /> + ); +}); + +export default class CustomSelectAutoComplete extends AutoComplete { + static DOMAttachKey = 'ucwCustomSelectAutoCompleteInstance'; + options: CustomSelectOptions & AutoCompleteOptions; + + constructor($dom, options: CustomSelectOptions & AutoCompleteOptions) { + super($dom, { + classes: 'custom-select', + ...options, + }); + } + + value(): Multi extends true ? number[] : string { + if (this.options.multi) return this.ref?.getSelectedItemKeys().map((i) => +i) ?? this.$dom.val(); + return this.ref?.getSelectedItems()[0] ?? null; + } + + attach() { + const value = this.$dom.val(); + ReactDOM.createRoot(this.container).render( + { this.ref = ref; }} + data={this.options.data} + value={value} + multi={this.options.multi} + onChange={this.onChange} + />, + ); + } +} + +assign(CustomSelectAutoComplete, DOMAttachedObject); +window.Hydro.components.CustomSelectAutoComplete = CustomSelectAutoComplete; diff --git a/packages/ui-default/locales/zh.yaml b/packages/ui-default/locales/zh.yaml index 8dac71002..965115b87 100644 --- a/packages/ui-default/locales/zh.yaml +++ b/packages/ui-default/locales/zh.yaml @@ -285,8 +285,6 @@ Download: 下载 Downvote: 差评 Duration (hours): 持续时间 (小时) Duration: 持续时间 -Edited: 已修改 -Edited at: 修改于 Edit any contests: 修改任意的比赛 Edit any homework: 修改任意的作业 Edit Contest: 编辑比赛 @@ -312,6 +310,8 @@ Edit problems: 修改题目 Edit Profile: 编辑个人信息 Edit training plans: 修改训练计划 Edit: 编辑 +Edited at: 修改于 +Edited: 已修改 Email Visibility: Email 可见性 Email: 电子邮件 Enabled: 开启 @@ -536,6 +536,7 @@ Not Enrolled: 未参加 Not started with a number: 不以数字开头 Not wrapped with space: 两侧不含空格 Numeric PID: 数字题号 +objective: 客观题 Oh, the user doesn't have any contributions!: 啊哦,这个用户还没贡献过题目~ Oh, the user hasn't created any discussions yet!: 这个用户还没有发布过讨论 Oh, the user hasn't submitted yet!: 这个用户还没有交过题 _(:зゝ∠)_ diff --git a/packages/ui-default/package.json b/packages/ui-default/package.json index 724cff267..69aed796a 100644 --- a/packages/ui-default/package.json +++ b/packages/ui-default/package.json @@ -1,6 +1,6 @@ { "name": "@hydrooj/ui-default", - "version": "4.42.14", + "version": "4.42.15", "author": "undefined ", "license": "AGPL-3.0", "main": "index.ts", diff --git a/packages/ui-default/pages/domain_edit.page.ts b/packages/ui-default/pages/domain_edit.page.ts new file mode 100644 index 000000000..57b78a099 --- /dev/null +++ b/packages/ui-default/pages/domain_edit.page.ts @@ -0,0 +1,25 @@ +import CustomSelectAutoComplete from 'vj/components/autocomplete/CustomSelectAutoComplete'; +import { NamedPage } from 'vj/misc/Page'; +import i18n from 'vj/utils/i18n'; + +const page = new NamedPage('domain_edit', () => { + const prefixes = new Set(Object.keys(window.LANGS).filter((i) => i.includes('.')).map((i) => i.split('.')[0])); + const langs = [ + { key: '_', name: i18n('objective') }, + ...Object.keys(window.LANGS).filter((i) => !prefixes.has(i)).map((i) => ( + { name: `${i.includes('.') ? `${window.LANGS[i.split('.')[0]].display}/` : ''}${window.LANGS[i].display}`, _id: i } + )), + ]; + + const $langSelect = $('[name=langs]'); + $langSelect.val(($langSelect.val() as string).split(',').filter((i) => !prefixes.has(i))); + + const select: CustomSelectAutoComplete = CustomSelectAutoComplete.getOrConstruct($('[name=langs]'), { multi: true, data: langs }); + select.onChange((val) => { + const value = val.split(','); + value.push(...Array.from(new Set(value.filter((i) => i.includes('.')).map((i) => i.split('.')[0])))); + $langSelect.val(value.join(',')); + }); +}); + +export default page;