Skip to content

[sync] fix(app): collapse the expanded chat panel when clicking a sidebar node T6478 - #3620

Open
tea-artist wants to merge 1 commit into
developfrom
sync/ee-20260729-033958
Open

[sync] fix(app): collapse the expanded chat panel when clicking a sidebar node T6478#3620
tea-artist wants to merge 1 commit into
developfrom
sync/ee-20260729-033958

Conversation

@tea-artist

@tea-artist tea-artist commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

🔄 Automated sync from EE repository.

8 commit(s) synced since last sync.

Authors

Included commits

  • fix(app): collapse the expanded chat panel when clicking a sidebar node T6478 (Aries X)
  • perf(app): warm the table chunk and base page bundle from the space page T6471 (Aries X)
  • feat(compute-activity): simplify panel for T6394 (Jun Lu)
  • feat(share): add mobile share actions (T6364) (Jun Lu)
  • feat(app): allow removing table and base emoji icons T6455 (SkyHuang)
  • fix(sdk): keep select tags visible after single/multi convert T6459 (nichenqin)
  • fix(grid): patch group collapse/expand in place instead of full refresh T6323 (SkyHuang)
  • feat(billing): seat confirmation before invites and role changes T6407 (SkyHuang)

Latest source commit: teableio/teable-ee@b03c649

This PR was automatically created by the sync workflow.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5d24ae0c57

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +287 to +288
const userCount = members.filter((m) => m.principalType === PrincipalType.User).length;
if (await confirmSeat({ role: role as IRole, count: userCount, action: 'invite' })) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Count department members in the seat delta

When the organization selection contains only departments, userCount is zero, so useSeatConfirm returns immediately and skips both the cloud billing confirmation and the EE license limit. Department collaborators grant access to their users—the backend includes a user's organization departments when resolving collaborators—so assigning a billable role to a department can consume multiple seats. Resolve the department's newly billable members instead of filtering departments out; the same zero-seat assumption is present in the base invitation and department role-change handlers.

Useful? React with 👍 / 👎.

