Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/1.2.5/UI #753

Merged
merged 9 commits into from
Jan 26, 2024
7 changes: 4 additions & 3 deletions i18n/en_US.yaml
Original file line number Diff line number Diff line change
@@ -1002,10 +1002,10 @@ ui:
label: Location
placeholder: "City, Country"
notification:
heading: Notifications
email: Email
heading: Email Notifications
turn_on: Turn on
inbox:
label: Email notifications
label: Inbox notifications
description: Answers to your questions, comments, invites, and more.
all_new_question:
label: All new questions
@@ -1166,6 +1166,7 @@ ui:
dark: Dark
system_setting: System setting
default: Default
reset: Reset
search:
title: Search Results
keywords: Keywords
11 changes: 8 additions & 3 deletions ui/src/common/interface.ts
Original file line number Diff line number Diff line change
@@ -623,12 +623,17 @@ export interface NotificationConfigItem {
key: string;
}
export interface NotificationConfig {
all_new_question: NotificationConfigItem[];
all_new_question_for_following_tags: NotificationConfigItem[];
inbox: NotificationConfigItem[];
all_new_question: NotificationConfigItem;
all_new_question_for_following_tags: NotificationConfigItem;
inbox: NotificationConfigItem;
}

export interface ActivatedPlugin {
name: string;
slug_name: string;
}

