mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-20 01:38:19 +08:00
ui: bug fixes
This commit is contained in:
15 files changed
+75
-53
No files matched your search
+5
-4
@@ -55,21 +55,21 @@
|
|||||||
"globby": "13.1.3",
|
"globby": "13.1.3",
|
||||||
"inspectpack": "^4.7.1",
|
"inspectpack": "^4.7.1",
|
||||||
"latest-version": "7.0.0",
|
"latest-version": "7.0.0",
|
||||||
"mini-css-extract-plugin": "^2.7.3",
|
"mini-css-extract-plugin": "^2.7.5",
|
||||||
"monaco-editor-webpack-plugin": "^7.0.1",
|
"monaco-editor-webpack-plugin": "^7.0.1",
|
||||||
"mongodb": "^5.1.0",
|
"mongodb": "^5.1.0",
|
||||||
"mongodb-memory-server": "^8.12.0",
|
"mongodb-memory-server": "^8.12.0",
|
||||||
"nyc": "^15.1.0",
|
"nyc": "^15.1.0",
|
||||||
"ora": "^6.1.2",
|
"ora": "^6.1.2",
|
||||||
"postcss-loader": "^7.0.2",
|
"postcss-loader": "^7.1.0",
|
||||||
"semver": "^7.3.8",
|
"semver": "^7.3.8",
|
||||||
"style-loader": "^3.3.2",
|
"style-loader": "^3.3.2",
|
||||||
"stylus": "^0.59.0",
|
"stylus": "^0.59.0",
|
||||||
"stylus-loader": "^7.1.0",
|
"stylus-loader": "^7.1.0",
|
||||||
"supertest": "^6.3.3",
|
"supertest": "^6.3.3",
|
||||||
"ts-loader": "^9.4.2",
|
"ts-loader": "^9.4.2",
|
||||||
"typescript": "4.9.5",
|
"typescript": "5.0.2",
|
||||||
"webpack": "^5.76.1",
|
"webpack": "^5.76.2",
|
||||||
"webpack-bundle-analyzer": "^4.8.0",
|
"webpack-bundle-analyzer": "^4.8.0",
|
||||||
"webpack-dev-server": "^4.12.0",
|
"webpack-dev-server": "^4.12.0",
|
||||||
"webpack-manifest-plugin": "^5.0.0",
|
"webpack-manifest-plugin": "^5.0.0",
|
||||||
@@ -80,6 +80,7 @@
|
|||||||
"@types/node": "18.14.1",
|
"@types/node": "18.14.1",
|
||||||
"@types/react": "18.0.28",
|
"@types/react": "18.0.28",
|
||||||
"cosmokit": "1.4.1",
|
"cosmokit": "1.4.1",
|
||||||
|
"schemastery": "3.7.2",
|
||||||
"prettier": "npm:not-installable-package@1.0.0"
|
"prettier": "npm:not-installable-package@1.0.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
"@aws-sdk/s3-request-presigner": "^3.290.0",
|
"@aws-sdk/s3-request-presigner": "^3.290.0",
|
||||||
"@graphql-tools/schema": "^9.0.17",
|
"@graphql-tools/schema": "^9.0.17",
|
||||||
"@hydrooj/utils": "workspace:*",
|
"@hydrooj/utils": "workspace:*",
|
||||||
"@simplewebauthn/server": "^7.0.1",
|
"@simplewebauthn/server": "^7.2.0",
|
||||||
"adm-zip": "0.5.5",
|
"adm-zip": "0.5.5",
|
||||||
"cac": "^6.7.14",
|
"cac": "^6.7.14",
|
||||||
"cordis": "^2.7.4",
|
"cordis": "^2.7.4",
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
"emojis-list": "2.1.0",
|
"emojis-list": "2.1.0",
|
||||||
"fs-extra": "^11.1.0",
|
"fs-extra": "^11.1.0",
|
||||||
"graphql": "^16.6.0",
|
"graphql": "^16.6.0",
|
||||||
"graphql-scalars": "1.20.1",
|
"graphql-scalars": "1.20.4",
|
||||||
"js-yaml": "^4.1.0",
|
"js-yaml": "^4.1.0",
|
||||||
"koa": "^2.14.1",
|
"koa": "^2.14.1",
|
||||||
"koa-body": "^6.0.1",
|
"koa-body": "^6.0.1",
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import type fs from 'fs';
|
|||||||
import type { Dictionary, NumericDictionary } from 'lodash';
|
import type { Dictionary, NumericDictionary } from 'lodash';
|
||||||
import type { Binary, FindCursor, ObjectId } from 'mongodb';
|
import type { Binary, FindCursor, ObjectId } from 'mongodb';
|
||||||
import type { Context } from './context';
|
import type { Context } from './context';
|
||||||
|
import type { DocStatusType } from './model/document';
|
||||||
import type { ProblemDoc } from './model/problem';
|
import type { ProblemDoc } from './model/problem';
|
||||||
import type { Handler } from './service/server';
|
import type { Handler } from './service/server';
|
||||||
|
|
||||||
@@ -649,7 +650,9 @@ declare module './service/db' {
|
|||||||
'domain.user': any;
|
'domain.user': any;
|
||||||
'record': RecordDoc;
|
'record': RecordDoc;
|
||||||
'document': any;
|
'document': any;
|
||||||
'document.status': StatusDocBase;
|
'document.status': StatusDocBase & {
|
||||||
|
[K in keyof DocStatusType]: { docType: K } & DocStatusType[K];
|
||||||
|
}[keyof DocStatusType];
|
||||||
'discussion.history': DiscussionHistoryDoc;
|
'discussion.history': DiscussionHistoryDoc;
|
||||||
'user': Udoc;
|
'user': Udoc;
|
||||||
'user.preference': UserPreferenceDoc;
|
'user.preference': UserPreferenceDoc;
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ export interface DocType {
|
|||||||
|
|
||||||
export interface DocStatusType {
|
export interface DocStatusType {
|
||||||
[TYPE_PROBLEM]: ProblemStatusDoc,
|
[TYPE_PROBLEM]: ProblemStatusDoc,
|
||||||
|
// FIXME: this need to be typed
|
||||||
[key: number]: any
|
[key: number]: any
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -396,6 +397,7 @@ export async function revPushStatus<T extends keyof DocStatusType>(
|
|||||||
if (!res.value) {
|
if (!res.value) {
|
||||||
res = await collStatus.findOneAndUpdate(
|
res = await collStatus.findOneAndUpdate(
|
||||||
{ domainId, docType, docId, uid },
|
{ domainId, docType, docId, uid },
|
||||||
|
// @ts-ignore
|
||||||
{ $push: { [key]: value }, $inc: { rev: 1 } },
|
{ $push: { [key]: value }, $inc: { rev: 1 } },
|
||||||
{ upsert: true, returnDocument: 'after' },
|
{ upsert: true, returnDocument: 'after' },
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -5,7 +5,8 @@ import { EventMap } from './bus';
|
|||||||
import type { Handler } from './server';
|
import type { Handler } from './server';
|
||||||
|
|
||||||
type MethodDecorator = (target: any, funcName: string, obj: any) => any;
|
type MethodDecorator = (target: any, funcName: string, obj: any) => any;
|
||||||
type ClassDecorator = <T extends new (...args: any[]) => any>(Class: T) => T extends new (...args: infer R) => infer S ? (...args: R) => S : never;
|
type ClassDecorator = <T extends new (...args: any[]) => any>(Class: T) => T extends new (...args: infer R) => infer S
|
||||||
|
? new (...args: R) => S : never;
|
||||||
export interface ParamOption<T> {
|
export interface ParamOption<T> {
|
||||||
name: string,
|
name: string,
|
||||||
source: 'all' | 'get' | 'post' | 'route',
|
source: 'all' | 'get' | 'post' | 'route',
|
||||||
@@ -85,7 +86,7 @@ export const post: DescriptorBuilder = (name, ...args) => _descriptor(_buildPara
|
|||||||
export const route: DescriptorBuilder = (name, ...args) => _descriptor(_buildParam(name, 'route', ...args));
|
export const route: DescriptorBuilder = (name, ...args) => _descriptor(_buildParam(name, 'route', ...args));
|
||||||
export const param: DescriptorBuilder = (name, ...args) => _descriptor(_buildParam(name, 'all', ...args));
|
export const param: DescriptorBuilder = (name, ...args) => _descriptor(_buildParam(name, 'all', ...args));
|
||||||
|
|
||||||
export const subscribe: (name: keyof EventMap) => MethodDecorator | ClassDecorator = (name) => (target, funcName, obj) => {
|
export const subscribe: (name: keyof EventMap) => MethodDecorator & ClassDecorator = (name) => (target, funcName?, obj?) => {
|
||||||
if (funcName) {
|
if (funcName) {
|
||||||
target.__subscribe ||= [];
|
target.__subscribe ||= [];
|
||||||
target.__subscribe.push({ name, target: obj.value });
|
target.__subscribe.push({ name, target: obj.value });
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ export interface AutoCompleteProps<Item> {
|
|||||||
allowEmptyQuery?: boolean;
|
allowEmptyQuery?: boolean;
|
||||||
freeSolo?: boolean;
|
freeSolo?: boolean;
|
||||||
freeSoloConverter?: (value: string) => string;
|
freeSoloConverter?: (value: string) => string;
|
||||||
|
alwaysShowList?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AutoCompleteHandle<Item> {
|
export interface AutoCompleteHandle<Item> {
|
||||||
@@ -97,6 +98,7 @@ const AutoComplete = forwardRef(function Impl<T>(props: AutoCompleteProps<T>, re
|
|||||||
const allowEmptyQuery = props.allowEmptyQuery ?? false;
|
const allowEmptyQuery = props.allowEmptyQuery ?? false;
|
||||||
const freeSolo = props.freeSolo ?? false;
|
const freeSolo = props.freeSolo ?? false;
|
||||||
const freeSoloConverter = freeSolo ? props.freeSoloConverter ?? ((i) => i) : ((i) => i);
|
const freeSoloConverter = freeSolo ? props.freeSoloConverter ?? ((i) => i) : ((i) => i);
|
||||||
|
const alwaysShowList = props.alwaysShowList ?? false;
|
||||||
|
|
||||||
const [focused, setFocused] = useState(false); // is focused
|
const [focused, setFocused] = useState(false); // is focused
|
||||||
const [selected, setSelected] = useState([]); // selected items
|
const [selected, setSelected] = useState([]); // selected items
|
||||||
@@ -152,7 +154,7 @@ const AutoComplete = forwardRef(function Impl<T>(props: AutoCompleteProps<T>, re
|
|||||||
const handleInputChange = debounce((e?) => queryList(e ? e.target.value : ''), 300);
|
const handleInputChange = debounce((e?) => queryList(e ? e.target.value : ''), 300);
|
||||||
|
|
||||||
const toggleItem = (item: T, key = itemKey(item), preserve = false) => {
|
const toggleItem = (item: T, key = itemKey(item), preserve = false) => {
|
||||||
const shouldKeepOpen = allowEmptyQuery && inputRef.current.value === '' && !multi;
|
const shouldKeepOpen = (multi ? alwaysShowList : allowEmptyQuery) && inputRef.current.value === '';
|
||||||
if (multi) {
|
if (multi) {
|
||||||
const idx = selectedKeys.indexOf(key);
|
const idx = selectedKeys.indexOf(key);
|
||||||
if (idx !== -1) {
|
if (idx !== -1) {
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ CustomSelectAutoComplete.defaultProps = {
|
|||||||
selectedKeys: [],
|
selectedKeys: [],
|
||||||
freeSolo: false,
|
freeSolo: false,
|
||||||
freeSoloConverter: (input) => input,
|
freeSoloConverter: (input) => input,
|
||||||
|
alwaysShowList: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default CustomSelectAutoComplete;
|
export default CustomSelectAutoComplete;
|
||||||
@@ -46,6 +46,7 @@ FileSelectAutoComplete.defaultProps = {
|
|||||||
selectedKeys: [],
|
selectedKeys: [],
|
||||||
freeSolo: false,
|
freeSolo: false,
|
||||||
freeSoloConverter: (input) => input,
|
freeSoloConverter: (input) => input,
|
||||||
|
alwaysShowList: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default FileSelectAutoComplete;
|
export default FileSelectAutoComplete;
|
||||||
@@ -85,7 +85,7 @@ function LangConfig() {
|
|||||||
<CustomSelectAutoComplete
|
<CustomSelectAutoComplete
|
||||||
ref={ref}
|
ref={ref}
|
||||||
data={data}
|
data={data}
|
||||||
placeholder={i18n('Unlimited')}
|
placeholder={!selectedKeys.length ? i18n('Unlimited') : i18n('Code language')}
|
||||||
selectedKeys={selectedKeys}
|
selectedKeys={selectedKeys}
|
||||||
onChange={(val) => {
|
onChange={(val) => {
|
||||||
const value = val.split(',');
|
const value = val.split(',');
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ export function SubtaskNode(props: { subtaskId: number }) {
|
|||||||
</span>
|
</span>
|
||||||
</div>}
|
</div>}
|
||||||
<ul className="bp4-tree-node-list" ref={drop}>
|
<ul className="bp4-tree-node-list" ref={drop}>
|
||||||
{subtaskId !== -1 && <SubtaskSettings subtaskId={subtaskId} time={time} memory={memory} />}
|
{subtaskId !== -1 && <SubtaskSettings subtaskId={subtaskId} subtaskIds={subtaskIds} time={time} memory={memory} />}
|
||||||
{expand
|
{expand
|
||||||
? <SelectionManager subtaskId={subtaskId} subtaskIds={subtaskIds} />
|
? <SelectionManager subtaskId={subtaskId} subtaskIds={subtaskIds} />
|
||||||
: <TreeNode
|
: <TreeNode
|
||||||
|
|||||||
@@ -15,17 +15,18 @@ const ajv = new Ajv();
|
|||||||
const validate = ajv.compile(schema);
|
const validate = ajv.compile(schema);
|
||||||
|
|
||||||
export default function reducer(state = {
|
export default function reducer(state = {
|
||||||
type: 'default', __loaded: false, __valid: true, __errors: [], __cases: [],
|
type: 'default', __loaded: false, __valid: true, __errors: [], __cases: [], subtasks: [],
|
||||||
} as State, action: any = {}): State {
|
} as State, action: any = {}): State {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case 'CONFIG_LOAD_FULFILLED': {
|
case 'CONFIG_LOAD_FULFILLED': {
|
||||||
try {
|
try {
|
||||||
const data = yaml.load(action.payload.config) as any;
|
let data = yaml.load(action.payload.config) as any;
|
||||||
|
if (typeof data !== 'object') data = { subtasks: [] };
|
||||||
if (!validate(data)) {
|
if (!validate(data)) {
|
||||||
return { ...state, __valid: false, __errors: validate.errors.map((i) => `${i.instancePath}: ${i.message}`) };
|
return { ...state, __valid: false, __errors: validate.errors.map((i) => `${i.instancePath}: ${i.message}`) };
|
||||||
}
|
}
|
||||||
const subtasks = (data as any).subtasks;
|
const subtasks = (data as any).subtasks;
|
||||||
for (const subtask of subtasks || []) {
|
for (const subtask of subtasks) {
|
||||||
if (typeof subtask.id !== 'number') {
|
if (typeof subtask.id !== 'number') {
|
||||||
for (let i = 1; ; i++) {
|
for (let i = 1; ; i++) {
|
||||||
if (!subtasks.find((s) => s.id === i)) {
|
if (!subtasks.find((s) => s.id === i)) {
|
||||||
|
|||||||
@@ -13,31 +13,47 @@ export function AddTestcase() {
|
|||||||
const [input, setInput] = React.useState('');
|
const [input, setInput] = React.useState('');
|
||||||
const [output, setOutput] = React.useState('');
|
const [output, setOutput] = React.useState('');
|
||||||
const [valid, setValid] = React.useState(false);
|
const [valid, setValid] = React.useState(false);
|
||||||
|
const [autoInput, setAutoInput] = React.useState(true);
|
||||||
|
const [autoOutput, setAutoOutput] = React.useState(true);
|
||||||
const testdata = useSelector((state: RootState) => state.testdata);
|
const testdata = useSelector((state: RootState) => state.testdata);
|
||||||
const store = useStore<RootState>();
|
const store = useStore<RootState>();
|
||||||
const refInput = useRef();
|
const refInput = useRef();
|
||||||
const refOutput = useRef();
|
const refOutput = useRef();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setValid(testdata.find((i) => i.name === input) && testdata.find((i) => i.name === output));
|
const inputValid = testdata.find((i) => i.name === input);
|
||||||
if (input && !output) {
|
if (input) setAutoInput(false);
|
||||||
|
else setAutoInput(true);
|
||||||
|
setValid(inputValid);
|
||||||
|
if (inputValid && autoOutput) {
|
||||||
const filename = input.substring(0, input.lastIndexOf('.'));
|
const filename = input.substring(0, input.lastIndexOf('.'));
|
||||||
let outputFile = '';
|
let outputFile = '';
|
||||||
if (testdata.find((i) => i.name === `${filename}.out`)) outputFile = `${filename}.out`;
|
if (testdata.find((i) => i.name === `${filename}.out`)) outputFile = `${filename}.out`;
|
||||||
else if (testdata.find((i) => i.name === `${filename}.ans`)) outputFile = `${filename}.ans`;
|
else if (testdata.find((i) => i.name === `${filename}.ans`)) outputFile = `${filename}.ans`;
|
||||||
// @ts-ignore
|
if (outputFile) {
|
||||||
refOutput.current!.setSelectedItems([outputFile]);
|
// @ts-ignore
|
||||||
setOutput(outputFile);
|
refOutput.current!.setSelectedItems([outputFile]);
|
||||||
|
setOutput(outputFile);
|
||||||
|
setAutoOutput(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (output && !input) {
|
}, [input]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const outputValid = testdata.find((i) => i.name === output);
|
||||||
|
if (output) setAutoOutput(false);
|
||||||
|
else setAutoOutput(true);
|
||||||
|
setValid(outputValid);
|
||||||
|
if (outputValid && autoInput) {
|
||||||
const filename = output.substring(0, output.lastIndexOf('.'));
|
const filename = output.substring(0, output.lastIndexOf('.'));
|
||||||
if (testdata.find((i) => i.name === `${filename}.in`)) {
|
if (testdata.find((i) => i.name === `${filename}.in`)) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
refInput.current!.setSelectedItems([`${filename}.in`]);
|
refInput.current!.setSelectedItems([`${filename}.in`]);
|
||||||
setInput(`${filename}.in`);
|
setInput(`${filename}.in`);
|
||||||
|
setAutoInput(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [input, output]);
|
}, [output]);
|
||||||
|
|
||||||
function onConfirm() {
|
function onConfirm() {
|
||||||
store.dispatch({
|
store.dispatch({
|
||||||
@@ -81,6 +97,8 @@ export function AddTestcase() {
|
|||||||
onClick={() => {
|
onClick={() => {
|
||||||
setInput('');
|
setInput('');
|
||||||
setOutput('');
|
setOutput('');
|
||||||
|
setAutoInput(true);
|
||||||
|
setAutoOutput(true);
|
||||||
setOpen(true);
|
setOpen(true);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -8,9 +8,11 @@ import { isEqual } from 'lodash';
|
|||||||
import React, { useEffect } from 'react';
|
import React, { useEffect } from 'react';
|
||||||
import { useDispatch, useSelector } from 'react-redux';
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
import { i18n } from 'vj/utils';
|
import { i18n } from 'vj/utils';
|
||||||
|
import CustomSelectAutoComplete from '../../autocomplete/components/CustomSelectAutoComplete';
|
||||||
import { RootState } from '../reducer';
|
import { RootState } from '../reducer';
|
||||||
|
|
||||||
interface SubtaskSettingsProps {
|
interface SubtaskSettingsProps {
|
||||||
|
subtaskIds: number[];
|
||||||
subtaskId: number;
|
subtaskId: number;
|
||||||
time: string;
|
time: string;
|
||||||
memory: string;
|
memory: string;
|
||||||
@@ -19,6 +21,7 @@ interface SubtaskSettingsProps {
|
|||||||
export function SubtaskSettings(props: SubtaskSettingsProps) {
|
export function SubtaskSettings(props: SubtaskSettingsProps) {
|
||||||
const [open, setOpen] = React.useState(false);
|
const [open, setOpen] = React.useState(false);
|
||||||
const [depsOpen, setDepsOpen] = React.useState(false);
|
const [depsOpen, setDepsOpen] = React.useState(false);
|
||||||
|
const subtaskIds = props.subtaskIds.filter((i) => i !== props.subtaskId);
|
||||||
const score = useSelector((state: RootState) => state.config.subtasks.find((i) => i.id === props.subtaskId).score);
|
const score = useSelector((state: RootState) => state.config.subtasks.find((i) => i.id === props.subtaskId).score);
|
||||||
const time = useSelector((state: RootState) => state.config.subtasks.find((i) => i.id === props.subtaskId).time);
|
const time = useSelector((state: RootState) => state.config.subtasks.find((i) => i.id === props.subtaskId).time);
|
||||||
const memory = useSelector((state: RootState) => state.config.subtasks.find((i) => i.id === props.subtaskId).memory);
|
const memory = useSelector((state: RootState) => state.config.subtasks.find((i) => i.id === props.subtaskId).memory);
|
||||||
@@ -88,14 +91,13 @@ export function SubtaskSettings(props: SubtaskSettingsProps) {
|
|||||||
</Dialog>
|
</Dialog>
|
||||||
<Dialog title={i18n('Set dependencies')} icon="cog" isOpen={depsOpen} onClose={() => setDepsOpen(false)}>
|
<Dialog title={i18n('Set dependencies')} icon="cog" isOpen={depsOpen} onClose={() => setDepsOpen(false)}>
|
||||||
<DialogBody>
|
<DialogBody>
|
||||||
<ControlGroup fill={true} vertical={false}>
|
<CustomSelectAutoComplete
|
||||||
<InputGroup
|
data={subtaskIds.map((i) => ({ _id: i, name: `${i18n('Subtask {0}', i)}` }))}
|
||||||
leftElement={<Icon icon="diagram-tree" />}
|
setSelectItems={cdeps.split(',').map((i) => i.trim()).filter((i) => +i).map((i) => +i)}
|
||||||
onChange={(ev) => setDeps(ev.currentTarget.value)}
|
onChange={(items) => setDeps(items)}
|
||||||
placeholder={'Dependencies'}
|
placeholder="dependencies"
|
||||||
value={cdeps || ''}
|
multi
|
||||||
/>
|
/>
|
||||||
</ControlGroup>
|
|
||||||
</DialogBody>
|
</DialogBody>
|
||||||
<DialogFooter actions={<Button className="primary rounded button" onClick={onConfirm} intent="primary" text="Save" />} />
|
<DialogFooter actions={<Button className="primary rounded button" onClick={onConfirm} intent="primary" text="Save" />} />
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@hydrooj/ui-default",
|
"name": "@hydrooj/ui-default",
|
||||||
"version": "4.48.5",
|
"version": "4.48.6",
|
||||||
"author": "undefined <i@undefined.moe>",
|
"author": "undefined <i@undefined.moe>",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"main": "index.ts",
|
"main": "index.ts",
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
"@fontsource/source-code-pro": "^4.5.14",
|
"@fontsource/source-code-pro": "^4.5.14",
|
||||||
"@fontsource/ubuntu-mono": "^4.5.11",
|
"@fontsource/ubuntu-mono": "^4.5.11",
|
||||||
"@hydrooj/utils": "workspace:*",
|
"@hydrooj/utils": "workspace:*",
|
||||||
"@simplewebauthn/browser": "^7.1.0",
|
"@simplewebauthn/browser": "^7.2.0",
|
||||||
"@svgr/webpack": "^6.5.1",
|
"@svgr/webpack": "^6.5.1",
|
||||||
"@types/gulp-if": "^0.0.34",
|
"@types/gulp-if": "^0.0.34",
|
||||||
"@types/jquery": "^3.5.16",
|
"@types/jquery": "^3.5.16",
|
||||||
@@ -37,8 +37,8 @@
|
|||||||
"@types/react": "^18.0.28",
|
"@types/react": "^18.0.28",
|
||||||
"@types/react-dom": "^18.0.11",
|
"@types/react-dom": "^18.0.11",
|
||||||
"@types/redux-logger": "^3.0.9",
|
"@types/redux-logger": "^3.0.9",
|
||||||
"@types/serviceworker": "^0.0.65",
|
"@types/serviceworker": "^0.0.66",
|
||||||
"@types/sharedworker": "^0.0.94",
|
"@types/sharedworker": "^0.0.95",
|
||||||
"@types/webpack-env": "^1.18.0",
|
"@types/webpack-env": "^1.18.0",
|
||||||
"@vscode/codicons": "^0.0.32",
|
"@vscode/codicons": "^0.0.32",
|
||||||
"ajv": "^8.12.0",
|
"ajv": "^8.12.0",
|
||||||
|
|||||||
@@ -29,6 +29,9 @@
|
|||||||
.button
|
.button
|
||||||
margin: 0
|
margin: 0
|
||||||
|
|
||||||
|
input::placeholder
|
||||||
|
color: rgba(95,107,124,.6)!important
|
||||||
|
|
||||||
.bp4-input-group
|
.bp4-input-group
|
||||||
input
|
input
|
||||||
appearance: none
|
appearance: none
|
||||||
@@ -46,6 +49,12 @@
|
|||||||
transition-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1)
|
transition-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1)
|
||||||
box-shadow: none
|
box-shadow: none
|
||||||
|
|
||||||
|
.bp4-tag.bp4-minimal
|
||||||
|
background: transparent
|
||||||
|
|
||||||
|
.bp4-input-action
|
||||||
|
pointer-events: none
|
||||||
|
|
||||||
.problem-config-form
|
.problem-config-form
|
||||||
font-family: var(--code-font-family)
|
font-family: var(--code-font-family)
|
||||||
|
|
||||||
@@ -54,25 +63,6 @@
|
|||||||
input[type="number"]
|
input[type="number"]
|
||||||
-moz-appearance: textfield
|
-moz-appearance: textfield
|
||||||
|
|
||||||
.bp4-tag.bp4-minimal
|
|
||||||
background: transparent
|
|
||||||
.bp4-input-action
|
|
||||||
pointer-events: none
|
|
||||||
|
|
||||||
.data-table
|
|
||||||
tr
|
|
||||||
border-top: 0
|
|
||||||
border-bottom: 0
|
|
||||||
height: auto
|
|
||||||
td
|
|
||||||
padding: 0
|
|
||||||
.thead td
|
|
||||||
text-align: center
|
|
||||||
td input, td div
|
|
||||||
background: transparent
|
|
||||||
|
|
||||||
.hover-row.status-bar
|
.hover-row.status-bar
|
||||||
display: none
|
display: none
|
||||||
|
|
||||||
input::placeholder
|
|
||||||
color: rgba(95,107,124,.6)!important
|
|
||||||
Reference in new issue
Block a user