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:
Zeke Zhang
2024-08-20 15:33:09 +08:00
committed by GitHub
parent 0e5f8b5e12
commit 77b60ed16c
19 changed files with 1075 additions and 91 deletions
@@ -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);
});
});