Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions packages/components/frontend/autocomplete/AutoComplete.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -310,18 +310,20 @@ const AutoComplete = forwardRef(function Impl<T>(props: AutoCompleteProps<T>, re
)}
{focused && itemList.length > 0 && (
<ul ref={listRef} className="autocomplete-list" style={listStyle} onMouseDown={(e) => e.preventDefault()}>
{itemList.map((item, idx) => (
<li
{itemList.map((item, idx) => {
const inner = renderItem(item);
if (!inner) return null;
return <li
key={itemKey(item)}
onClick={() => toggleItem(item)}
onMouseMove={() => setCurrentItem(idx)}
data-selected={selectedKeys.includes(itemKey(item))}
data-focus={idx === currentItem}
>
<div>{renderItem(item)}</div>
<div>{inner}</div>
{selectedKeys.includes(itemKey(item)) && <Icon name="check" />}
</li>
))}
</li>;
})}
</ul>
)}
</div>
Expand Down
5 changes: 3 additions & 2 deletions packages/hydrooj/src/handler/contest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -305,11 +305,12 @@ export class ContestEditHandler extends Handler {
@param('contestDuration', Types.Float, true)
@param('maintainer', Types.NumericArray, true)
@param('allowViewCode', Types.Boolean)
@param('langs', Types.CommaSeperatedArray, true)
async postUpdate(
domainId: string, tid: ObjectId, beginAtDate: string, beginAtTime: string, duration: number,
title: string, content: string, rule: string, _pids: string, rated = false,
_code = '', autoHide = false, assign: string[] = [], lock: number = null,
contestDuration: number = null, maintainer: number[] = [], allowViewCode = false,
contestDuration: number = null, maintainer: number[] = [], allowViewCode = false, langs: string[] = [],
) {
if (autoHide) this.checkPerm(PERM.PERM_EDIT_PROBLEM);
const pids = _pids.replace(/,/g, ',').split(',').map((i) => +i).filter((i) => i);
Expand Down Expand Up @@ -350,7 +351,7 @@ export class ContestEditHandler extends Handler {
});
}
await contest.edit(domainId, tid, {
assign, _code, autoHide, lockAt, maintainer, allowViewCode,
assign, _code, autoHide, lockAt, maintainer, allowViewCode, langs,
});
this.response.body = { tid };
this.response.redirect = this.url('contest_detail', { tid });
Expand Down
4 changes: 3 additions & 1 deletion packages/hydrooj/src/handler/homework.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,11 +191,12 @@ class HomeworkEditHandler extends Handler {
@param('rated', Types.Boolean)
@param('maintainer', Types.NumericArray, true)
@param('assign', Types.CommaSeperatedArray, true)
@param('langs', Types.CommaSeperatedArray, true)
async postUpdate(
domainId: string, tid: ObjectId, beginAtDate: string, beginAtTime: string,
penaltySinceDate: string, penaltySinceTime: string, extensionDays: number,
penaltyRules: PenaltyRules, title: string, content: string, _pids: string, rated = false,
maintainer: number[] = [], assign: string[] = [],
maintainer: number[] = [], assign: string[] = [], langs: string[] = [],
) {
const pids = _pids.replace(/,/g, ',').split(',').map((i) => +i).filter((i) => i);
const tdoc = tid ? await contest.get(domainId, tid) : null;
Expand Down Expand Up @@ -226,6 +227,7 @@ class HomeworkEditHandler extends Handler {
rated,
maintainer,
assign,
langs,
});
if (tdoc.beginAt !== beginAt.toDate()
|| tdoc.endAt !== endAt.toDate()
Expand Down
1 change: 1 addition & 0 deletions packages/hydrooj/src/handler/problem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,7 @@ export class ProblemDetailHandler extends ContestDetailBaseHandler {
if (this.pdoc.config.langs) t.push(this.pdoc.config.langs);
if (ddoc.langs) t.push(ddoc.langs.split(',').map((i) => i.trim()).filter((i) => i));
if (this.domain.langs) t.push(this.domain.langs.split(',').map((i) => i.trim()).filter((i) => i));
if (this.tdoc?.langs) t.push(this.tdoc.langs);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also need check if tdoc.langs.length > 0, or none language can be submited.

if (this.pdoc.config.type === 'remote_judge') {
const p = this.pdoc.config.subType;
const dl = Object.keys(setting.langs).filter((i) => i.startsWith(`${p}.`) || setting.langs[i].validAs[p]);
Expand Down
1 change: 1 addition & 0 deletions packages/hydrooj/src/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,7 @@ export interface Tdoc extends Document {
autoHide?: boolean;
balloon?: Record<number, string | { color: string, name: string }>;
score?: Record<number, number>;
langs?: string[];

/**
* In hours
Expand Down
Original file line number Diff line number Diff line change
@@ -1,55 +1,25 @@
import { CustomSelectAutoComplete as CustomSelectAutoCompleteFC } from '@hydrooj/components';
import React from 'react';
import AutoComplete, { AutoCompleteOptions } from '.';

interface CustomSelectOptions {
data: any[]
}

const Component = React.forwardRef<any, any>((props, ref) => {
const [value, setValue] = React.useState(props.value);
return (
<CustomSelectAutoCompleteFC
ref={ref as any}
height="auto"
selectedKeys={value.split(',').map((i) => i.trim()).filter((i) => i)}
onChange={(v) => {
setValue(v);
props.onChange(v);
}}
data={props.data}
multi={props.multi}
/>
);
});

export default class CustomSelectAutoComplete<Multi extends boolean> extends AutoComplete<CustomSelectOptions> {
static DOMAttachKey = 'ucwCustomSelectAutoCompleteInstance';

constructor($dom, options: CustomSelectOptions & AutoCompleteOptions<Multi>) {
super($dom, {
classes: 'custom-select',
component: CustomSelectAutoCompleteFC,
props: {
data: options.data,
multi: options.multi,
height: 'auto',
},
...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();
this.component.render(
<Component
ref={(ref) => { this.ref = ref; }}
data={this.options.data}
value={value}
multi={this.options.multi}
onChange={this.onChange}
/>,
);
}
}

window.Hydro.components.CustomSelectAutoComplete = CustomSelectAutoComplete;
Original file line number Diff line number Diff line change
@@ -1,42 +1,20 @@
import React from 'react';
import AutoComplete from '.';
import DomainSelectAutoCompleteFC from './components/DomainSelectAutoComplete';

const Component = React.forwardRef((props: { value: string, multi: boolean, onChange: (v: string) => void }, ref) => {
const [value, setValue] = React.useState(props.value ?? '');
return (
<DomainSelectAutoCompleteFC
ref={ref as any}
height="34px"
selectedKeys={value.split(',').map((i) => i.trim()).filter((i) => i)}
onChange={(v) => {
setValue(v);
props.onChange(v);
}}
multi={props.multi}
/>
);
});

export default class DomainSelectAutoComplete extends AutoComplete {
static DOMAttachKey = 'ucwDomainSelectAutoCompleteInstance';

constructor($dom, options) {
super($dom, {
classes: 'domain-select',
component: DomainSelectAutoCompleteFC,
props: {
multi: options.multi,
height: '34px',
},
...options,
});
}

attach() {
const value = this.$dom.val();
this.component.render(<Component
ref={(ref) => { this.ref = ref; }}
value={value}
onChange={this.onChange}
multi={this.options.multi}
/>);
}
}

window.Hydro.components.DomainSelectAutoComplete = DomainSelectAutoComplete;
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import React from 'react';
import AutoComplete, { AutoCompleteOptions } from '.';
import FileSelectAutoCompleteFC from './components/FileSelectAutoComplete';

Expand All @@ -9,50 +8,21 @@ interface FileSelectOptions {
}[];
}

const Component = React.forwardRef<any, any>((props, ref) => {
const [value, setValue] = React.useState(props.value);
return (
<FileSelectAutoCompleteFC
ref={ref as any}
height="auto"
selectedKeys={value.split(',').map((i) => i.trim()).filter((i) => i)}
onChange={(v) => {
setValue(v);
props.onChange(v);
}}
data={props.data}
multi={props.multi}
/>
);
});

export default class FileSelectAutoComplete<Multi extends boolean> extends AutoComplete<FileSelectOptions> {
static DOMAttachKey = 'ucwFileSelectAutoCompleteInstance';

constructor($dom, options: FileSelectOptions & AutoCompleteOptions<Multi>) {
super($dom, {
classes: 'custom-select',
Comment thread
undefined-moe marked this conversation as resolved.
Outdated
component: FileSelectAutoCompleteFC,
props: {
data: options.data,
multi: options.multi,
height: 'auto',
},
...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();
this.component.render(
<Component
ref={(ref) => { this.ref = ref; }}
data={this.options.data}
value={value}
multi={this.options.multi}
onChange={this.onChange}
/>,
);
}
}

window.Hydro.components.FileSelectAutoComplete = FileSelectAutoComplete;
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import AutoComplete, { AutoCompleteOptions } from '.';
import LanguageSelectAutoCompleteFC from './components/LanguageSelectAutoComplete';

interface LanguageSelectOptions {
multi?: boolean;
withAuto?: boolean;
}

export class LanguageSelectAutoComplete<Multi extends boolean> extends AutoComplete<LanguageSelectOptions> {
static DOMAttachKey = 'ucwLanguageSelectAutoCompleteInstance';

constructor($dom, options: LanguageSelectOptions & AutoCompleteOptions<Multi>) {
super($dom, {
classes: 'language-select',
component: LanguageSelectAutoCompleteFC,
props: {
multi: options.multi,
withAuto: options.withAuto,
height: 'auto',
},
...options,
});
}
}

window.Hydro.components.LanguageSelectAutoComplete = LanguageSelectAutoComplete;
Original file line number Diff line number Diff line change
@@ -1,44 +1,20 @@
import React from 'react';
import AutoComplete from '.';
import ProblemSelectAutoCompleteFC from './components/ProblemSelectAutoComplete';

const Component = React.forwardRef<any, any>((props, ref) => {
const [value, setValue] = React.useState(props.value ?? '');
return (
<ProblemSelectAutoCompleteFC
ref={ref as any}
height="auto"
selectedKeys={value.split(',').map((i) => i.trim()).filter((i) => i)}
onChange={(v) => {
setValue(v);
props.onChange(v);
}}
multi={props.multi}
/>
);
});

export default class ProblemSelectAutoComplete extends AutoComplete {
static DOMAttachKey = 'ucwProblemSelectAutoCompleteInstance';

constructor($dom, options) {
super($dom, {
classes: 'problem-select',
component: ProblemSelectAutoCompleteFC,
props: {
multi: options.multi,
height: 'auto',
},
...options,
});
}

attach() {
const value = this.$dom.val();
this.component.render(
<Component
ref={(ref) => { this.ref = ref; }}
value={value}
multi={this.options.multi}
onChange={this.onChange}
/>,
);
}
}

window.Hydro.components.ProblemSelectAutoComplete = ProblemSelectAutoComplete;
Original file line number Diff line number Diff line change
@@ -1,29 +1,17 @@
import React from 'react';
import AutoComplete, { AutoCompleteOptions } from '.';
import UserSelectAutoCompleteFC from './components/UserSelectAutoComplete';

const Component = React.forwardRef<any, any>((props, ref) => {
const [value, setValue] = React.useState(props.value ?? '');
return (
<UserSelectAutoCompleteFC
ref={ref as any}
height="auto"
selectedKeys={value.split(',').map((i) => i.trim()).filter((i) => i)}
onChange={(v) => {
setValue(v);
props.onChange(v);
}}
multi={props.multi}
/>
);
});

export default class UserSelectAutoComplete<Multi extends boolean> extends AutoComplete {
static DOMAttachKey = 'ucwUserSelectAutoCompleteInstance';

constructor($dom, options: AutoCompleteOptions<Multi>) {
super($dom, {
classes: 'user-select',
component: UserSelectAutoCompleteFC,
props: {
multi: options.multi,
height: 'auto',
},
...options,
});
}
Expand All @@ -32,18 +20,6 @@ export default class UserSelectAutoComplete<Multi extends boolean> extends AutoC
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();
this.component.render(
<Component
ref={(ref) => { this.ref = ref; }}
value={value}
multi={this.options.multi}
onChange={this.onChange}
/>,
);
}
}

window.Hydro.components.UserSelectAutoComplete = UserSelectAutoComplete;
Loading
Loading