Skip to content

Commit d9e91ca

Browse files
committed
feat: support publish
1 parent cef5ae9 commit d9e91ca

File tree

23 files changed

+1611
-61
lines changed

23 files changed

+1611
-61
lines changed

src/@types/translations/en.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,8 @@
508508
"namespaceLengthAtLeast2Characters": "The namespace must be at least 2 characters long",
509509
"onlyWorkspaceOwnerCanUpdateNamespace": "Only workspace owner can update the namespace",
510510
"onlyWorkspaceOwnerCanRemoveHomepage": "Only workspace owner can remove the homepage",
511+
"onlyWorkspaceOwnerCanChangeHomepage": "Only workspace owner can change the homepage",
512+
"onlyProCanSetHomepage": "Only Pro Plan workspace owner can set the homepage",
511513
"setHomepageFailed": "Failed to set homepage",
512514
"namespaceTooLong": "The namespace is too long, please try another one",
513515
"namespaceTooShort": "The namespace is too short, please try another one",
@@ -3042,5 +3044,8 @@
30423044
"memberCount_many": "{{count}} members",
30433045
"memberCount_other": "{{count}} members",
30443046
"aiMatch": "AI match",
3045-
"titleMatch": "Title match"
3047+
"titleMatch": "Title match",
3048+
"namespace": "Namespace",
3049+
"manageNamespaceDescription": "Manage your namespace and homepage",
3050+
"homepage": "Homepage"
30463051
}

src/application/services/js-services/http/http_api.ts

Lines changed: 121 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,13 @@ import {
2121
CreateSpacePayload,
2222
UpdateSpacePayload,
2323
Role,
24-
WorkspaceMember, QuickNote, QuickNoteEditorData, CreateWorkspacePayload, UpdateWorkspacePayload,
24+
WorkspaceMember,
25+
QuickNote,
26+
QuickNoteEditorData,
27+
CreateWorkspacePayload,
28+
UpdateWorkspacePayload,
29+
PublishViewPayload,
30+
UploadPublishNamespacePayload,
2531
} from '@/application/types';
2632
import { GlobalComment, Reaction } from '@/application/comment.type';
2733
import { initGrantService, refreshToken } from '@/application/services/js-services/http/gotrue';
@@ -328,6 +334,48 @@ export async function getUserWorkspaceInfo (): Promise<{
328334
return Promise.reject(data);
329335
}
330336

337+
export async function publishView (workspaceId: string, viewId: string, payload?: PublishViewPayload) {
338+
const url = `/api/workspace/${workspaceId}/page-view/${viewId}/publish`;
339+
const response = await axiosInstance?.post<{
340+
code: number;
341+
message: string;
342+
}>(url, payload);
343+
344+
if (response?.data.code === 0) {
345+
return;
346+
}
347+
348+
return Promise.reject(response?.data);
349+
}
350+
351+
export async function unpublishView (workspaceId: string, viewId: string) {
352+
const url = `/api/workspace/${workspaceId}/page-view/${viewId}/unpublish`;
353+
const response = await axiosInstance?.delete<{
354+
code: number;
355+
message: string;
356+
}>(url);
357+
358+
if (response?.data.code === 0) {
359+
return;
360+
}
361+
362+
return Promise.reject(response?.data);
363+
}
364+
365+
export async function updatePublishNamespace (workspaceId: string, payload: UploadPublishNamespacePayload) {
366+
const url = `/api/workspace/${workspaceId}/publish-namespace`;
367+
const response = await axiosInstance?.put<{
368+
code: number;
369+
message: string;
370+
}>(url, payload);
371+
372+
if (response?.data.code === 0) {
373+
return;
374+
}
375+
376+
return Promise.reject(response?.data);
377+
}
378+
331379
export async function getPublishViewMeta (namespace: string, publishName: string) {
332380
const url = `/api/workspace/v1/published/${namespace}/${publishName}`;
333381
const response = await axiosInstance?.get<{
@@ -491,6 +539,9 @@ export async function getPublishInfoWithViewId (viewId: string) {
491539
data?: {
492540
namespace: string;
493541
publish_name: string;
542+
publisher_email: string;
543+
view_id: string;
544+
publish_timestamp: string;
494545
};
495546
message: string;
496547
}>(url);
@@ -596,6 +647,75 @@ export async function getView (workspaceId: string, viewId: string, depth: numbe
596647
return Promise.reject(data);
597648
}
598649

650+
export async function getPublishNamespace (workspaceId: string) {
651+
const url = `/api/workspace/${workspaceId}/publish-namespace`;
652+
const response = await axiosInstance?.get<{
653+
code: number;
654+
data?: string;
655+
message: string;
656+
}>(url);
657+
658+
const data = response?.data;
659+
660+
if (data?.code === 0 && data.data) {
661+
return data.data;
662+
}
663+
664+
return Promise.reject(data);
665+
}
666+
667+
export async function getPublishHomepage (workspaceId: string) {
668+
const url = `/api/workspace/${workspaceId}/publish-default`;
669+
const response = await axiosInstance?.get<{
670+
code: number;
671+
data?: {
672+
namespace: string;
673+
publish_name: string;
674+
publisher_email: string;
675+
view_id: string;
676+
};
677+
message: string;
678+
}>(url);
679+
680+
const data = response?.data;
681+
682+
if (data?.code === 0 && data.data) {
683+
return data.data;
684+
}
685+
686+
return Promise.reject(data);
687+
}
688+
689+
export async function updatePublishHomepage (workspaceId: string, viewId: string) {
690+
const url = `/api/workspace/${workspaceId}/publish-default`;
691+
const response = await axiosInstance?.put<{
692+
code: number;
693+
message: string;
694+
}>(url, {
695+
view_id: viewId,
696+
});
697+
698+
if (response?.data.code === 0) {
699+
return;
700+
}
701+
702+
return Promise.reject(response?.data);
703+
}
704+
705+
export async function removePublishHomepage (workspaceId: string) {
706+
const url = `/api/workspace/${workspaceId}/publish-default`;
707+
const response = await axiosInstance?.delete<{
708+
code: number;
709+
message: string;
710+
}>(url);
711+
712+
if (response?.data.code === 0) {
713+
return;
714+
}
715+
716+
return Promise.reject(response?.data);
717+
}
718+
599719
export async function getPublishOutline (publishNamespace: string) {
600720
const url = `/api/workspace/published-outline/${publishNamespace}`;
601721
const response = await axiosInstance?.get<{

src/application/services/js-services/index.ts

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@ import {
3131
import {
3232
CreatePagePayload, CreateSpacePayload, CreateWorkspacePayload,
3333
DatabaseRelations,
34-
DuplicatePublishView, QuickNoteEditorData,
34+
DuplicatePublishView, PublishViewPayload, QuickNoteEditorData,
3535
SubscriptionInterval, SubscriptionPlan,
36-
Types, UpdatePagePayload, UpdateSpacePayload, UpdateWorkspacePayload, WorkspaceMember,
36+
Types, UpdatePagePayload, UpdateSpacePayload, UpdateWorkspacePayload, UploadPublishNamespacePayload, WorkspaceMember,
3737
YjsEditorKey,
3838
} from '@/application/types';
3939
import { applyYDoc } from '@/application/ydoc/apply';
@@ -65,6 +65,43 @@ export class AFClientService implements AFService {
6565
return this.clientId;
6666
}
6767

68+
async publishView (workspaceId: string, viewId: string, payload?: PublishViewPayload) {
69+
if (this.publishViewInfo.has(viewId)) {
70+
this.publishViewInfo.delete(viewId);
71+
}
72+
73+
return APIService.publishView(workspaceId, viewId, payload);
74+
}
75+
76+
async unpublishView (workspaceId: string, viewId: string) {
77+
if (this.publishViewInfo.has(viewId)) {
78+
this.publishViewInfo.delete(viewId);
79+
}
80+
81+
return APIService.unpublishView(workspaceId, viewId);
82+
}
83+
84+
async updatePublishNamespace (workspaceId: string, payload: UploadPublishNamespacePayload) {
85+
this.publishViewInfo.clear();
86+
return APIService.updatePublishNamespace(workspaceId, payload);
87+
}
88+
89+
async getPublishNamespace (workspaceId: string) {
90+
return APIService.getPublishNamespace(workspaceId);
91+
}
92+
93+
async getPublishHomepage (workspaceId: string) {
94+
return APIService.getPublishHomepage(workspaceId);
95+
}
96+
97+
async updatePublishHomepage (workspaceId: string, viewId: string) {
98+
return APIService.updatePublishHomepage(workspaceId, viewId);
99+
}
100+
101+
async removePublishHomepage (workspaceId: string) {
102+
return APIService.removePublishHomepage(workspaceId);
103+
}
104+
68105
async getPublishViewMeta (namespace: string, publishName: string) {
69106
const name = `${namespace}_${publishName}`;
70107

@@ -165,6 +202,9 @@ export class AFClientService implements AFService {
165202
return this.publishViewInfo.get(viewId) as {
166203
namespace: string;
167204
publishName: string;
205+
publisherEmail: string;
206+
viewId: string;
207+
publishedAt: string;
168208
};
169209
}
170210

@@ -179,6 +219,9 @@ export class AFClientService implements AFService {
179219
const data = {
180220
namespace,
181221
publishName: info.publish_name,
222+
publisherEmail: info.publisher_email,
223+
viewId: info.view_id,
224+
publishedAt: info.publish_timestamp,
182225
};
183226

184227
this.publishViewInfo.set(viewId, data);
@@ -569,7 +612,7 @@ export class AFClientService implements AFService {
569612
return APIService.deleteQuickNote(workspaceId, id);
570613
}
571614

572-
searchWorkspace(workspaceId: string, query: string) {
615+
searchWorkspace (workspaceId: string, query: string) {
573616
return APIService.searchWorkspace(workspaceId, query);
574617
}
575618
}

src/application/services/services.type.ts

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,12 @@ import {
1919
UpdateSpacePayload,
2020
WorkspaceMember,
2121
QuickNoteEditorData,
22-
QuickNote, Subscription, CreateWorkspacePayload, UpdateWorkspacePayload,
22+
QuickNote,
23+
Subscription,
24+
CreateWorkspacePayload,
25+
UpdateWorkspacePayload,
26+
PublishViewPayload,
27+
UploadPublishNamespacePayload,
2328
} from '@/application/types';
2429
import { GlobalComment, Reaction } from '@/application/comment.type';
2530
import { ViewMeta } from '@/application/db/tables/view_metas';
@@ -138,11 +143,22 @@ export interface TemplateService {
138143
}
139144

140145
export interface PublishService {
141-
146+
publishView: (workspaceId: string, viewId: string, payload?: PublishViewPayload) => Promise<void>;
147+
unpublishView: (workspaceId: string, viewId: string) => Promise<void>;
148+
updatePublishNamespace: (workspaceId: string, payload: UploadPublishNamespacePayload) => Promise<void>;
142149
getPublishViewMeta: (namespace: string, publishName: string) => Promise<ViewMeta>;
143150
getPublishView: (namespace: string, publishName: string) => Promise<YDoc>;
144151
getPublishRowDocument: (viewId: string) => Promise<YDoc>;
145-
getPublishInfo: (viewId: string) => Promise<{ namespace: string; publishName: string }>;
152+
getPublishInfo: (viewId: string) => Promise<{
153+
namespace: string;
154+
publishName: string,
155+
publisherEmail: string,
156+
publishedAt: string
157+
}>;
158+
getPublishNamespace: (namespace: string) => Promise<string>;
159+
getPublishHomepage: (workspaceId: string) => Promise<{ view_id: string }>;
160+
updatePublishHomepage: (workspaceId: string, viewId: string) => Promise<void>;
161+
removePublishHomepage: (workspaceId: string) => Promise<void>;
146162

147163
getPublishOutline (namespace: string): Promise<View[]>;
148164

src/application/types.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -684,6 +684,16 @@ export enum CollabOrigin {
684684

685685
}
686686

687+
export interface PublishViewPayload {
688+
publish_name?: string;
689+
visible_database_view_ids?: string[];
690+
}
691+
692+
export interface UploadPublishNamespacePayload {
693+
old_namespace: string;
694+
new_namespace: string;
695+
}
696+
687697
export const layoutMap = {
688698
[ViewLayout.Document]: 'document',
689699
[ViewLayout.Grid]: 'grid',
@@ -1020,4 +1030,11 @@ export interface CreateWorkspacePayload {
10201030

10211031
export interface UpdateWorkspacePayload {
10221032
workspace_name: string;
1033+
}
1034+
1035+
export enum SettingMenuItem {
1036+
ACCOUNT = 'ACCOUNT',
1037+
WORKSPACE = 'WORKSPACE',
1038+
MEMBERS = 'MEMBERS',
1039+
SITES = 'SITES',
10231040
}

src/components/_shared/modal/NormalModal.tsx

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { ReactComponent as CloseIcon } from '@/assets/close.svg';
77
// @ts-ignore
88
export interface NormalModalProps extends DialogProps {
99
okText?: string;
10-
cancelText?: string;
10+
cancelText?: string | React.ReactNode;
1111
onOk?: () => void;
1212
onCancel?: () => void;
1313
danger?: boolean;
@@ -17,6 +17,7 @@ export interface NormalModalProps extends DialogProps {
1717
cancelButtonProps?: ButtonProps;
1818
okLoading?: boolean;
1919
closable?: boolean;
20+
overflowHidden?: boolean;
2021
}
2122

2223
export function NormalModal ({
@@ -32,6 +33,7 @@ export function NormalModal ({
3233
cancelButtonProps,
3334
okLoading,
3435
closable = true,
36+
overflowHidden = false,
3537
...dialogProps
3638
}: NormalModalProps) {
3739
const { t } = useTranslation();
@@ -51,7 +53,12 @@ export function NormalModal ({
5153
}}
5254
{...dialogProps}
5355
>
54-
<div className={'relative flex flex-col gap-4 p-5'}>
56+
<div
57+
style={{
58+
overflow: overflowHidden ? 'hidden' : 'auto',
59+
}}
60+
className={'relative flex flex-col gap-4 p-5'}
61+
>
5562
<div className={'flex w-full items-center justify-between text-base font-medium'}>
5663
<div className={'flex-1 text-center font-medium truncate'}>{title}</div>
5764
{closable && <div className={'relative -right-1.5'}>
@@ -67,7 +74,12 @@ export function NormalModal ({
6774

6875
</div>
6976

70-
<div className={'flex-1'}>{children}</div>
77+
<div
78+
style={{
79+
overflow: overflowHidden ? 'hidden' : 'auto',
80+
}}
81+
className={'flex-1 w-full'}
82+
>{children}</div>
7183
<div className={'flex w-full justify-end gap-3'}>
7284
<Button
7385
color={'inherit'}

src/components/_shared/outline/OutlineItemContent.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import React, { memo } from 'react';
66
import { useTranslation } from 'react-i18next';
77
import PageIcon from '@/components/_shared/view-icon/PageIcon';
88

9-
function OutlineItemContent({
9+
function OutlineItemContent ({
1010
item,
1111
setIsExpanded,
1212
navigateToView,
@@ -53,7 +53,11 @@ function OutlineItemContent({
5353
value={extra.space_icon || ''}
5454
char={extra.space_icon ? undefined : name.slice(0, 1)}
5555
/> :
56-
<PageIcon view={item} className={'flex h-5 w-5 min-w-5 items-center justify-center'}/>
56+
<PageIcon
57+
view={item}
58+
iconSize={16}
59+
className={'flex w-4 h-4 text-sm items-center justify-center'}
60+
/>
5761
}
5862

5963
<Tooltip

0 commit comments

Comments
 (0)