bug fixes

This commit is contained in:
undefined committed 2025-03-31 23:25:38 +08:00
1 parent baa9436c30
commit 1a8232899c
12 files changed
+46 -35

No files matched your search

+1 -1
View File
@@ -4,7 +4,7 @@
"license": "MIT",
"main": "base.mjs",
"dependencies": {
"@eslint-react/eslint-plugin": "^1.38.3",
"@eslint-react/eslint-plugin": "^1.38.4",
"@eslint/compat": "^1.2.7",
"@eslint/eslintrc": "^3.3.1",
"@stylistic/eslint-plugin": "^4.2.0",
+2 -2
View File
@@ -35,7 +35,7 @@
"@types/autocannon": "^7.12.6",
"@types/chai": "^5.2.1",
"@types/cross-spawn": "^6.0.6",
"@types/node": "22.13.8",
"@types/node": "22.13.14",
"@types/semver": "^7.7.0",
"autocannon": "^8.0.0",
"cac": "^6.7.14",
@@ -44,7 +44,7 @@
"cross-spawn": "^7.0.6",
"esbuild": "0.25.0",
"eslint": "^9.23.0",
"eslint-import-resolver-typescript": "^4.2.5",
"eslint-import-resolver-typescript": "^4.3.1",
"eslint-import-resolver-webpack": "^0.13.10",
"fs-extra": "^11.3.0",
"globals": "^16.0.0",
+2 -2
View File
@@ -17,8 +17,7 @@ export interface LangConfig {
hidden: boolean;
isBinary?: boolean;
analysis?: string;
/** @deprecated */
remote?: string;
remote: boolean;
validAs?: Record<string, string>;
/** @deprecated */
pretest?: string | false;
@@ -51,6 +50,7 @@ export function parseLang(config: string): Record<string, LangConfig> {
entry.code_file ||= `foo.${key}`;
entry.execute ||= '/w/foo';
entry.key = key;
entry.remote = !!entry.remote;
entry.hidden ||= false;
entry.disabled ||= false;
entry.isBinary ||= false;
+18 -12
View File
@@ -15,10 +15,9 @@ const locales = {
function MonacoContainer({
config, setValue, setError, monaco, schema, editorCallback, size,
}) {
const editorRef = React.useRef<HTMLDivElement>(null);
const [loading, setLoading] = React.useState(false);
const [editor, setEditor] = React.useState<any>(null);
const [model, setModel] = React.useState<any>(null);
const [initialized, setInitialized] = React.useState(false);
const { codeFontFamily } = React.useContext(ComponentsContext);
React.useEffect(() => {
@@ -62,14 +61,14 @@ function MonacoContainer({
}
});
return () => disposable.dispose(); // eslint-disable-line
}, [editor, model, setValue, setError]);
React.useEffect(() => {
if (!editorRef.current || loading) return;
setLoading(true);
}, [editor, model, setValue, setError, schema]);
const initializeEditor = React.useCallback((element) => {
if (!element || initialized) return;
setInitialized(true);
// eslint-disable-next-line
const model = monaco.editor.createModel(config, 'yaml', monaco.Uri.parse('hydro://system/setting.yaml'));
setModel(model);
const e = monaco.editor.create(editorRef.current, {
const e = monaco.editor.create(element, {
theme: 'vs-light',
lineNumbers: 'off',
glyphMargin: true,
@@ -85,9 +84,9 @@ function MonacoContainer({
ambiguousCharacters: true,
},
});
editorCallback(e, model, editorRef.current);
editorCallback(e, model, element);
setEditor(e);
}, [editorRef.current]);
}, [config, monaco, editorCallback, codeFontFamily, initialized]);
React.useEffect(() => {
if (!editor) return;
const current = editor.getValue({ lineEnding: '\n', preserveBOM: false });
@@ -111,7 +110,7 @@ function MonacoContainer({
model.pushEditOperations([], ops, undefined);
}, [editor, config]);
return (
<div ref={editorRef} style={{
<div ref={initializeEditor} style={{
width: '100%', height: '500px',
}} />
);
@@ -120,10 +119,17 @@ function MonacoContainer({
export default function ConfigEditor({
schema, config, monaco, Markdown, onSave, registerAction, sidebar,
}) {
const [value, setValue] = React.useState(yaml.load(config));
const getValue = () => {
try {
return yaml.load(config);
} catch (e) {
return {};
}
};
const [value, setValue] = React.useState(getValue);
const [info, setInfo] = React.useState('');
const [stringConfig, setStringConfig] = React.useState(config);
const initial = React.useMemo(() => yaml.load(config), []);
const initial = React.useMemo(getValue, []);
const { i18n } = React.useContext(ComponentsContext);
const Form = React.useMemo(() => createSchemasteryReact({
+2 -1
View File
@@ -4,7 +4,7 @@ import moment from 'moment-timezone';
import type { Context } from '../context';
import {
CannotDeleteSystemDomainError, DomainJoinAlreadyMemberError, DomainJoinForbiddenError, ForbiddenError,
InvalidJoinInvitationCodeError, OnlyOwnerCanDeleteDomainError, PermissionError, RoleAlreadyExistError, ValidationError,
InvalidJoinInvitationCodeError, NotFoundError, OnlyOwnerCanDeleteDomainError, PermissionError, RoleAlreadyExistError, ValidationError,
} from '../error';
import type { DomainDoc } from '../interface';
import avatar from '../lib/avatar';
@@ -337,6 +337,7 @@ class DomainJoinHandler extends Handler {
domain.get(target),
domain.collUser.findOne({ domainId: target, uid: this.user._id }),
]);
if (!dudoc) throw new NotFoundError(target);
const assignedRole = this.user.hasPriv(PRIV.PRIV_MANAGE_ALL_DOMAIN)
? 'root'
: dudoc?.role || 'default';
+5 -1
View File
@@ -198,7 +198,11 @@ class SystemConfigHandler extends SystemHandler {
};
try {
value = Schema.intersect(this.ctx.config.settings)(yaml.load(this.ctx.config.configSource));
try {
value = Schema.intersect(this.ctx.config.settings)(yaml.load(this.ctx.config.configSource));
} catch (e) {
value = yaml.load(this.ctx.config.configSource);
}
for (const schema of this.ctx.config.settings) processNode(value, schema);
} catch (e) { }
this.response.body = {
+9 -10
View File
@@ -139,16 +139,15 @@ export class ConfigService extends Service {
});
}
let curValue = s(this.systemConfig);
if (dynamic) {
this.ctx.on('system/setting', () => {
try {
curValue = s(this.systemConfig);
} catch (e) {
logger.warn('Cannot read config: ', e.message);
curValue = null;
}
});
}
if (!dynamic) return curValue;
this.ctx.on('system/setting', () => {
try {
curValue = s(this.systemConfig);
} catch (e) {
logger.warn('Cannot read config: ', e.message);
curValue = null;
}
});
const that = this;
const getAccess = (path: (string | symbol)[]) => {
if (path.some((p) => ConfigService.blacklist.includes(p.toString()))) throw new Error('Invalid path');
+1 -1
View File
@@ -7,6 +7,6 @@
"postinstall": "node -r @hydrooj/register install.ts"
},
"dependencies": {
"@xcpcio/board-app": "^0.54.0"
"@xcpcio/board-app": "^0.55.1"
}
}
+1 -1
View File
@@ -22,7 +22,7 @@
"@fontsource/source-code-pro": "^5.2.5",
"@fontsource/ubuntu-mono": "^5.2.5",
"@hydrooj/utils": "workspace:^",
"@sentry/browser": "^9.10.0",
"@sentry/browser": "^9.10.1",
"@sentry/webpack-plugin": "^3.2.4",
"@simplewebauthn/browser": "13.1.0",
"@svgr/webpack": "^8.1.0",
+1 -1
View File
@@ -46,7 +46,7 @@ const page = new NamedPage('manage_config', async () => {
overflow: hidden;
}
.footer {
display: hidden;
visibility: hidden;
}
.omnibar-toggle {
display: none;
@@ -55,8 +55,9 @@
<span class="icon icon-add"></span> {{ _('Login to Attend Contest') }}
</a>
{% elif not handler.user._dudoc.join %}
<li class="menu__item"><a class="menu__link" href="/domain/join?target={{ pdoc.domainId }}">
<span class="icon icon-add"></span> {{ _('Join Domain to Attend Contest') }}</a></li>
<a class="menu__link" href="/domain/join?target={{ pdoc.domainId }}">
<span class="icon icon-add"></span> {{ _('Join Domain to Attend Contest') }}
</a>
{% else %}
<a class="menu__link disabled" href="javascript:;">
<span class="icon icon-add"></span> {{ _('No Permission to Attend Contest') }}
+1 -1
View File
@@ -16,6 +16,6 @@
"@types/react": "^19.0.12",
"@types/react-dom": "^19.0.4",
"@vitejs/plugin-react-swc": "^3.8.1",
"vite": "^6.2.3"
"vite": "^6.2.4"
}
}