Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
D
dify
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ai-tech
dify
Commits
433f8cb5
Unverified
Commit
433f8cb5
authored
Jun 13, 2023
by
crazywoola
Committed by
GitHub
Jun 13, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Feature/add emoji to webapp (#345)
parent
cd136fb2
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
99 additions
and
75 deletions
+99
-75
NewAppDialog.tsx
web/app/(commonLayout)/apps/NewAppDialog.tsx
+1
-2
index.tsx
web/app/components/app/overview/customize/index.tsx
+2
-4
index.tsx
web/app/components/app/overview/settings/index.tsx
+86
-62
index.tsx
web/app/components/base/loading/index.tsx
+2
-2
style.css
web/app/components/base/loading/style.css
+5
-5
app.ts
web/types/app.ts
+3
-0
No files found.
web/app/(commonLayout)/apps/NewAppDialog.tsx
View file @
433f8cb5
...
@@ -52,7 +52,7 @@ const NewAppDialog = ({ show, onSuccess, onClose }: NewAppDialogProps) => {
...
@@ -52,7 +52,7 @@ const NewAppDialog = ({ show, onSuccess, onClose }: NewAppDialogProps) => {
mutateTemplates
()
mutateTemplates
()
setIsWithTemplate
(
false
)
setIsWithTemplate
(
false
)
}
}
},
[
show
])
},
[
mutateTemplates
,
show
])
const
isCreatingRef
=
useRef
(
false
)
const
isCreatingRef
=
useRef
(
false
)
const
onCreate
:
MouseEventHandler
=
useCallback
(
async
()
=>
{
const
onCreate
:
MouseEventHandler
=
useCallback
(
async
()
=>
{
...
@@ -97,7 +97,6 @@ const NewAppDialog = ({ show, onSuccess, onClose }: NewAppDialogProps) => {
...
@@ -97,7 +97,6 @@ const NewAppDialog = ({ show, onSuccess, onClose }: NewAppDialogProps) => {
return
<>
return
<>
{
showEmojiPicker
&&
<
EmojiPicker
{
showEmojiPicker
&&
<
EmojiPicker
onSelect=
{
(
icon
,
icon_background
)
=>
{
onSelect=
{
(
icon
,
icon_background
)
=>
{
console
.
log
(
icon
,
icon_background
)
setEmoji
({
icon
,
icon_background
})
setEmoji
({
icon
,
icon_background
})
setShowEmojiPicker
(
false
)
setShowEmojiPicker
(
false
)
}
}
}
}
...
...
web/app/components/app/overview/customize/index.tsx
View file @
433f8cb5
'use client'
'use client'
import
type
{
FC
}
from
'react'
import
type
{
FC
}
from
'react'
import
React
from
'react'
import
React
from
'react'
import
{
AppMode
}
from
'@/types/app'
import
{
ArrowTopRightOnSquareIcon
}
from
'@heroicons/react/24/outline'
import
{
ArrowTopRightOnSquareIcon
}
from
'@heroicons/react/24/outline'
import
{
useTranslation
}
from
'react-i18next'
import
{
useTranslation
}
from
'react-i18next'
import
{
useContext
}
from
'use-context-selector'
import
{
useContext
}
from
'use-context-selector'
import
type
{
AppMode
}
from
'@/types/app'
import
I18n
from
'@/context/i18n'
import
I18n
from
'@/context/i18n'
import
Button
from
'@/app/components/base/button'
import
Button
from
'@/app/components/base/button'
import
Modal
from
'@/app/components/base/modal'
import
Modal
from
'@/app/components/base/modal'
...
@@ -23,8 +23,6 @@ const StepNum: FC<{ children: React.ReactNode }> = ({ children }) =>
...
@@ -23,8 +23,6 @@ const StepNum: FC<{ children: React.ReactNode }> = ({ children }) =>
{
children
}
{
children
}
</
div
>
</
div
>
const
GithubIcon
=
({
className
}:
{
className
:
string
})
=>
{
const
GithubIcon
=
({
className
}:
{
className
:
string
})
=>
{
return
(
return
(
<
svg
width=
"18"
height=
"18"
viewBox=
"0 0 18 18"
fill=
"none"
xmlns=
"http://www.w3.org/2000/svg"
className=
{
className
}
>
<
svg
width=
"18"
height=
"18"
viewBox=
"0 0 18 18"
fill=
"none"
xmlns=
"http://www.w3.org/2000/svg"
className=
{
className
}
>
...
@@ -73,7 +71,7 @@ const CustomizeModal: FC<IShareLinkProps> = ({
...
@@ -73,7 +71,7 @@ const CustomizeModal: FC<IShareLinkProps> = ({
<
div
className=
'text-gray-500 text-xs mt-1 mb-2'
>
{
t
(
`${prefixCustomize}.way1.step2Tip`
)
}
</
div
>
<
div
className=
'text-gray-500 text-xs mt-1 mb-2'
>
{
t
(
`${prefixCustomize}.way1.step2Tip`
)
}
</
div
>
<
pre
className=
'box-border py-3 px-4 bg-gray-100 text-xs font-medium rounded-lg select-text'
>
<
pre
className=
'box-border py-3 px-4 bg-gray-100 text-xs font-medium rounded-lg select-text'
>
export const APP_ID = '
{
appId
}
'
<
br
/>
export const APP_ID = '
{
appId
}
'
<
br
/>
export const API_KEY =
{
`'<Web API Key From Dify>'`
}
export const API_KEY =
{
'
\'
<Web API Key From Dify>
\'
'
}
</
pre
>
</
pre
>
</
div
>
</
div
>
</
div
>
</
div
>
...
...
web/app/components/app/overview/settings/index.tsx
View file @
433f8cb5
...
@@ -7,11 +7,11 @@ import { Trans, useTranslation } from 'react-i18next'
...
@@ -7,11 +7,11 @@ import { Trans, useTranslation } from 'react-i18next'
import
s
from
'./style.module.css'
import
s
from
'./style.module.css'
import
Modal
from
'@/app/components/base/modal'
import
Modal
from
'@/app/components/base/modal'
import
Button
from
'@/app/components/base/button'
import
Button
from
'@/app/components/base/button'
import
Switch
from
'@/app/components/base/switch'
import
AppIcon
from
'@/app/components/base/app-icon'
import
AppIcon
from
'@/app/components/base/app-icon'
import
{
SimpleSelect
}
from
'@/app/components/base/select'
import
{
SimpleSelect
}
from
'@/app/components/base/select'
import
type
{
AppDetailResponse
}
from
'@/models/app'
import
type
{
AppDetailResponse
}
from
'@/models/app'
import
type
{
Language
}
from
'@/types/app'
import
type
{
Language
}
from
'@/types/app'
import
EmojiPicker
from
'@/app/components/base/emoji-picker'
export
type
ISettingsModalProps
=
{
export
type
ISettingsModalProps
=
{
appInfo
:
AppDetailResponse
appInfo
:
AppDetailResponse
...
@@ -42,11 +42,14 @@ const SettingsModal: FC<ISettingsModalProps> = ({
...
@@ -42,11 +42,14 @@ const SettingsModal: FC<ISettingsModalProps> = ({
onSave
,
onSave
,
})
=>
{
})
=>
{
const
[
isShowMore
,
setIsShowMore
]
=
useState
(
false
)
const
[
isShowMore
,
setIsShowMore
]
=
useState
(
false
)
const
{
title
,
description
,
copyright
,
privacy_policy
,
default_language
}
=
appInfo
.
site
const
{
title
,
description
,
copyright
,
privacy_policy
,
default_language
,
icon
,
icon_background
}
=
appInfo
.
site
const
[
inputInfo
,
setInputInfo
]
=
useState
({
title
,
desc
:
description
,
copyright
,
privacyPolicy
:
privacy_policy
})
const
[
inputInfo
,
setInputInfo
]
=
useState
({
title
,
desc
:
description
,
copyright
,
privacyPolicy
:
privacy_policy
})
const
[
language
,
setLanguage
]
=
useState
(
default_language
)
const
[
language
,
setLanguage
]
=
useState
(
default_language
)
const
[
saveLoading
,
setSaveLoading
]
=
useState
(
false
)
const
[
saveLoading
,
setSaveLoading
]
=
useState
(
false
)
const
{
t
}
=
useTranslation
()
const
{
t
}
=
useTranslation
()
// Emoji Picker
const
[
showEmojiPicker
,
setShowEmojiPicker
]
=
useState
(
false
)
const
[
emoji
,
setEmoji
]
=
useState
({
icon
,
icon_background
})
const
onHide
=
()
=>
{
const
onHide
=
()
=>
{
onClose
()
onClose
()
...
@@ -64,6 +67,8 @@ const SettingsModal: FC<ISettingsModalProps> = ({
...
@@ -64,6 +67,8 @@ const SettingsModal: FC<ISettingsModalProps> = ({
prompt_public
:
false
,
prompt_public
:
false
,
copyright
:
inputInfo
.
copyright
,
copyright
:
inputInfo
.
copyright
,
privacy_policy
:
inputInfo
.
privacyPolicy
,
privacy_policy
:
inputInfo
.
privacyPolicy
,
icon
:
emoji
.
icon
,
icon_background
:
emoji
.
icon_background
,
}
}
await
onSave
(
params
)
await
onSave
(
params
)
setSaveLoading
(
false
)
setSaveLoading
(
false
)
...
@@ -77,69 +82,88 @@ const SettingsModal: FC<ISettingsModalProps> = ({
...
@@ -77,69 +82,88 @@ const SettingsModal: FC<ISettingsModalProps> = ({
}
}
return
(
return
(
<
Modal
<>
title=
{
t
(
`${prefixSettings}.title`
)
}
{
showEmojiPicker
&&
<
EmojiPicker
isShow=
{
isShow
}
onSelect=
{
(
icon
,
icon_background
)
=>
{
onClose=
{
onHide
}
console
.
log
(
icon
,
icon_background
)
className=
{
`${s.settingsModal}`
}
setEmoji
({
icon
,
icon_background
})
>
setShowEmojiPicker
(
false
)
<
div
className=
{
`mt-6 font-medium ${s.settingTitle} text-gray-900`
}
>
{
t
(
`${prefixSettings}.webName`
)
}
</
div
>
}
}
<
div
className=
'flex mt-2'
>
onClose=
{
()
=>
{
<
AppIcon
className=
'!mr-3 self-center'
/>
setEmoji
({
icon
:
'🤖'
,
icon_background
:
'#FFEAD5'
})
<
input
className=
{
`flex-grow rounded-lg h-10 box-border px-3 ${s.projectName} bg-gray-100`
}
setShowEmojiPicker
(
false
)
value=
{
inputInfo
.
title
}
}
}
onChange=
{
onChange
(
'title'
)
}
/>
/>
}
</
div
>
<
Modal
<
div
className=
{
`mt-6 font-medium ${s.settingTitle} text-gray-900 `
}
>
{
t
(
`${prefixSettings}.webDesc`
)
}
</
div
>
title=
{
t
(
`${prefixSettings}.title`
)
}
<
p
className=
{
`mt-1 ${s.settingsTip} text-gray-500`
}
>
{
t
(
`${prefixSettings}.webDescTip`
)
}
</
p
>
isShow=
{
isShow
}
<
textarea
onClose=
{
onHide
}
rows=
{
3
}
className=
{
`${s.settingsModal}`
}
className=
{
`mt-2 pt-2 pb-2 px-3 rounded-lg bg-gray-100 w-full ${s.settingsTip} text-gray-900`
}
>
value=
{
inputInfo
.
desc
}
<
div
className=
{
`mt-6 font-medium ${s.settingTitle} text-gray-900`
}
>
{
t
(
`${prefixSettings}.webName`
)
}
</
div
>
onChange=
{
onChange
(
'desc'
)
}
<
div
className=
'flex mt-2'
>
placeholder=
{
t
(
`${prefixSettings}.webDescPlaceholder`
)
as
string
}
<
AppIcon
size=
'large'
/>
onClick=
{
()
=>
{
setShowEmojiPicker
(
true
)
}
}
<
div
className=
{
`mt-6 mb-2 font-medium ${s.settingTitle} text-gray-900 `
}
>
{
t
(
`${prefixSettings}.language`
)
}
</
div
>
className=
'cursor-pointer !mr-3 self-center'
<
SimpleSelect
icon=
{
emoji
.
icon
}
items=
{
Object
.
keys
(
LANGUAGE_MAP
).
map
(
lang
=>
({
name
:
LANGUAGE_MAP
[
lang
as
Language
],
value
:
lang
}))
}
background=
{
emoji
.
icon_background
}
defaultValue=
{
language
}
/>
onSelect=
{
item
=>
setLanguage
(
item
.
value
as
Language
)
}
<
input
className=
{
`flex-grow rounded-lg h-10 box-border px-3 ${s.projectName} bg-gray-100`
}
/>
value=
{
inputInfo
.
title
}
{
!
isShowMore
&&
<
div
className=
'w-full cursor-pointer mt-8'
onClick=
{
()
=>
setIsShowMore
(
true
)
}
>
onChange=
{
onChange
(
'title'
)
}
/>
<
div
className=
'flex justify-between'
>
<
div
className=
{
`font-medium ${s.settingTitle} flex-grow text-gray-900`
}
>
{
t
(
`${prefixSettings}.more.entry`
)
}
</
div
>
<
div
className=
'flex-shrink-0 w-4 h-4 text-gray-500'
>
<
ChevronRightIcon
/>
</
div
>
</
div
>
</
div
>
<
p
className=
{
`mt-1 ${s.policy} text-gray-500`
}
>
{
t
(
`${prefixSettings}.more.copyright`
)
}
&
{
t
(
`${prefixSettings}.more.privacyPolicy`
)
}
</
p
>
<
div
className=
{
`mt-6 font-medium ${s.settingTitle} text-gray-900 `
}
>
{
t
(
`${prefixSettings}.webDesc`
)
}
</
div
>
</
div
>
}
<
p
className=
{
`mt-1 ${s.settingsTip} text-gray-500`
}
>
{
t
(
`${prefixSettings}.webDescTip`
)
}
</
p
>
{
isShowMore
&&
<>
<
textarea
<
hr
className=
'w-full mt-6'
/>
rows=
{
3
}
<
div
className=
{
`mt-6 font-medium ${s.settingTitle} text-gray-900`
}
>
{
t
(
`${prefixSettings}.more.copyright`
)
}
</
div
>
className=
{
`mt-2 pt-2 pb-2 px-3 rounded-lg bg-gray-100 w-full ${s.settingsTip} text-gray-900`
}
<
input
className=
{
`w-full mt-2 rounded-lg h-10 box-border px-3 ${s.projectName} bg-gray-100`
}
value=
{
inputInfo
.
desc
}
value=
{
inputInfo
.
copyright
}
onChange=
{
onChange
(
'desc'
)
}
onChange=
{
onChange
(
'copyright'
)
}
placeholder=
{
t
(
`${prefixSettings}.webDescPlaceholder`
)
as
string
}
placeholder=
{
t
(
`${prefixSettings}.more.copyRightPlaceholder`
)
as
string
}
/>
/>
<
div
className=
{
`mt-8 font-medium ${s.settingTitle} text-gray-900`
}
>
{
t
(
`${prefixSettings}.more.privacyPolicy`
)
}
</
div
>
<
div
className=
{
`mt-6 mb-2 font-medium ${s.settingTitle} text-gray-900 `
}
>
{
t
(
`${prefixSettings}.language`
)
}
</
div
>
<
p
className=
{
`mt-1 ${s.settingsTip} text-gray-500`
}
>
<
SimpleSelect
<
Trans
items=
{
Object
.
keys
(
LANGUAGE_MAP
).
map
(
lang
=>
({
name
:
LANGUAGE_MAP
[
lang
as
Language
],
value
:
lang
}))
}
i18nKey=
{
`${prefixSettings}.more.privacyPolicyTip`
}
defaultValue=
{
language
}
components=
{
{
privacyPolicyLink
:
<
Link
href=
{
'https://langgenius.ai/privacy-policy'
}
target=
'_blank'
className=
'text-primary-600'
/>
}
}
onSelect=
{
item
=>
setLanguage
(
item
.
value
as
Language
)
}
/>
</
p
>
<
input
className=
{
`w-full mt-2 rounded-lg h-10 box-border px-3 ${s.projectName} bg-gray-100`
}
value=
{
inputInfo
.
privacyPolicy
}
onChange=
{
onChange
(
'privacyPolicy'
)
}
placeholder=
{
t
(
`${prefixSettings}.more.privacyPolicyPlaceholder`
)
as
string
}
/>
/>
</>
}
{
!
isShowMore
&&
<
div
className=
'w-full cursor-pointer mt-8'
onClick=
{
()
=>
setIsShowMore
(
true
)
}
>
<
div
className=
'mt-10 flex justify-end'
>
<
div
className=
'flex justify-between'
>
<
Button
className=
'mr-2 flex-shrink-0'
onClick=
{
onHide
}
>
{
t
(
'common.operation.cancel'
)
}
</
Button
>
<
div
className=
{
`font-medium ${s.settingTitle} flex-grow text-gray-900`
}
>
{
t
(
`${prefixSettings}.more.entry`
)
}
</
div
>
<
Button
type=
'primary'
className=
'flex-shrink-0'
onClick=
{
onClickSave
}
loading=
{
saveLoading
}
>
{
t
(
'common.operation.save'
)
}
</
Button
>
<
div
className=
'flex-shrink-0 w-4 h-4 text-gray-500'
>
</
div
>
<
ChevronRightIcon
/>
</
Modal
>
</
div
>
</
div
>
<
p
className=
{
`mt-1 ${s.policy} text-gray-500`
}
>
{
t
(
`${prefixSettings}.more.copyright`
)
}
&
{
t
(
`${prefixSettings}.more.privacyPolicy`
)
}
</
p
>
</
div
>
}
{
isShowMore
&&
<>
<
hr
className=
'w-full mt-6'
/>
<
div
className=
{
`mt-6 font-medium ${s.settingTitle} text-gray-900`
}
>
{
t
(
`${prefixSettings}.more.copyright`
)
}
</
div
>
<
input
className=
{
`w-full mt-2 rounded-lg h-10 box-border px-3 ${s.projectName} bg-gray-100`
}
value=
{
inputInfo
.
copyright
}
onChange=
{
onChange
(
'copyright'
)
}
placeholder=
{
t
(
`${prefixSettings}.more.copyRightPlaceholder`
)
as
string
}
/>
<
div
className=
{
`mt-8 font-medium ${s.settingTitle} text-gray-900`
}
>
{
t
(
`${prefixSettings}.more.privacyPolicy`
)
}
</
div
>
<
p
className=
{
`mt-1 ${s.settingsTip} text-gray-500`
}
>
<
Trans
i18nKey=
{
`${prefixSettings}.more.privacyPolicyTip`
}
components=
{
{
privacyPolicyLink
:
<
Link
href=
{
'https://langgenius.ai/privacy-policy'
}
target=
'_blank'
className=
'text-primary-600'
/>
}
}
/>
</
p
>
<
input
className=
{
`w-full mt-2 rounded-lg h-10 box-border px-3 ${s.projectName} bg-gray-100`
}
value=
{
inputInfo
.
privacyPolicy
}
onChange=
{
onChange
(
'privacyPolicy'
)
}
placeholder=
{
t
(
`${prefixSettings}.more.privacyPolicyPlaceholder`
)
as
string
}
/>
</>
}
<
div
className=
'mt-10 flex justify-end'
>
<
Button
className=
'mr-2 flex-shrink-0'
onClick=
{
onHide
}
>
{
t
(
'common.operation.cancel'
)
}
</
Button
>
<
Button
type=
'primary'
className=
'flex-shrink-0'
onClick=
{
onClickSave
}
loading=
{
saveLoading
}
>
{
t
(
'common.operation.save'
)
}
</
Button
>
</
div
>
</
Modal
>
</>
)
)
}
}
export
default
React
.
memo
(
SettingsModal
)
export
default
React
.
memo
(
SettingsModal
)
web/app/components/base/loading/index.tsx
View file @
433f8cb5
import
React
from
'react'
import
React
from
'react'
import
'./style.css'
import
'./style.css'
interface
ILoadingProps
{
type
ILoadingProps
=
{
type
?:
'area'
|
'app'
type
?:
'area'
|
'app'
}
}
const
Loading
=
(
const
Loading
=
(
{
type
=
'area'
}:
ILoadingProps
=
{
type
:
'area'
}
{
type
=
'area'
}:
ILoadingProps
=
{
type
:
'area'
}
,
)
=>
{
)
=>
{
return
(
return
(
<
div
className=
{
`flex w-full justify-center items-center ${type === 'app' ? 'h-full' : ''}`
}
>
<
div
className=
{
`flex w-full justify-center items-center ${type === 'app' ? 'h-full' : ''}`
}
>
...
...
web/app/components/base/loading/style.css
View file @
433f8cb5
.spin-animation
path
{
.spin-animation
path
{
animation
:
custom
2
s
linear
infinite
;
animation
:
custom
1
s
linear
infinite
;
}
}
@keyframes
custom
{
@keyframes
custom
{
...
@@ -29,13 +29,13 @@
...
@@ -29,13 +29,13 @@
}
}
.spin-animation
path
:nth-child
(
2
)
{
.spin-animation
path
:nth-child
(
2
)
{
animation-delay
:
0.5s
;
animation-delay
:
0.
2
5s
;
}
}
.spin-animation
path
:nth-child
(
3
)
{
.spin-animation
path
:nth-child
(
3
)
{
animation-delay
:
1
s
;
animation-delay
:
0.5
s
;
}
}
.spin-animation
path
:nth-child
(
4
)
{
.spin-animation
path
:nth-child
(
4
)
{
animation-delay
:
1.5s
;
animation-delay
:
1s
;
}
}
\ No newline at end of file
web/types/app.ts
View file @
433f8cb5
...
@@ -179,6 +179,9 @@ export type SiteConfig = {
...
@@ -179,6 +179,9 @@ export type SiteConfig = {
copyright
:
string
copyright
:
string
/** Privacy Policy */
/** Privacy Policy */
privacy_policy
:
string
privacy_policy
:
string
icon
:
string
icon_background
:
string
}
}
/**
/**
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment