Skip to content

fix: record default view selection T713#2304

Merged
younocode merged 3 commits intodevelopfrom
fix/record-default-view-selection
Dec 19, 2025
Merged

fix: record default view selection T713#2304
younocode merged 3 commits intodevelopfrom
fix/record-default-view-selection

Conversation

@younocode
Copy link
Copy Markdown
Contributor

@younocode younocode commented Dec 19, 2025

Related Issues: T713

@younocode younocode requested a review from Copilot December 19, 2025 07:19
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes an issue with default view selection when navigating to table pages with record IDs (T713). The main changes focus on improving URL query string handling and filtering out form views when a record ID is present in the query parameters.

Key changes:

  • Enhanced query string handling to avoid appending empty query strings to redirect URLs
  • Modified default view selection logic to exclude form views when a record ID is present
  • Refactored tree rendering in BaseNodeTree to separate view and edit modes

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.

File Description
apps/nextjs-app/src/pages/base/[baseId]/[[...slug]].tsx Fixed query string handling to avoid appending ? when query string is empty
apps/nextjs-app/src/features/app/blocks/base/base-side-bar/BaseNodeTree.tsx Split tree rendering into separate functions for view and edit modes, added border styling fix
apps/nextjs-app/src/features/app/base-node/TablePage.tsx Enhanced default view selection to filter out form views when record ID is present, improved query string handling

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread apps/nextjs-app/src/features/app/blocks/base/base-side-bar/BaseNodeTree.tsx Outdated
Comment thread apps/nextjs-app/src/features/app/base-node/TablePage.tsx
Comment thread apps/nextjs-app/src/features/app/base-node/TablePage.tsx Outdated
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (1)