export interface UserPluginsConfigRes {
name: string;
slug_name: string;
}
8 changes: 4 additions & 4 deletions ui/src/components/Counts/index.tsx
Original file line number Diff line number Diff line change
@@ -51,7 +51,7 @@ const Index: FC<Props> = ({
return (
<div className={classname('d-flex align-items-center', className)}>
{showVotes && (
<div className="d-flex align-items-center">
<div className="d-flex align-items-center flex-shrink-0">
<Icon name="hand-thumbs-up-fill me-1" />
<span>
{data.votes} {t('votes')}
@@ -60,15 +60,15 @@ const Index: FC<Props> = ({
)}

{showAccepted && (
<div className="d-flex align-items-center ms-3 text-success">
<div className="d-flex align-items-center ms-3 text-success flex-shrink-0">
<Icon name="check-circle-fill me-1" />
<span>{t('accepted')}</span>
</div>
)}

{showAnswers && (
<div
className={`d-flex align-items-center ms-3 ${
className={`d-flex flex-shrink-0 align-items-center ms-3 ${
isAccepted ? 'text-success' : ''
}`}>
{isAccepted ? (
@@ -82,7 +82,7 @@ const Index: FC<Props> = ({
</div>
)}
{showViews && (
<span className="summary-stat ms-3">
<span className="summary-stat ms-3 flex-shrink-0">
<Icon name="eye-fill" />
<em className="fst-normal ms-1">
{data.views} {t('views')}
8 changes: 4 additions & 4 deletions ui/src/components/QuestionList/index.tsx
Original file line number Diff line number Diff line change
@@ -103,8 +103,8 @@ const QuestionList: FC<Props> = ({
{li.status === 2 ? ` [${t('closed')}]` : ''}
</NavLink>
</h5>
<div className="d-flex flex-column flex-md-row align-items-md-center small mb-2 text-secondary">
<div className="d-flex">
<div className="d-flex flex-wrap flex-column flex-md-row align-items-md-center small mb-2 text-secondary">
<div className="d-flex flex-wrap me-0 me-md-3">
<BaseUserCard
data={li.operator}
showAvatar={false}
@@ -113,7 +113,7 @@ const QuestionList: FC<Props> = ({
<FormatTime
time={li.operated_at}
className="text-secondary ms-1"
className="text-secondary ms-1 flex-shrink-0"
preFix={t(li.operation_type)}
/>
</div>
@@ -124,7 +124,7 @@ const QuestionList: FC<Props> = ({
views: li.view_count,
}}
isAccepted={li.accepted_answer_id >= 1}
className="ms-0 ms-md-3 mt-2 mt-md-0"
className="mt-2 mt-md-0"
/>
</div>
<div className="question-tags m-n1">
3 changes: 2 additions & 1 deletion ui/src/components/SchemaForm/README.md
Original file line number Diff line number Diff line change
@@ -183,8 +183,9 @@ export interface BaseUIOptions {
empty?: string;
// Will be appended to the className of the form component itself
className?: classnames.Argument;
class_name?: classnames.Argument;
// The className that will be attached to a form field container
fieldClassName?: classnames.Argument;
field_class_name?: classnames.Argument;
// Make a form component render into simplified mode
readOnly?: boolean;
simplify?: boolean;
50 changes: 48 additions & 2 deletions ui/src/components/SchemaForm/components/Button.tsx
Original file line number Diff line number Diff line change
@@ -17,31 +17,43 @@
* under the License.
*/

import React, { FC, useLayoutEffect, useState } from 'react';
import { FC, useEffect, useState } from 'react';
import { Button, ButtonProps, Spinner } from 'react-bootstrap';

import { request } from '@/utils';
import type { UIAction, FormKit } from '../types';
import { useToast } from '@/hooks';
import { Icon } from '@/components';

interface Props {
fieldName: string;
text: string;
action: UIAction | undefined;
actionType?: 'submit' | 'click';
clickCallback?: () => void;
formKit: FormKit;
readOnly: boolean;
variant?: ButtonProps['variant'];
size?: ButtonProps['size'];
iconName?: string;
nowrap?: boolean;
title?: string;
}
const Index: FC<Props> = ({
fieldName,
action,
actionType = 'submit',
formKit,
text = '',
readOnly = false,
variant = 'primary',
size,
iconName = '',
nowrap = false,
clickCallback,
title,
}) => {
console.log('Button.tsx: action:', title);
const Toast = useToast();
const [isLoading, setLoading] = useState(false);
const handleToast = (msg, type: 'success' | 'danger' = 'success') => {
@@ -62,6 +74,12 @@ const Index: FC<Props> = ({
}
};
const handleAction = () => {
if (actionType === 'click') {
if (typeof clickCallback === 'function') {
clickCallback();
}
return;
}
if (!action) {
return;
}
@@ -87,13 +105,39 @@ const Index: FC<Props> = ({
setLoading(false);
});
};
useLayoutEffect(() => {
useEffect(() => {
if (action?.loading?.state === 'pending') {
setLoading(true);
}
}, []);
const loadingText = action?.loading?.text || text;
const disabled = isLoading || readOnly;
if (nowrap) {
return (
<Button
name={fieldName}
onClick={handleAction}
disabled={disabled}
size={size}
title={title}
variant={variant}>
{isLoading ? (
<>
<Spinner
className="align-middle me-2"
animation="border"
size="sm"
variant={variant}
/>
{loadingText}
</>
) : (
text
)}
{iconName && <Icon name={iconName} />}
</Button>
);
}

return (
<div className="d-flex">
@@ -102,6 +146,7 @@ const Index: FC<Props> = ({
onClick={handleAction}
disabled={disabled}
size={size}
title={title}
variant={variant}>
{isLoading ? (
<>
@@ -116,6 +161,7 @@ const Index: FC<Props> = ({
) : (
text
)}
{iconName && <Icon name={iconName} />}
</Button>
</div>
);
2 changes: 1 addition & 1 deletion ui/src/components/SchemaForm/components/Input.tsx
Original file line number Diff line number Diff line change
@@ -63,7 +63,7 @@ const Index: FC<Props> = ({
onChange={handleChange}
disabled={readOnly}
isInvalid={fieldObject?.isInvalid}
style={type === 'color' ? { width: '6rem' } : {}}
style={type === 'color' ? { width: '100px', flex: 'none' } : {}}
/>
);
};
90 changes: 90 additions & 0 deletions ui/src/components/SchemaForm/components/InputGroup.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import { FC } from 'react';
import { InputGroup } from 'react-bootstrap';

import type { FormKit, InputGroupOptions } from '../types';

import Button from './Button';

interface Props {
formKitWithContext: FormKit;
uiOpt: InputGroupOptions;
prefixText?: string;
suffixText?: string;
children: React.ReactNode;
}

const InputGroupBtn = ({
formKitWithContext,
uiOpt,
}: {
formKitWithContext: FormKit;
uiOpt:
| InputGroupOptions['prefixBtnOptions']
| InputGroupOptions['suffixBtnOptions'];
}) => {
return (
<Button
fieldName="1"
text={String(uiOpt?.text)}
iconName={uiOpt?.iconName ? uiOpt?.iconName : ''}
action={uiOpt?.action ? uiOpt?.action : undefined}
actionType="click"
clickCallback={uiOpt?.clickCallback ? uiOpt?.clickCallback : undefined}
formKit={formKitWithContext}
variant={uiOpt?.variant ? uiOpt.variant : undefined}
size={uiOpt?.size ? uiOpt?.size : undefined}
title={uiOpt?.title ? uiOpt?.title : ''}
nowrap
readOnly={false}
/>
);
};

const Index: FC<Props> = ({
formKitWithContext,
uiOpt,
prefixText = null,
suffixText = null,
children,
}) => {
return (
<InputGroup>
{prefixText && <InputGroup.Text>{prefixText}</InputGroup.Text>}
{uiOpt && 'prefixBtnOptions' in uiOpt && (
<InputGroupBtn
uiOpt={uiOpt.prefixBtnOptions}
formKitWithContext={formKitWithContext}
/>
)}
{children}
{uiOpt && 'suffixBtnOptions' in uiOpt && (
<InputGroupBtn
uiOpt={uiOpt.suffixBtnOptions}
formKitWithContext={formKitWithContext}
/>
)}
{suffixText ? <InputGroup.Text>{suffixText}</InputGroup.Text> : null}
</InputGroup>
);
};

export default Index;
5 changes: 3 additions & 2 deletions ui/src/components/SchemaForm/components/Legend.tsx
Original file line number Diff line number Diff line change
@@ -22,9 +22,10 @@ import { Form } from 'react-bootstrap';

interface Props {
title: string;
className?: string | undefined;
}
const Index: FC<Props> = ({ title }) => {
return <Form.Label>{title}</Form.Label>;
const Index: FC<Props> = ({ title, className }) => {
return <Form.Label className={className}>{title}</Form.Label>;
};

export default Index;
2 changes: 2 additions & 0 deletions ui/src/components/SchemaForm/components/index.ts
Original file line number Diff line number Diff line change
@@ -26,6 +26,7 @@ import Upload from './Upload';
import Textarea from './Textarea';
import Input from './Input';
import Button from './Button';
import InputGroup from './InputGroup';

export {
Legend,
@@ -37,4 +38,5 @@ export {
Textarea,
Input,
Button,
InputGroup,
};
Loading