Comment on lines 267 to +269
onCreate={async (ro) => {
if (!(await confirmSeat({ role: ro.role, count: ro.emails.length, action: 'invite' }))) {
return false;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Gate email invitations using the actual seat increase

On an EE instance, ro.emails.length is not necessarily the number of new seats. For example, inviting a user who is already billable through another base or space creates a new collaborator without increasing the instance-wide billable-user count. If the instance is at its seat limit, this calculation rejects that valid invitation because seats + emails.length exceeds the limit. The confirmation needs a server-derived count of newly billable users; the base email flow has the same issue.

Useful? React with 👍 / 👎.

Comment on lines +243 to +245
onUpdate={async (invitationId, role) => {
if (await confirmSeat({ role, count: 1, action: 'link' })) {
updateInviteLink({

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Avoid charging a seat for billable-to-billable link updates

Updating an existing invitation link from one billable role to another, such as Creator to Editor, does not add a collaborator or consume a seat—the backend only updates the invitation row. Nevertheless this always checks with count: 1, so an EE instance at its seat limit cannot make that role adjustment, and cloud users receive an inaccurate bill-increase confirmation. Compare the existing link role and apply a positive delta only when the transition actually introduces billable access; the base-link handler repeats this behavior.

Useful? React with 👍 / 👎.

const { confirm, alert } = useConfirm();
const queryClient = useQueryClient();

const isPaidSpace = isCloud && level != null && level !== BillingProductLevel.Free;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Wait for the cloud billing level before allowing the action

On Cloud, level is undefined while useBillingLevel is still fetching, and it remains undefined if that query fails. This classifies the space as unpaid; because isEE is also false, the callback falls through to true. A paid customer who submits an invitation or role change before the usage query resolves therefore bypasses the required bill-increase confirmation. Await or block on the billing query rather than treating an unknown level as Free.

Useful? React with 👍 / 👎.

queryFn: () => getInstanceUsage().then((res) => res.data),
staleTime: 0,
})
.catch(() => undefined);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Do not fail open when the EE usage request fails

When the instance-usage request fails, this catch converts the error to undefined, leaving seatLimit absent and allowing the callback to return true. During any transient usage-service or network failure, the self-hosted seat-limit dialog and the stated hard stop are therefore bypassed, and the billable mutation is attempted without knowing whether capacity remains. Surface the failure or fail closed instead of silently authorizing the action.

Useful? React with 👍 / 👎.

@coveralls

coveralls commented Jul 29, 2026

Copy link
Copy Markdown
Collaborator

Coverage Report for CI Build 30447417723

Coverage at 58.238% (no base build to compare)

Details

  • Coverage remained the same as the base build.
  • Patch coverage: 1 of 1 lines across 1 file are fully covered (100%).
  • No coverage regressions found.

Uncovered Changes

No uncovered changes found.

Coverage Regressions

No coverage regressions found.


Coverage Stats

Coverage Status
Relevant Lines: 62389
Covered Lines: 36334
Line Coverage: 58.24%
Relevant Branches: 10562
Covered Branches: 8334
Branch Coverage: 78.91%
Branches in Coverage %: No
Coverage Strength: 2840.05 hits per line

💛 - Coveralls

@tea-artist tea-artist changed the title [sync] feat(billing): seat confirmation before invites and role changes T6407 [sync] fix(grid): patch group collapse/expand in place instead of full refresh T6323 Jul 29, 2026
@tea-artist
tea-artist force-pushed the sync/ee-20260729-033958 branch from 5d24ae0 to f0f79a9 Compare July 29, 2026 04:27
@tea-artist tea-artist changed the title [sync] fix(grid): patch group collapse/expand in place instead of full refresh T6323 [sync] fix(sdk): keep select tags visible after single/multi convert T6459 Jul 29, 2026
@tea-artist
tea-artist force-pushed the sync/ee-20260729-033958 branch from f0f79a9 to e600e6e Compare July 29, 2026 05:57

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e600e6e93d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

return;
}
if (knownCount > 0) {
ctx.nextGroupPoints.push({ type: GroupPointType.Row, count: knownCount });

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Restore nested headers when expanding a parent

When a multi-level group's parent is collapsed, its descendant headers are removed from groupPoints; re-expanding that parent here restores only one aggregate row block and cannot reconstruct those headers. The locally patched state therefore flattens the parent, and useGridAsyncRecords subsequently caches that malformed structure, so on a slow or failed fresh delivery the child groups remain missing and cannot be expanded or collapsed. Preserve the cached subtree for parent expansion, or avoid applying the in-place expansion when only an aggregate count is available.

Useful? React with 👍 / 👎.

// deliveries re-send a structurally identical list on every page (and
// after an exact local collapse patch): keep the previous reference so
// the grid does not rebuild its O(total rows) linear layout for nothing
setGroupPoints((prev) => (isEqual(prev, freshGroupPoints) ? prev : freshGroupPoints));

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Refill row counts on equal server deliveries

After a same-view filter, sort, or row-hiding search change, the layout effect clears groupRowCounts; if the authoritative delivery has structurally equal group points—which is common when sorting within groups or when a filter preserves each group's count—this equality branch retains the old state reference, so the effect that collects counts never runs again. Collapsing a group then omits its now-missing count, and re-expanding it takes the unknown-size path that drops every loaded row behind it until another delivery arrives. Refresh the count cache from every authoritative delivery even when the React layout state can retain its reference.

Useful? React with 👍 / 👎.

@tea-artist tea-artist changed the title [sync] fix(sdk): keep select tags visible after single/multi convert T6459 [sync] feat(app): allow removing table and base emoji icons T6455 Jul 29, 2026
@tea-artist
tea-artist force-pushed the sync/ee-20260729-033958 branch from e600e6e to 49b46d0 Compare July 29, 2026 07:30
@tea-artist tea-artist changed the title [sync] feat(app): allow removing table and base emoji icons T6455 [sync] feat(share): add mobile share actions (T6364) Jul 29, 2026
@tea-artist
tea-artist force-pushed the sync/ee-20260729-033958 branch from 49b46d0 to d6ab6e0 Compare July 29, 2026 10:03
@tea-artist tea-artist changed the title [sync] feat(share): add mobile share actions (T6364) [sync] feat(compute-activity): simplify panel for T6394 Jul 29, 2026
@tea-artist
tea-artist force-pushed the sync/ee-20260729-033958 branch from d6ab6e0 to bee7cb1 Compare July 29, 2026 11:24

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: bee7cb196b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

})
}
onCreate={async (role) => {
if (await confirmSeat({ role, count: 1, action: 'link' })) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Do not reserve an EE seat when creating an invitation link

On an EE instance already at its seat limit, this count: 1 makes useSeatConfirm reject creating a billable-role link even though link creation consumes no seat: InvitationService.generateInvitationLink only creates the invitation, while a collaborator is added later by acceptInvitationLink. The eventual accepter may also already be billable, so capacity cannot be determined at link-creation time; retain the Cloud warning but do not apply the EE seat-delta gate here. The space-link creation handler has the same problem.

Useful? React with 👍 / 👎.

const isInIframe = useIsInIframe();
const [dismissed, setDismissed] = useState(false);

if (!isHydrated || !isMobile || isInIframe || dismissed) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Hide the mobile operation bar for explicit embed URLs

When a ?embed=... share URL is opened outside an actual iframe on a viewport at or below 640px, isInIframe is false and this condition renders the fixed edit/save bar. The share view components consistently treat the query parameter itself as embed mode and suppress their headers, so a direct embed preview or new-tab embed now gains an operation overlay despite requesting chrome-free embed output. Check router.query.embed here in addition to the window iframe state.

Useful? React with 👍 / 👎.

const handleUpdateRole = useCallback(
(role: IRole, item: CollaboratorItem) => {
async (role: IRole, item: CollaboratorItem) => {
const addedSeats = item.type === PrincipalType.User && !item.billable ? 1 : 0;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Derive role-change deltas from populated billing data

For the base and space collaborator-list responses implemented in this tree, CollaboratorService.getListByBase and getListBySpace never populate the optional billable property, so every user reaches this expression with item.billable === undefined and is treated as a new seat. Consequently, changing an already billable user from Creator to Editor shows a false Cloud cost-increase confirmation and is blocked entirely on an EE instance at its seat limit. Populate the billing status or obtain the actual server-side seat delta before gating the role update; the invitation-dialog role handlers repeat this assumption.

Useful? React with 👍 / 👎.

@tea-artist tea-artist changed the title [sync] feat(compute-activity): simplify panel for T6394 [sync] perf(app): warm the table chunk and base page bundle from the space page T6471 Jul 29, 2026
@tea-artist
tea-artist force-pushed the sync/ee-20260729-033958 branch from bee7cb1 to f2f75f1 Compare July 29, 2026 13:11

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f2f75f1457

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +25 to +26
if (connection?.saveData || connection?.effectiveType === '2g') {
return;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Skip prefetching on slow-2g connections

When the Network Information API reports effectiveType === 'slow-2g' and data saver is disabled, this condition still schedules the heavy Table chunk download. Since slow-2g is an explicit effective-connection type and is slower than 2g, the users most affected by this speculative download bypass the protection described by the hook; exclude both 2g and slow-2g before warming the bundles.

Useful? React with 👍 / 👎.

…ebar node T6478

Synced from teableio/teable-ee@b03c649

Co-authored-by: Aries X <caoxing9@gmail.com>
Co-authored-by: Jun Lu <hammond@teable.io>
Co-authored-by: SkyHuang <sky.huang.fe@gmail.com>
Co-authored-by: nichenqin <nichenqin@hotmail.com>
@tea-artist tea-artist changed the title [sync] perf(app): warm the table chunk and base page bundle from the space page T6471 [sync] fix(app): collapse the expanded chat panel when clicking a sidebar node T6478 Jul 29, 2026
@tea-artist
tea-artist force-pushed the sync/ee-20260729-033958 branch from f2f75f1 to a937e10 Compare July 29, 2026 14:21
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.

2 participants