mirror of
https://github.com/nocobase/nocobase.git
synced 2026-10-29 18:16:18 +08:00
feat(kanban): add support for opening via URL (#5083)
* refactor: rename 'usePagePopup' to 'usePopupUtils' * refactor: remove useless code * refactor(kanban): reduce card dependency on context * feat: finished * test: add e2e test * chore: fix e2e test
This commit is contained in:
@@ -9,19 +9,21 @@
|
||||
|
||||
import { css } from '@emotion/css';
|
||||
import { FormLayout } from '@formily/antd-v5';
|
||||
import { createForm } from '@formily/core';
|
||||
import { observer, RecursionField, useFieldSchema } from '@formily/react';
|
||||
import {
|
||||
ActionContextProvider,
|
||||
DndContext,
|
||||
RecordProvider,
|
||||
FormProvider,
|
||||
PopupContextProvider,
|
||||
useCollection,
|
||||
useCollectionParentRecordData,
|
||||
useCollectionRecordData,
|
||||
usePopupUtils,
|
||||
VariablePopupRecordProvider,
|
||||
} from '@nocobase/client';
|
||||
import { Schema } from '@nocobase/utils';
|
||||
import { Card } from 'antd';
|
||||
import React, { useCallback, useContext, useMemo, useState } from 'react';
|
||||
import React, { useCallback, useContext, useMemo } from 'react';
|
||||
import { KanbanCardContext } from './context';
|
||||
import { useKanbanTranslation } from './locale';
|
||||
|
||||
const cardCss = css`
|
||||
.ant-card-body {
|
||||
@@ -72,23 +74,27 @@ MemorizedRecursionField.displayName = 'MemorizedRecursionField';
|
||||
|
||||
export const KanbanCard: any = observer(
|
||||
() => {
|
||||
const { t } = useKanbanTranslation();
|
||||
const collection = useCollection();
|
||||
const { setDisableCardDrag, cardViewerSchema, card, cardField, columnIndex, cardIndex } =
|
||||
useContext(KanbanCardContext);
|
||||
const parentRecordData = useCollectionParentRecordData();
|
||||
const { setDisableCardDrag } = useContext(KanbanCardContext) || {};
|
||||
const fieldSchema = useFieldSchema();
|
||||
const [visible, setVisible] = useState(false);
|
||||
const handleCardClick = useCallback((e: React.MouseEvent) => {
|
||||
const targetElement = e.target as Element; // 将事件目标转换为Element类型
|
||||
const currentTargetElement = e.currentTarget as Element;
|
||||
if (currentTargetElement.contains(targetElement)) {
|
||||
setVisible(true);
|
||||
e.stopPropagation();
|
||||
} else {
|
||||
e.stopPropagation();
|
||||
}
|
||||
}, []);
|
||||
const { openPopup, getPopupSchemaFromSchema } = usePopupUtils();
|
||||
const recordData = useCollectionRecordData();
|
||||
const popupSchema = getPopupSchemaFromSchema(fieldSchema) || getPopupSchemaFromParent(fieldSchema);
|
||||
const handleCardClick = useCallback(
|
||||
(e: React.MouseEvent) => {
|
||||
const targetElement = e.target as Element; // 将事件目标转换为Element类型
|
||||
const currentTargetElement = e.currentTarget as Element;
|
||||
if (currentTargetElement.contains(targetElement)) {
|
||||
openPopup({
|
||||
popupUidUsedInURL: popupSchema?.['x-uid'],
|
||||
});
|
||||
e.stopPropagation();
|
||||
} else {
|
||||
e.stopPropagation();
|
||||
}
|
||||
},
|
||||
[openPopup, popupSchema],
|
||||
);
|
||||
const cardStyle = useMemo(() => {
|
||||
return {
|
||||
cursor: 'pointer',
|
||||
@@ -96,51 +102,70 @@ export const KanbanCard: any = observer(
|
||||
};
|
||||
}, []);
|
||||
|
||||
const form = useMemo(() => {
|
||||
return createForm({
|
||||
values: recordData,
|
||||
});
|
||||
}, [recordData]);
|
||||
|
||||
const onDragStart = useCallback(() => {
|
||||
setDisableCardDrag(true);
|
||||
}, []);
|
||||
setDisableCardDrag?.(true);
|
||||
}, [setDisableCardDrag]);
|
||||
const onDragEnd = useCallback(() => {
|
||||
setDisableCardDrag(false);
|
||||
}, []);
|
||||
setDisableCardDrag?.(false);
|
||||
}, [setDisableCardDrag]);
|
||||
|
||||
const actionContextValue = useMemo(() => {
|
||||
// if not wrapped, only Tab component's content will be rendered, Drawer component's content will not be rendered
|
||||
const wrappedPopupSchema = useMemo(() => {
|
||||
return {
|
||||
openMode: fieldSchema['x-component-props']?.['openMode'] || 'drawer',
|
||||
openSize: fieldSchema['x-component-props']?.['openSize'],
|
||||
visible,
|
||||
setVisible,
|
||||
type: 'void',
|
||||
properties: {
|
||||
drawer: popupSchema,
|
||||
},
|
||||
};
|
||||
}, [fieldSchema, visible]);
|
||||
|
||||
const basePath = useMemo(
|
||||
() => cardField.address.concat(`${columnIndex}.cards.${cardIndex}`),
|
||||
[cardField, columnIndex, cardIndex],
|
||||
);
|
||||
const cardViewerBasePath = useMemo(
|
||||
() => cardField.address.concat(`${columnIndex}.cardViewer.${cardIndex}`),
|
||||
[cardField, columnIndex, cardIndex],
|
||||
);
|
||||
}, [popupSchema]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Card onClick={handleCardClick} bordered={false} hoverable style={cardStyle} className={cardCss}>
|
||||
<DndContext onDragStart={onDragStart} onDragEnd={onDragEnd}>
|
||||
<FormLayout layout={'vertical'}>
|
||||
<MemorizedRecursionField basePath={basePath} schema={fieldSchema} onlyRenderProperties />
|
||||
<FormProvider form={form}>
|
||||
<MemorizedRecursionField schema={fieldSchema} onlyRenderProperties />
|
||||
</FormProvider>
|
||||
</FormLayout>
|
||||
</DndContext>
|
||||
</Card>
|
||||
{cardViewerSchema && (
|
||||
<ActionContextProvider value={actionContextValue}>
|
||||
<RecordProvider record={card} parent={parentRecordData}>
|
||||
<VariablePopupRecordProvider recordData={card} collection={collection}>
|
||||
<MemorizedRecursionField basePath={cardViewerBasePath} schema={cardViewerSchema} onlyRenderProperties />
|
||||
</VariablePopupRecordProvider>
|
||||
</RecordProvider>
|
||||
</ActionContextProvider>
|
||||
)}
|
||||
<PopupContextProvider>
|
||||
<VariablePopupRecordProvider recordData={recordData} collection={collection}>
|
||||
<MemorizedRecursionField schema={wrappedPopupSchema} />
|
||||
</VariablePopupRecordProvider>
|
||||
</PopupContextProvider>
|
||||
</>
|
||||
);
|
||||
},
|
||||
{ displayName: 'KanbanCard' },
|
||||
);
|
||||
|
||||
function getPopupSchemaFromParent(fieldSchema: Schema) {
|
||||
if (fieldSchema.parent?.properties?.cardViewer?.properties?.drawer) {
|
||||
return fieldSchema.parent.properties.cardViewer.properties.drawer;
|
||||
}
|
||||
|
||||
const cardSchema = findSchemaByUid(fieldSchema['x-uid'], fieldSchema.root);
|
||||
return cardSchema.parent.properties.cardViewer.properties.drawer;
|
||||
}
|
||||
|
||||
function findSchemaByUid(uid: string, rootSchema: Schema, resultRef: { value: Schema } = { value: null }) {
|
||||
resultRef = resultRef || {
|
||||
value: null,
|
||||
};
|
||||
rootSchema.mapProperties((schema) => {
|
||||
if (schema['x-uid'] === uid) {
|
||||
resultRef.value = schema;
|
||||
} else {
|
||||
findSchemaByUid(uid, schema, resultRef);
|
||||
}
|
||||
});
|
||||
return resultRef.value;
|
||||
}
|
||||
|
||||
@@ -136,7 +136,7 @@ export const Kanban: any = withDynamicSchemaProps(
|
||||
<Tag color={color}>{title}</Tag>
|
||||
</div>
|
||||
)}
|
||||
renderCard={(card, { column, dragging }) => {
|
||||
renderCard={(card, { column }) => {
|
||||
const columnIndex = dataSource?.indexOf(column);
|
||||
const cardIndex = column?.cards?.indexOf(card);
|
||||
const { ref, inView } = useInView({
|
||||
@@ -144,24 +144,18 @@ export const Kanban: any = withDynamicSchemaProps(
|
||||
triggerOnce: true,
|
||||
initialInView: lastDraggedCard.current && lastDraggedCard.current === card[primaryKey],
|
||||
});
|
||||
|
||||
return (
|
||||
schemas.card && (
|
||||
<RecordProvider record={card} parent={parentRecordData}>
|
||||
<KanbanCardContext.Provider
|
||||
value={{
|
||||
setDisableCardDrag,
|
||||
cardViewerSchema: schemas.cardViewer,
|
||||
cardField: field,
|
||||
card,
|
||||
column,
|
||||
dragging,
|
||||
columnIndex,
|
||||
cardIndex,
|
||||
}}
|
||||
>
|
||||
<div ref={ref}>
|
||||
{inView ? (
|
||||
<MemorizedRecursionField name={schemas.card.name} schema={schemas.card} />
|
||||
<MemorizedRecursionField name={'card'} schema={fieldSchema.properties.card} />
|
||||
) : (
|
||||
<Card bordered={false}>
|
||||
<Skeleton paragraph={{ rows: 4 }} />
|
||||
|
||||
@@ -0,0 +1,755 @@
|
||||
/**
|
||||
* This file is part of the NocoBase (R) project.
|
||||
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
||||
* Authors: NocoBase Team.
|
||||
*
|
||||
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
||||
* For more information, please refer to: https://www.nocobase.com/agreement.
|
||||
*/
|
||||
|
||||
export const kanbanURL = {
|
||||
collections: [
|
||||
{
|
||||
name: 'kanban',
|
||||
fields: [
|
||||
{
|
||||
name: 'select',
|
||||
interface: 'select',
|
||||
uiSchema: {
|
||||
enum: [
|
||||
{
|
||||
value: 'option1',
|
||||
label: 'Option1',
|
||||
color: 'red',
|
||||
},
|
||||
{
|
||||
value: 'option2',
|
||||
label: 'Option2',
|
||||
color: 'green',
|
||||
},
|
||||
{
|
||||
value: 'option3',
|
||||
label: 'Option3',
|
||||
color: 'blue',
|
||||
},
|
||||
],
|
||||
type: 'string',
|
||||
'x-component': 'Select',
|
||||
title: 'Single select',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'sort',
|
||||
interface: 'sort',
|
||||
scopeKey: 'select',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
pageSchema: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-component': 'Page',
|
||||
properties: {
|
||||
eehnoq75dyp: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-component': 'Grid',
|
||||
'x-initializer': 'page:addBlock',
|
||||
properties: {
|
||||
qy13k7twlgr: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-component': 'Grid.Row',
|
||||
'x-app-version': '1.3.0-alpha',
|
||||
properties: {
|
||||
z2zx32gyeno: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-component': 'Grid.Col',
|
||||
'x-app-version': '1.3.0-alpha',
|
||||
properties: {
|
||||
'6h3p53u5ek7': {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-acl-action': 'kanban:list',
|
||||
'x-decorator': 'KanbanBlockProvider',
|
||||
'x-decorator-props': {
|
||||
collection: 'kanban',
|
||||
dataSource: 'main',
|
||||
action: 'list',
|
||||
groupField: 'select',
|
||||
sortField: 'sort',
|
||||
params: {
|
||||
paginate: false,
|
||||
sort: ['sort'],
|
||||
},
|
||||
},
|
||||
'x-toolbar': 'BlockSchemaToolbar',
|
||||
'x-settings': 'blockSettings:kanban',
|
||||
'x-component': 'CardItem',
|
||||
'x-app-version': '1.3.0-alpha',
|
||||
properties: {
|
||||
actions: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-initializer': 'kanban:configureActions',
|
||||
'x-component': 'ActionBar',
|
||||
'x-component-props': {
|
||||
style: {
|
||||
marginBottom: 'var(--nb-spacing)',
|
||||
},
|
||||
},
|
||||
'x-app-version': '1.3.0-alpha',
|
||||
'x-uid': 'zb0mo93az5z',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
ms2kyy843uc: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'array',
|
||||
'x-component': 'Kanban',
|
||||
'x-use-component-props': 'useKanbanBlockProps',
|
||||
'x-app-version': '1.3.0-alpha',
|
||||
properties: {
|
||||
card: {
|
||||
'x-uid': '1y1b9kliqui',
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-read-pretty': true,
|
||||
'x-label-disabled': true,
|
||||
'x-decorator': 'BlockItem',
|
||||
'x-component': 'Kanban.Card',
|
||||
'x-component-props': {
|
||||
openMode: 'drawer',
|
||||
},
|
||||
'x-designer': 'Kanban.Card.Designer',
|
||||
'x-app-version': '1.3.0-alpha',
|
||||
'x-action-context': {
|
||||
dataSource: 'main',
|
||||
collection: 'kanban',
|
||||
},
|
||||
properties: {
|
||||
grid: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-component': 'Grid',
|
||||
'x-component-props': {
|
||||
dndContext: false,
|
||||
},
|
||||
'x-app-version': '1.3.0-alpha',
|
||||
properties: {
|
||||
'8evl3dcvt86': {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-component': 'Grid.Row',
|
||||
properties: {
|
||||
'36yop5rgpyi': {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-component': 'Grid.Col',
|
||||
properties: {
|
||||
select: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'string',
|
||||
'x-toolbar': 'FormItemSchemaToolbar',
|
||||
'x-settings': 'fieldSettings:FormItem',
|
||||
'x-component': 'CollectionField',
|
||||
'x-decorator': 'FormItem',
|
||||
'x-collection-field': 'kanban.select',
|
||||
'x-component-props': {
|
||||
style: {
|
||||
width: '100%',
|
||||
},
|
||||
},
|
||||
'x-read-pretty': true,
|
||||
'x-uid': '8a20gaw8qdh',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': 'pzvcxvven6y',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': 'xd4gdx5j0qm',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': 'zx1rf8qfane',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
cardViewer: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
title: '{{ t("View") }}',
|
||||
'x-designer': 'Action.Designer',
|
||||
'x-component': 'Kanban.CardViewer',
|
||||
'x-action': 'view',
|
||||
'x-component-props': {
|
||||
openMode: 'drawer',
|
||||
},
|
||||
'x-app-version': '1.3.0-alpha',
|
||||
properties: {
|
||||
drawer: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
title: '{{ t("View record") }}',
|
||||
'x-component': 'Action.Container',
|
||||
'x-component-props': {
|
||||
className: 'nb-action-popup',
|
||||
},
|
||||
'x-app-version': '1.3.0-alpha',
|
||||
properties: {
|
||||
tabs: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-component': 'Tabs',
|
||||
'x-component-props': {},
|
||||
'x-initializer': 'popup:addTab',
|
||||
'x-app-version': '1.3.0-alpha',
|
||||
properties: {
|
||||
tab1: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
title: '{{t("Details")}}',
|
||||
'x-component': 'Tabs.TabPane',
|
||||
'x-designer': 'Tabs.Designer',
|
||||
'x-component-props': {},
|
||||
'x-app-version': '1.3.0-alpha',
|
||||
properties: {
|
||||
grid: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-component': 'Grid',
|
||||
'x-initializer': 'popup:common:addBlock',
|
||||
'x-app-version': '1.3.0-alpha',
|
||||
properties: {
|
||||
'8bv7l5hiazu': {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-component': 'Grid.Row',
|
||||
'x-app-version': '1.3.0-alpha',
|
||||
properties: {
|
||||
torszg5y5zd: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-component': 'Grid.Col',
|
||||
'x-app-version': '1.3.0-alpha',
|
||||
properties: {
|
||||
d4p7lp86m03: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-acl-action': 'kanban:get',
|
||||
'x-decorator': 'DetailsBlockProvider',
|
||||
'x-use-decorator-props': 'useDetailsDecoratorProps',
|
||||
'x-decorator-props': {
|
||||
dataSource: 'main',
|
||||
collection: 'kanban',
|
||||
readPretty: true,
|
||||
action: 'get',
|
||||
},
|
||||
'x-toolbar': 'BlockSchemaToolbar',
|
||||
'x-settings': 'blockSettings:details',
|
||||
'x-component': 'CardItem',
|
||||
'x-app-version': '1.3.0-alpha',
|
||||
properties: {
|
||||
'1oxl6q1ktkh': {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-component': 'Details',
|
||||
'x-read-pretty': true,
|
||||
'x-use-component-props': 'useDetailsProps',
|
||||
'x-app-version': '1.3.0-alpha',
|
||||
properties: {
|
||||
r27t49cfoo5: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-initializer': 'details:configureActions',
|
||||
'x-component': 'ActionBar',
|
||||
'x-component-props': {
|
||||
style: {
|
||||
marginBottom: 24,
|
||||
},
|
||||
},
|
||||
'x-app-version': '1.3.0-alpha',
|
||||
properties: {
|
||||
uya6ulpeavl: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
title: '{{ t("Edit") }}',
|
||||
'x-action': 'update',
|
||||
'x-toolbar': 'ActionSchemaToolbar',
|
||||
'x-settings': 'actionSettings:edit',
|
||||
'x-component': 'Action',
|
||||
'x-component-props': {
|
||||
openMode: 'drawer',
|
||||
icon: 'EditOutlined',
|
||||
type: 'primary',
|
||||
},
|
||||
'x-action-context': {
|
||||
dataSource: 'main',
|
||||
collection: 'kanban',
|
||||
},
|
||||
'x-decorator': 'ACLActionProvider',
|
||||
'x-app-version': '1.3.0-alpha',
|
||||
properties: {
|
||||
drawer: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
title: '{{ t("Edit record") }}',
|
||||
'x-component': 'Action.Container',
|
||||
'x-component-props': {
|
||||
className: 'nb-action-popup',
|
||||
},
|
||||
'x-app-version': '1.3.0-alpha',
|
||||
properties: {
|
||||
tabs: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-component': 'Tabs',
|
||||
'x-component-props': {},
|
||||
'x-initializer': 'popup:addTab',
|
||||
'x-app-version': '1.3.0-alpha',
|
||||
properties: {
|
||||
tab1: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
title: '{{t("Edit")}}',
|
||||
'x-component': 'Tabs.TabPane',
|
||||
'x-designer': 'Tabs.Designer',
|
||||
'x-component-props': {},
|
||||
'x-app-version': '1.3.0-alpha',
|
||||
properties: {
|
||||
grid: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-component': 'Grid',
|
||||
'x-initializer':
|
||||
'popup:common:addBlock',
|
||||
'x-app-version': '1.3.0-alpha',
|
||||
properties: {
|
||||
etzmlia85gh: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-component': 'Grid.Row',
|
||||
'x-app-version': '1.3.0-alpha',
|
||||
properties: {
|
||||
'6dn14wki0e5': {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-component': 'Grid.Col',
|
||||
'x-app-version':
|
||||
'1.3.0-alpha',
|
||||
properties: {
|
||||
cruqx5ulnow: {
|
||||
_isJSONSchemaObject:
|
||||
true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-acl-action-props': {
|
||||
skipScopeCheck: false,
|
||||
},
|
||||
'x-acl-action':
|
||||
'kanban:update',
|
||||
'x-decorator':
|
||||
'FormBlockProvider',
|
||||
'x-use-decorator-props':
|
||||
'useEditFormBlockDecoratorProps',
|
||||
'x-decorator-props': {
|
||||
action: 'get',
|
||||
dataSource: 'main',
|
||||
collection: 'kanban',
|
||||
},
|
||||
'x-toolbar':
|
||||
'BlockSchemaToolbar',
|
||||
'x-settings':
|
||||
'blockSettings:editForm',
|
||||
'x-component':
|
||||
'CardItem',
|
||||
'x-app-version':
|
||||
'1.3.0-alpha',
|
||||
properties: {
|
||||
y0q5ei7mma2: {
|
||||
_isJSONSchemaObject:
|
||||
true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-component':
|
||||
'FormV2',
|
||||
'x-use-component-props':
|
||||
'useEditFormBlockProps',
|
||||
'x-app-version':
|
||||
'1.3.0-alpha',
|
||||
properties: {
|
||||
grid: {
|
||||
_isJSONSchemaObject:
|
||||
true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-component':
|
||||
'Grid',
|
||||
'x-initializer':
|
||||
'form:configureFields',
|
||||
'x-app-version':
|
||||
'1.3.0-alpha',
|
||||
properties: {
|
||||
rjbvqpp7xmu: {
|
||||
_isJSONSchemaObject:
|
||||
true,
|
||||
version:
|
||||
'2.0',
|
||||
type: 'void',
|
||||
'x-component':
|
||||
'Grid.Row',
|
||||
'x-app-version':
|
||||
'1.3.0-alpha',
|
||||
properties:
|
||||
{
|
||||
cxiykvzwfv1:
|
||||
{
|
||||
_isJSONSchemaObject:
|
||||
true,
|
||||
version:
|
||||
'2.0',
|
||||
type: 'void',
|
||||
'x-component':
|
||||
'Grid.Col',
|
||||
'x-app-version':
|
||||
'1.3.0-alpha',
|
||||
properties:
|
||||
{
|
||||
select:
|
||||
{
|
||||
_isJSONSchemaObject:
|
||||
true,
|
||||
version:
|
||||
'2.0',
|
||||
type: 'string',
|
||||
'x-toolbar':
|
||||
'FormItemSchemaToolbar',
|
||||
'x-settings':
|
||||
'fieldSettings:FormItem',
|
||||
'x-component':
|
||||
'CollectionField',
|
||||
'x-decorator':
|
||||
'FormItem',
|
||||
'x-collection-field':
|
||||
'kanban.select',
|
||||
'x-component-props':
|
||||
{
|
||||
style:
|
||||
{
|
||||
width:
|
||||
'100%',
|
||||
},
|
||||
},
|
||||
'x-app-version':
|
||||
'1.3.0-alpha',
|
||||
'x-uid':
|
||||
'eo2xh4adfaz',
|
||||
'x-async':
|
||||
false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid':
|
||||
'walnc8ivgzp',
|
||||
'x-async':
|
||||
false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid':
|
||||
'3san45vkk32',
|
||||
'x-async':
|
||||
false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid':
|
||||
'opiixrhoo0z',
|
||||
'x-async':
|
||||
false,
|
||||
'x-index': 1,
|
||||
},
|
||||
'5j12oi9pvf3': {
|
||||
_isJSONSchemaObject:
|
||||
true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-initializer':
|
||||
'editForm:configureActions',
|
||||
'x-component':
|
||||
'ActionBar',
|
||||
'x-component-props':
|
||||
{
|
||||
layout:
|
||||
'one-column',
|
||||
},
|
||||
'x-app-version':
|
||||
'1.3.0-alpha',
|
||||
properties: {
|
||||
m9e7qxjys7o: {
|
||||
_isJSONSchemaObject:
|
||||
true,
|
||||
version:
|
||||
'2.0',
|
||||
title:
|
||||
'{{ t("Submit") }}',
|
||||
'x-action':
|
||||
'submit',
|
||||
'x-component':
|
||||
'Action',
|
||||
'x-use-component-props':
|
||||
'useUpdateActionProps',
|
||||
'x-toolbar':
|
||||
'ActionSchemaToolbar',
|
||||
'x-settings':
|
||||
'actionSettings:updateSubmit',
|
||||
'x-component-props':
|
||||
{
|
||||
type: 'primary',
|
||||
htmlType:
|
||||
'submit',
|
||||
},
|
||||
'x-action-settings':
|
||||
{
|
||||
triggerWorkflows:
|
||||
[],
|
||||
},
|
||||
type: 'void',
|
||||
'x-app-version':
|
||||
'1.3.0-alpha',
|
||||
'x-uid':
|
||||
'5sc8g3215j4',
|
||||
'x-async':
|
||||
false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid':
|
||||
'2v1zlgnh0lp',
|
||||
'x-async':
|
||||
false,
|
||||
'x-index': 2,
|
||||
},
|
||||
},
|
||||
'x-uid':
|
||||
'u5viek4cakp',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': 'z38sbx5yocb',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': 'y0wdbxagcre',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': 'dn2spxvle3x',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': 'fsmyjuyc0mc',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': 'x27vohz57u1',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': 'uxbmlytgowr',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': 'p108r8s8pjh',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': 'detjnjixd9n',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': 'i9622c7n8nv',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
grid: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-component': 'Grid',
|
||||
'x-initializer': 'details:configureFields',
|
||||
'x-app-version': '1.3.0-alpha',
|
||||
properties: {
|
||||
cylu3xjywvu: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-component': 'Grid.Row',
|
||||
'x-app-version': '1.3.0-alpha',
|
||||
properties: {
|
||||
z1eb85u2n4n: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-component': 'Grid.Col',
|
||||
'x-app-version': '1.3.0-alpha',
|
||||
properties: {
|
||||
select: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'string',
|
||||
'x-toolbar': 'FormItemSchemaToolbar',
|
||||
'x-settings': 'fieldSettings:FormItem',
|
||||
'x-component': 'CollectionField',
|
||||
'x-decorator': 'FormItem',
|
||||
'x-collection-field': 'kanban.select',
|
||||
'x-component-props': {
|
||||
style: {
|
||||
width: '100%',
|
||||
},
|
||||
},
|
||||
'x-app-version': '1.3.0-alpha',
|
||||
'x-uid': 'mfz4c6l4ft9',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': 'lt4bp9emb4z',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': 'ny6e5q4fhww',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': 'yfunnpaf97c',
|
||||
'x-async': false,
|
||||
'x-index': 2,
|
||||
},
|
||||
},
|
||||
'x-uid': 'pegqhin3s88',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': 'wpafritzh4d',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': '2vjqy76fds6',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': 'avlvzb0yl0s',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': 'm5x3kz75nm2',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': '6wb8grmdenj',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': 'uybfp4br16z',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': '4dwpi8dug9d',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': 'x0dusy43fhl',
|
||||
'x-async': false,
|
||||
'x-index': 2,
|
||||
},
|
||||
},
|
||||
'x-uid': '6vpzr0nsxjs',
|
||||
'x-async': false,
|
||||
'x-index': 2,
|
||||
},
|
||||
},
|
||||
'x-uid': 'f1eqli5bc07',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': '4exwrzlac4i',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': 'edzxlnh6nx4',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': 's95fpawrrle',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': '57xhoz3sfzq',
|
||||
'x-async': true,
|
||||
'x-index': 1,
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* This file is part of the NocoBase (R) project.
|
||||
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
||||
* Authors: NocoBase Team.
|
||||
*
|
||||
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
||||
* For more information, please refer to: https://www.nocobase.com/agreement.
|
||||
*/
|
||||
|
||||
import { expect, test } from '@nocobase/test/e2e';
|
||||
import { kanbanURL } from './templates';
|
||||
|
||||
test.describe('kanban: open popup via URL', () => {
|
||||
test('basic', async ({ page, mockPage, mockRecords }) => {
|
||||
const nocoPage = await mockPage(kanbanURL).waitForInit();
|
||||
await mockRecords('kanban', [{ select: 'option1' }, { select: 'option2' }, { select: 'option3' }]);
|
||||
await nocoPage.goto();
|
||||
|
||||
// 1. click a card to open a popup
|
||||
await page.getByLabel('block-item-CollectionField-').filter({ hasText: 'option1' }).click();
|
||||
await expect(
|
||||
page.getByTestId('drawer-Action.Container-kanban-View record').getByLabel('block-item-CollectionField-'),
|
||||
).toHaveText('Single select:Option1');
|
||||
|
||||
// 2. then reload the page, the popup should be opened
|
||||
await page.reload();
|
||||
await expect(
|
||||
page.getByTestId('drawer-Action.Container-kanban-View record').getByLabel('block-item-CollectionField-'),
|
||||
).toHaveText('Single select:Option1');
|
||||
|
||||
// 3. click the `Edit` button to open another popup
|
||||
await page.getByLabel('action-Action-Edit-update-').click();
|
||||
await expect(
|
||||
page.getByTestId('drawer-Action.Container-kanban-Edit record').getByLabel('block-item-CollectionField-'),
|
||||
).toHaveText('Single select:Option1');
|
||||
|
||||
// 4. then reload the page, the second popup should be opened
|
||||
await page.reload();
|
||||
await expect(
|
||||
page.getByTestId('drawer-Action.Container-kanban-Edit record').getByLabel('block-item-CollectionField-'),
|
||||
).toHaveText('Single select:Option1');
|
||||
|
||||
// 5. change the `Option` then close, the previous popup's content should be updated
|
||||
await page.getByTestId('select-single').click();
|
||||
await page.getByRole('option', { name: 'Option2' }).click();
|
||||
await page.getByLabel('action-Action-Submit-submit-').click();
|
||||
await page.mouse.move(300, 0);
|
||||
|
||||
await expect(page.getByLabel('block-item-CollectionField-kanban-details-kanban.select-Single select')).toHaveText(
|
||||
'Single select:Option2',
|
||||
);
|
||||
|
||||
// close the first popup
|
||||
// await page.locator('.ant-drawer-mask').click();
|
||||
// await expect(page.getByLabel('block-item-CollectionField-').filter({ hasText: 'option2' })).toHaveCount(2);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user