apps/nextjs-app/src/features/app/blocks/base/base-side-bar/BaseNodeTree.tsx:840

  • There is significant code duplication between renderViewTree and renderEditTree functions. Both functions share nearly identical tree rendering logic (ScrollArea, Tree, TreeItem structure, ItemIcon, ItemStatus, name handling). Consider extracting the common tree item rendering logic into a shared component or helper function, parameterized by the edit mode differences (e.g., editing input, additional action buttons).
  const renderViewTree = () => {
    return (
      <ScrollArea
        viewportRef={viewportRef}
        className="flex w-full !border-none px-2 [&>[data-radix-scroll-area-viewport]>div]:!block [&>[data-radix-scroll-area-viewport]>div]:!min-w-0"
        scrollBar="none"
      >
        <Tree indent={INDENTATION_WIDTH} tree={tree} className="py-1">
          <AssistiveTreeDescription tree={tree} />
          {tree.getItems().map((item) => {
            const nodeId = item.getId();
            const node = item.getItemData();
            if (!node || Object.keys(node).length === 0) return null;
            const { resourceType, resourceId } = node;
            const name = getNodeName(node);
            const isPinned = pinMap?.[resourceId];
            return (
              <TreeItem asChild key={nodeId} item={item}>
                <div className="h-8 w-full cursor-pointer">
                  <TreeItemLabel className={cn('size-full min-w-0 py-0')}>
                    <div className="flex min-w-0 flex-1 items-center gap-2">
                      <ItemIcon item={item} />
                      <div className="flex min-w-0 grow items-center gap-1" title={name}>
                        <span className="truncate text-left">{name}</span>

                        <ItemStatus item={item} />
                        {
                          // eslint-disable-next-line jsx-a11y/no-static-element-interactions, jsx-a11y/click-events-have-key-events
                          <div
                            onClick={(e) => {
                              e.stopPropagation();
                            }}
                            className={cn('flex shrink-0 cursor-pointer items-center', {
                              'w-0 group-hover:w-auto': !isPinned,
                            })}
                          >
                            <BaseNodeStarButton
                              resourceType={resourceType}
                              resourceId={resourceId}
                            />
                          </div>
                        }
                      </div>
                    </div>
                  </TreeItemLabel>
                </div>
              </TreeItem>
            );
          })}
          <TreeDragLine />
        </Tree>
        <ScrollBar className="z-30" />
      </ScrollArea>
    );
  };

  const renderEditTree = () => {
    return (
      <ScrollArea
        viewportRef={viewportRef}
        className={cn(
          'flex w-full px-2 [&>[data-radix-scroll-area-viewport]>div]:!block [&>[data-radix-scroll-area-viewport]>div]:!min-w-0',
          {
            '!border-none': canCreateResource,
          }
        )}
        scrollBar="none"
      >
        <Tree indent={INDENTATION_WIDTH} tree={tree} className="py-1">
          <AssistiveTreeDescription tree={tree} />
          {tree.getItems().map((item) => {
            const nodeId = item.getId();
            const node = item.getItemData();
            if (!node || Object.keys(node).length === 0) return null;
            const { resourceType, resourceId } = node;
            const name = getNodeName(node);
            const isHighlighted = isEditMode && highlightedTableId === resourceId;
            const isPinned = pinMap?.[resourceId];
            return (
              <TreeItem asChild key={nodeId} item={item}>
                <div className="h-8 w-full cursor-pointer">
                  <TreeItemLabel
                    className={cn('size-full min-w-0 py-0', {
                      'bg-orange-300/40 hover:bg-orange-300/40': isHighlighted,
                    })}
                  >
                    <div className="flex min-w-0 flex-1 items-center gap-2">
                      {editingNodeId === nodeId ? (
                        <Input
                          ref={inputRef}
                          type="text"
                          placeholder="name"
                          defaultValue={item.getItemName()}
                          style={{
                            boxShadow: 'none',
                          }}
                          className="round-none size-full cursor-text bg-background outline-none"
                          onKeyDown={(e) => {
                            if (e.key === 'Enter') {
                              const newVal = e.currentTarget.value;
                              if (newVal && newVal !== item.getItemName()) {
                                curdHooks.updateNode(nodeId, { name: newVal });
                              }
                              setEditingNodeId(null);
                            } else if (e.key === 'Escape') {
                              setEditingNodeId(null);
                            }
                          }}
                          onClick={(e) => {
                            e.stopPropagation();
                          }}
                          onMouseDown={(e) => {
                            e.stopPropagation();
                          }}
                        />
                      ) : (
                        <>
                          <ItemIcon item={item} />
                          <div className="flex min-w-0 grow items-center gap-1" title={name}>
                            <span
                              className="truncate text-left"
                              onDoubleClick={() => {
                                setEditingNodeId(nodeId);
                              }}
                            >
                              {name}
                            </span>

                            <ItemStatus item={item} />
                          </div>
                          {
                            // eslint-disable-next-line jsx-a11y/no-static-element-interactions, jsx-a11y/click-events-have-key-events
                            <div
                              onClick={(e) => {
                                e.stopPropagation();
                              }}
                              className={cn('flex shrink-0 cursor-pointer items-center gap-2', {
                                'w-0 group-hover:w-auto': !isPinned,
                              })}
                            >
                              <div className="opacity-0 group-hover:opacity-100 group-data-[folder=false]:hidden">
                                {canCreateResource && (
                                  <BaseNodeAddResourceButton
                                    curdHooks={curdHooks}
                                    parentId={nodeId === ROOT_ID ? undefined : nodeId}
                                    canCreateFolder={
                                      canCreateFolder && checkCanCreateFolder(item, maxFolderDepth)
                                    }
                                    canCreateTable={canCreateTable}
                                    canCreateDashboard={canCreateDashboard}
                                    canCreateWorkflow={canCreateWorkflow}
                                    canCreateApp={canCreateApp}
                                  >
                                    <Button variant={'ghost'} size={'xs'} className="size-4 p-0">
                                      <AddBoldIcon className="size-full" />
                                    </Button>
                                  </BaseNodeAddResourceButton>
                                )}
                              </div>
                              {
                                <BaseNodeStarButton
                                  resourceType={resourceType}
                                  resourceId={resourceId}
                                />
                              }
                              <div className="opacity-0 group-hover:opacity-100 ">
                                <BaseNodeMore
                                  resourceType={resourceType}
                                  resourceId={resourceId}
                                  className="size-4 shrink-0 sm:opacity-0 sm:group-hover:opacity-100"
                                  onRename={() => setEditingNodeId(nodeId)}
                                  onDelete={async (permanent: boolean, confirm: boolean = true) => {
                                    const titleMap = {
                                      [BaseNodeResourceType.Folder]: t('common:noun.folder'),
                                      [BaseNodeResourceType.Table]: t('common:noun.table'),
                                      [BaseNodeResourceType.Dashboard]: t('common:noun.dashboard'),
                                      [BaseNodeResourceType.Workflow]: t('common:noun.automation'),
                                      [BaseNodeResourceType.App]: t('common:noun.app'),
                                    };
                                    const result = !confirm
                                      ? true
                                      : await comfirmModal({
                                          title: `${t('common:actions.delete')} ${(titleMap[resourceType] ?? '').toLowerCase()}`,
                                          description: t('common:actions.deleteTip', {
                                            name,
                                          }),
                                          confirmText: t('common:actions.delete'),
                                          cancelText: t('common:actions.cancel'),
                                          confirmButtonVariant: 'destructive',
                                        });
                                    if (result) {
                                      await curdHooks.deleteNode(nodeId, permanent);
                                    }
                                  }}
                                  onDuplicate={async (ro?: IDuplicateBaseNodeRo) => {
                                    await curdHooks.duplicateNode(nodeId, {
                                      name,
                                      ...(ro ?? {}),
                                    });
                                  }}
                                />
                              </div>
                            </div>
                          }
                        </>
                      )}
                    </div>
                  </TreeItemLabel>
                </div>
              </TreeItem>
            );
          })}
          <TreeDragLine />
        </Tree>
        <ScrollBar className="z-30" />
      </ScrollArea>
    );

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@younocode younocode merged commit 039bb95 into develop Dec 19, 2025
13 checks passed
@younocode younocode deleted the fix/record-default-view-selection branch December 19, 2025 07:45
@github-actions
Copy link
Copy Markdown
Contributor

🧹 Preview Environment Cleanup

hammond-lj pushed a commit that referenced this pull request Dec 22, 2025
* fix:  improve query handling in TablePage component T713

* refactor: enhance BaseNodeTree component with improved rendering logic and styling adjustments

* refactor: improve view selection logic in TablePage component
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants