feat: support use template on web (#22)
This commit is contained in:
parent
fa43205569
commit
b28f566f0a
|
|
@ -3056,5 +3056,10 @@
|
||||||
"AISearchPlaceholder": "Search or ask a question...",
|
"AISearchPlaceholder": "Search or ask a question...",
|
||||||
"searchLabel": "Search",
|
"searchLabel": "Search",
|
||||||
"publishSelectedViews": "Publish {{count}} selected views",
|
"publishSelectedViews": "Publish {{count}} selected views",
|
||||||
"untitled": "Untitled"
|
"untitled": "Untitled",
|
||||||
|
"addToWorkspace": "Added to your workspace",
|
||||||
|
"downloadTip": "Don't have AppFlowy Apps installed? Download <link/>.",
|
||||||
|
"here": "here",
|
||||||
|
"openInBrowser": "Open in browser",
|
||||||
|
"openInApp": "Open in app"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -972,11 +972,14 @@ export async function duplicatePublishView (workspaceId: string, payload: Duplic
|
||||||
|
|
||||||
const res = await axiosInstance?.post<{
|
const res = await axiosInstance?.post<{
|
||||||
code: number;
|
code: number;
|
||||||
|
data: {
|
||||||
|
view_id: string;
|
||||||
|
};
|
||||||
message: string;
|
message: string;
|
||||||
}>(url, payload);
|
}>(url, payload);
|
||||||
|
|
||||||
if (res?.data.code === 0) {
|
if (res?.data.code === 0) {
|
||||||
return;
|
return res.data.data.view_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Promise.reject(res?.data.message);
|
return Promise.reject(res?.data.message);
|
||||||
|
|
|
||||||
|
|
@ -168,6 +168,6 @@ export interface PublishService {
|
||||||
getPublishViewReactions: (viewId: string, commentId?: string) => Promise<Record<string, Reaction[]>>;
|
getPublishViewReactions: (viewId: string, commentId?: string) => Promise<Record<string, Reaction[]>>;
|
||||||
addPublishViewReaction: (viewId: string, commentId: string, reactionType: string) => Promise<void>;
|
addPublishViewReaction: (viewId: string, commentId: string, reactionType: string) => Promise<void>;
|
||||||
removePublishViewReaction: (viewId: string, commentId: string, reactionType: string) => Promise<void>;
|
removePublishViewReaction: (viewId: string, commentId: string, reactionType: string) => Promise<void>;
|
||||||
duplicatePublishView: (params: DuplicatePublishView) => Promise<void>;
|
duplicatePublishView: (params: DuplicatePublishView) => Promise<string>;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
import { IconButton, Tooltip } from '@mui/material';
|
import { IconButton, Tooltip } from '@mui/material';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
// import { ReactComponent as TemplateIcon } from '@/assets/template.svg';
|
import { ReactComponent as TemplateIcon } from '@/assets/template.svg';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { ReactComponent as TrashIcon } from '@/assets/trash.svg';
|
import { ReactComponent as TrashIcon } from '@/assets/trash.svg';
|
||||||
import { QuickNote } from '@/components/quick-note';
|
import { QuickNote } from '@/components/quick-note';
|
||||||
|
|
||||||
function SideBarBottom() {
|
function SideBarBottom () {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
|
@ -18,16 +18,16 @@ function SideBarBottom() {
|
||||||
className={'flex py-4 border-t border-line-divider gap-1 justify-around items-center'}
|
className={'flex py-4 border-t border-line-divider gap-1 justify-around items-center'}
|
||||||
|
|
||||||
>
|
>
|
||||||
{/*<Tooltip title={t('template.label')}>*/}
|
<Tooltip title={t('template.label')}>
|
||||||
{/* <IconButton*/}
|
<IconButton
|
||||||
{/* size={'small'}*/}
|
size={'small'}
|
||||||
{/* onClick={() => {*/}
|
onClick={() => {
|
||||||
{/* window.open('https://appflowy.io/templates', '_blank');*/}
|
window.open('https://appflowy.io/templates', '_blank');
|
||||||
{/* }}*/}
|
}}
|
||||||
{/* >*/}
|
>
|
||||||
{/* <TemplateIcon/>*/}
|
<TemplateIcon />
|
||||||
{/* </IconButton>*/}
|
</IconButton>
|
||||||
{/*</Tooltip>*/}
|
</Tooltip>
|
||||||
|
|
||||||
<Tooltip title={t('trash.text')}>
|
<Tooltip title={t('trash.text')}>
|
||||||
<IconButton
|
<IconButton
|
||||||
|
|
@ -36,11 +36,11 @@ function SideBarBottom() {
|
||||||
navigate('/app/trash');
|
navigate('/app/trash');
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<TrashIcon/>
|
<TrashIcon />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|
||||||
<QuickNote/>
|
<QuickNote />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { AFConfigContext } from '@/components/main/app.hooks';
|
import { AFConfigContext } from '@/components/main/app.hooks';
|
||||||
import React, { useCallback, useContext, useEffect } from 'react';
|
import React, { useCallback, useContext, useEffect } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { Trans, useTranslation } from 'react-i18next';
|
||||||
import { NormalModal } from '@/components/_shared/modal';
|
import { NormalModal } from '@/components/_shared/modal';
|
||||||
import SelectWorkspace from '@/components/publish/header/duplicate/SelectWorkspace';
|
import SelectWorkspace from '@/components/publish/header/duplicate/SelectWorkspace';
|
||||||
import { useLoadWorkspaces } from '@/components/publish/header/duplicate/useDuplicate';
|
import { useLoadWorkspaces } from '@/components/publish/header/duplicate/useDuplicate';
|
||||||
|
|
@ -31,6 +31,7 @@ function DuplicateModal ({ open, onClose }: { open: boolean; onClose: () => void
|
||||||
const layout = viewMeta?.layout as ViewLayout;
|
const layout = viewMeta?.layout as ViewLayout;
|
||||||
const [loading, setLoading] = React.useState<boolean>(false);
|
const [loading, setLoading] = React.useState<boolean>(false);
|
||||||
const [successModalOpen, setSuccessModalOpen] = React.useState<boolean>(false);
|
const [successModalOpen, setSuccessModalOpen] = React.useState<boolean>(false);
|
||||||
|
const [newViewId, setNewViewId] = React.useState<string | undefined>(undefined);
|
||||||
const {
|
const {
|
||||||
workspaceList,
|
workspaceList,
|
||||||
spaceList,
|
spaceList,
|
||||||
|
|
@ -64,15 +65,18 @@ function DuplicateModal ({ open, onClose }: { open: boolean; onClose: () => void
|
||||||
|
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
try {
|
try {
|
||||||
await service?.duplicatePublishView({
|
const newViewId = await service?.duplicatePublishView({
|
||||||
workspaceId: selectedWorkspaceId,
|
workspaceId: selectedWorkspaceId,
|
||||||
spaceViewId: selectedSpaceId,
|
spaceViewId: selectedSpaceId,
|
||||||
viewId,
|
viewId,
|
||||||
collabType,
|
collabType,
|
||||||
});
|
});
|
||||||
|
|
||||||
onClose();
|
onClose();
|
||||||
setSuccessModalOpen(true);
|
setSuccessModalOpen(true);
|
||||||
|
setNewViewId(newViewId);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
setNewViewId(undefined);
|
||||||
notify.error(t('publish.duplicateFailed'));
|
notify.error(t('publish.duplicateFailed'));
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
|
|
@ -115,18 +119,35 @@ function DuplicateModal ({ open, onClose }: { open: boolean; onClose: () => void
|
||||||
maxWidth: 420,
|
maxWidth: 420,
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
okText={t('publish.useThisTemplate')}
|
okText={t('openInBrowser')}
|
||||||
cancelText={t('publish.downloadIt')}
|
cancelText={t('openInApp')}
|
||||||
onOk={() => window.open(openAppFlowySchema, '_self')}
|
onOk={() => {
|
||||||
|
if (!newViewId || !selectedWorkspaceId) return;
|
||||||
|
window.open(`/app/${selectedWorkspaceId}/${newViewId}`, '_self');
|
||||||
|
}}
|
||||||
onCancel={() => {
|
onCancel={() => {
|
||||||
window.open(downloadPage, '_blank');
|
window.open(openAppFlowySchema, '_self');
|
||||||
}}
|
}}
|
||||||
onClose={() => setSuccessModalOpen(false)}
|
onClose={() => setSuccessModalOpen(false)}
|
||||||
open={successModalOpen}
|
open={successModalOpen}
|
||||||
title={<div className={'text-left'}>{t('publish.duplicateSuccessfully')}</div>}
|
title={
|
||||||
|
<div className={'text-left'}>
|
||||||
|
{t('addToWorkspace')}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<div className={'w-full whitespace-pre-wrap break-words pb-1 text-text-caption'}>
|
<div className={'w-full whitespace-pre-wrap break-words pb-1 text-text-caption'}>
|
||||||
{t('publish.duplicateSuccessfullyDescription')}
|
<Trans
|
||||||
|
i18nKey="downloadTip"
|
||||||
|
components={{
|
||||||
|
link: <span
|
||||||
|
onClick={() => {
|
||||||
|
window.open(downloadPage, '_blank');
|
||||||
|
}}
|
||||||
|
className={'hover:underline cursor-pointer text-fill-default'}
|
||||||
|
>{t('here')}</span>,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</NormalModal>
|
</NormalModal>
|
||||||
</>
|
</>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue