Merge branch 'main' into chore/kanban

This commit is contained in:
katherinehhh 2023-04-14 19:14:52 +08:00
commit 46d8c00f76
12 changed files with 121 additions and 111 deletions

View File

@ -13,6 +13,7 @@ const formatData = (
hideChildren: boolean = false, hideChildren: boolean = false,
) => { ) => {
data.forEach((item: any) => { data.forEach((item: any) => {
const percent=item[fieldNames.progress] * 100;
if (item.children && item.children.length) { if (item.children && item.children.length) {
tasks.push({ tasks.push({
start: new Date(item[fieldNames.start]), start: new Date(item[fieldNames.start]),
@ -20,7 +21,7 @@ const formatData = (
name: item[fieldNames.title], name: item[fieldNames.title],
id: item.id + '', id: item.id + '',
type: 'project', type: 'project',
progress: item[fieldNames.progress] * 100 || 0, progress: percent>100?100:percent || 0,
hideChildren: hideChildren, hideChildren: hideChildren,
project: projectId, project: projectId,
color: item.color, color: item.color,
@ -33,7 +34,7 @@ const formatData = (
name: item[fieldNames.title], name: item[fieldNames.title],
id: item.id + '', id: item.id + '',
type: fieldNames.end ? 'task' : 'milestone', type: fieldNames.end ? 'task' : 'milestone',
progress: item[fieldNames.progress] * 100 || 0, progress: percent>100?100:percent || 0,
project: projectId, project: projectId,
color: item.color, color: item.color,
}); });

View File

@ -718,7 +718,17 @@ export const useDestroyActionProps = () => {
await resource.destroy({ await resource.destroy({
filterByTk, filterByTk,
}); });
const { count = 0, page = 0, pageSize = 0 } = service?.data?.meta || {};
if (count % pageSize === 1) {
service.run({
...service?.params?.[0],
page: page - 1,
});
} else {
service?.refresh?.(); service?.refresh?.();
}
if (block !== 'TableField') { if (block !== 'TableField') {
__parent?.service?.refresh?.(); __parent?.service?.refresh?.();
setVisible?.(false); setVisible?.(false);

View File

@ -39,7 +39,7 @@ export const TaskGantt: React.FC<TaskGanttProps> = forwardRef(
width={gridProps.svgWidth} width={gridProps.svgWidth}
height={calendarProps.headerHeight} height={calendarProps.headerHeight}
fontFamily={barProps.fontFamily} fontFamily={barProps.fontFamily}
style={{ borderBottom: '1px solid #f0f0f0',fontWeight:700 }} style={{ borderBottom: '1px solid #f0f0f0', fontWeight: 700 }}
> >
<Calendar {...calendarProps} /> <Calendar {...calendarProps} />
</svg> </svg>

View File

@ -98,7 +98,7 @@ export const TaskItem: React.FC<TaskItemProps> = (props) => {
{taskItem} {taskItem}
<text <text
x={isProjectBar ? task.x1 : getX()} x={isProjectBar ? task.x1 : getX()}
y={isProjectBar ? task.y - 8 : task.y + taskHeight * 0.5} y={isProjectBar ? task.y - 8 : isTextInside ? task.y + taskHeight * 0.5 : task.y + taskHeight * 0.65}
className={isProjectBar ? cx(projectLabel) : isTextInside ? cx(barLabel) : cx(barLabel) && cx(barLabelOutside)} className={isProjectBar ? cx(projectLabel) : isTextInside ? cx(barLabel) : cx(barLabel) && cx(barLabelOutside)}
ref={textRef} ref={textRef}
> >

View File

@ -58,7 +58,7 @@ ReadPretty.TextArea = (props) => {
value value
); );
return ( return (
<div className={cls(prefixCls, props.className)} style={props.style}> <div className={cls(prefixCls, props.className)} style={{ overflowWrap: 'break-word', ...props.style }}>
{props.addonBefore} {props.addonBefore}
{props.prefix} {props.prefix}
{content} {content}
@ -94,7 +94,7 @@ ReadPretty.Html = (props) => {
</EllipsisWithTooltip> </EllipsisWithTooltip>
); );
return ( return (
<div className={cls(prefixCls, props.className)} style={props.style}> <div className={cls(prefixCls, props.className)} style={{ overflowWrap: 'break-word', ...props.style }}>
{props.addonBefore} {props.addonBefore}
{props.prefix} {props.prefix}
{content} {content}

View File

@ -1,8 +1,5 @@
.nb-markdown { .nb-markdown {
line-height: 1.612; line-height: 1.612;
a {
word-break: break-all;
}
} }
.nb-markdown > *:last-child { .nb-markdown > *:last-child {

View File

@ -131,7 +131,7 @@ const usePaginationProps = (pagination1, pagination2) => {
...pagination1, ...pagination1,
...pagination2, ...pagination2,
}; };
return result.total < result.pageSize ? false : result; return result.total <= result.pageSize ? false : result;
}; };
const useValidator = (validator: (value: any) => string) => { const useValidator = (validator: (value: any) => string) => {

View File

@ -1,10 +1,10 @@
import React, { useRef, useState } from 'react'; import React, { useRef } from 'react';
import { Button, Cascader, Popover, Input as AntInput } from 'antd'; import { Button } from 'antd';
import { css } from "@emotion/css"; import { css } from "@emotion/css";
import { Input } from "../input"; import { Input } from "../input";
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { XButton } from './XButton'; import { VariableSelect } from './VariableSelect';
@ -21,7 +21,6 @@ export function JSONInput(props) {
const inputRef = useRef<any>(null); const inputRef = useRef<any>(null);
const { value, space = 2, scope } = props; const { value, space = 2, scope } = props;
const { t } = useTranslation(); const { t } = useTranslation();
const [selectedVar, setSelectedVar] = useState<string[]>([]);
const options = typeof scope === 'function' ? scope() : (scope ?? []); const options = typeof scope === 'function' ? scope() : (scope ?? []);
function onFormat() { function onFormat() {
@ -72,24 +71,7 @@ export function JSONInput(props) {
`} `}
> >
<Button onClick={onFormat}>{t('Prettify')}</Button> <Button onClick={onFormat}>{t('Prettify')}</Button>
<Popover <VariableSelect options={options} onInsert={onInsert} />
content={(
<AntInput.Group compact>
<Cascader
placeholder={t('Select a variable')}
value={selectedVar}
options={options}
onChange={(keyPaths) => setSelectedVar(keyPaths as string[])}
changeOnSelect
/>
<Button onClick={onInsert}>{t('Insert')}</Button>
</AntInput.Group>
)}
trigger="click"
placement="topRight"
>
<XButton />
</Popover>
</Button.Group> </Button.Group>
</div> </div>
); );

View File

@ -1,12 +1,12 @@
import React, { useState, useEffect, useRef, useMemo } from 'react'; import React, { useState, useEffect, useRef, useMemo } from 'react';
import { Input, Cascader, Button, Tag } from 'antd'; import { Input } from 'antd';
import { useForm } from '@formily/react'; import { useForm } from '@formily/react';
import { cx, css } from '@emotion/css'; import { cx, css } from '@emotion/css';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import * as sanitizeHTML from 'sanitize-html'; import * as sanitizeHTML from 'sanitize-html';
import { EllipsisWithTooltip, useCompile } from '../..'; import { EllipsisWithTooltip, useCompile } from '../..';
import { useRecord } from '../../../record-provider'; import { VariableSelect } from './VariableSelect';
type RangeIndexes = [number, number, number, number]; type RangeIndexes = [number, number, number, number];
@ -341,19 +341,6 @@ export function TextArea(props) {
} }
} }
} }
.x-button{
.ant-select.ant-cascader{
position: absolute;
top: -1px;
left: -1px;
min-width: auto;
width: calc(100% + 2px);
height: calc(100% + 2px);
overflow: hidden;
opacity: 0;
}
}
`} `}
> >
<div <div
@ -382,63 +369,7 @@ export function TextArea(props) {
dangerouslySetInnerHTML={{ __html: html }} dangerouslySetInnerHTML={{ __html: html }}
/> />
{!disabled {!disabled
? ( ? <VariableSelect options={options} onInsert={onInsert} />
<Button className={cx('x-button', css`
position: relative;
`)}>
<span
className={css`
font-style: italic;
font-family: "New York", "Times New Roman", Times, serif;
`}
>x</span>
<Cascader
placeholder={t('Select a variable')}
value={[]}
options={options}
onChange={(keyPaths = [], selectedOptions = []) => {
setSelectedVar(keyPaths as string[]);
if (!keyPaths.length) {
return;
}
const option = selectedOptions[selectedOptions.length - 1];
if (!option?.children?.length) {
onInsert(keyPaths);
}
}}
changeOnSelect
onClick={(e: any) => {
if (e.detail !== 2) {
return;
}
for (let n = e.target; n && n !== e.currentTarget; n = n.parentNode) {
if (Array.from(n.classList ?? []).includes('ant-cascader-menu-item')) {
onInsert(selectedVar);
}
}
}}
dropdownClassName={css`
.ant-cascader-menu{
margin-bottom: 0;
}
`}
dropdownRender={(menu) => (
<>
{menu}
<div
className={css`
padding: .5em;
border-top: 1px solid rgba(0, 0, 0, .06);
color: rgba(0, 0, 0, .45);
`}
>
{t('Double click to choose entire object')}
</div>
</>
)}
/>
</Button>
)
: null : null
} }
</Input.Group> </Input.Group>

View File

@ -0,0 +1,83 @@
import { css, cx } from "@emotion/css";
import { Button, Cascader } from "antd";
import React, { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
export function VariableSelect(props) {
const { options, onInsert } = props;
const { t } = useTranslation();
const [selectedVar, setSelectedVar] = useState<string[]>([]);
useEffect(() => {
setSelectedVar([]);
}, [options]);
return (
<Button className={cx('x-button', css`
position: relative;
.ant-select.ant-cascader{
position: absolute;
top: -1px;
left: -1px;
min-width: auto;
width: calc(100% + 2px);
height: calc(100% + 2px);
overflow: hidden;
opacity: 0;
}
`)}>
<span
className={css`
font-style: italic;
font-family: "New York", "Times New Roman", Times, serif;
`}
>x</span>
<Cascader
placeholder={t('Select a variable')}
value={[]}
options={options}
onChange={(keyPaths = [], selectedOptions = []) => {
setSelectedVar(keyPaths as string[]);
if (!keyPaths.length) {
return;
}
const option = selectedOptions[selectedOptions.length - 1];
if (!option?.children?.length) {
onInsert(keyPaths);
}
}}
changeOnSelect
onClick={(e: any) => {
if (e.detail !== 2) {
return;
}
for (let n = e.target; n && n !== e.currentTarget; n = n.parentNode) {
if (Array.from(n.classList ?? []).includes('ant-cascader-menu-item')) {
onInsert(selectedVar);
}
}
}}
dropdownClassName={css`
.ant-cascader-menu{
margin-bottom: 0;
}
`}
dropdownRender={(menu) => (
<>
{menu}
<div
className={css`
padding: .5em;
border-top: 1px solid rgba(0, 0, 0, .06);
color: rgba(0, 0, 0, .45);
`}
>
{t('Double click to choose entire object')}
</div>
</>
)}
/>
</Button>
);
}

View File

@ -19,15 +19,13 @@ export default {
type: 'number', type: 'number',
title: `{{t("End Status", { ns: "${NAMESPACE}" })}}`, title: `{{t("End Status", { ns: "${NAMESPACE}" })}}`,
'x-decorator': 'FormItem', 'x-decorator': 'FormItem',
'x-component': 'Select', 'x-component': 'Radio.Group',
'x-component-props': {
placeholder: `{{t("Select status", { ns: "${NAMESPACE}" })}}`,
},
enum: [ enum: [
{ label: `{{t("Succeed and continue", { ns: "${NAMESPACE}" })}}`, value: JOB_STATUS.RESOLVED }, { label: `{{t("Succeed and continue", { ns: "${NAMESPACE}" })}}`, value: JOB_STATUS.RESOLVED },
{ label: `{{t("Fail and exit", { ns: "${NAMESPACE}" })}}`, value: JOB_STATUS.FAILED }, { label: `{{t("Fail and exit", { ns: "${NAMESPACE}" })}}`, value: JOB_STATUS.FAILED },
], ],
required: true required: true,
default: JOB_STATUS.RESOLVED
} }
}, },
view: { view: {

View File

@ -423,7 +423,6 @@ export function NodeDefaultView(props) {
'x-component': 'fieldset', 'x-component': 'fieldset',
'x-component-props': { 'x-component-props': {
className: css` className: css`
.ant-input,
.ant-select, .ant-select,
.ant-cascader-picker, .ant-cascader-picker,
.ant-picker, .ant-picker,
@ -434,6 +433,15 @@ export function NodeDefaultView(props) {
min-width: 6em; min-width: 6em;
} }
} }
.ant-input-affix-wrapper{
&:not(.full-width){
.ant-input{
width: auto;
min-width: 6em;
}
}
}
` `
}, },
properties: instruction.fieldset properties: instruction.fieldset