Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
C
canifa_note
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
Vũ Hoàng Anh
canifa_note
Commits
84fb8b22
Unverified
Commit
84fb8b22
authored
Feb 23, 2023
by
boojack
Committed by
GitHub
Feb 23, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: update storage setting section (#1140)
parent
6d2d3221
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
95 additions
and
152 deletions
+95
-152
system.go
server/system.go
+1
-1
CreateIdentityProviderDialog.tsx
web/src/components/CreateIdentityProviderDialog.tsx
+1
-2
CreateStorageServiceDialog.tsx
web/src/components/CreateStorageServiceDialog.tsx
+10
-35
StorageSection.tsx
web/src/components/Settings/StorageSection.tsx
+83
-27
index.ts
web/src/store/index.ts
+0
-2
index.ts
web/src/store/module/index.ts
+0
-1
storage.ts
web/src/store/module/storage.ts
+0
-31
storage.ts
web/src/store/reducer/storage.ts
+0
-53
No files found.
server/system.go
View file @
84fb8b22
...
@@ -99,7 +99,7 @@ func (s *Server) registerSystemRoutes(g *echo.Group) {
...
@@ -99,7 +99,7 @@ func (s *Server) registerSystemRoutes(g *echo.Group) {
systemStatus
.
CustomizedProfile
.
ExternalURL
=
v
.
(
string
)
systemStatus
.
CustomizedProfile
.
ExternalURL
=
v
.
(
string
)
}
}
}
else
if
systemSetting
.
Name
==
api
.
SystemSettingStorageServiceIDName
{
}
else
if
systemSetting
.
Name
==
api
.
SystemSettingStorageServiceIDName
{
systemStatus
.
StorageServiceID
=
value
.
(
int
)
systemStatus
.
StorageServiceID
=
int
(
value
.
(
float64
)
)
}
}
}
}
...
...
web/src/components/CreateIdentityProviderDialog.tsx
View file @
84fb8b22
...
@@ -191,11 +191,10 @@ const CreateIdentityProviderDialog: React.FC<Props> = (props: Props) => {
...
@@ -191,11 +191,10 @@ const CreateIdentityProviderDialog: React.FC<Props> = (props: Props) => {
console
.
error
(
error
);
console
.
error
(
error
);
toastHelper
.
error
(
error
.
response
.
data
.
message
);
toastHelper
.
error
(
error
.
response
.
data
.
message
);
}
}
destroy
();
if
(
confirmCallback
)
{
if
(
confirmCallback
)
{
confirmCallback
();
confirmCallback
();
}
}
destroy
();
};
};
const
setPartialOAuth2Config
=
(
state
:
Partial
<
IdentityProviderOAuth2Config
>
)
=>
{
const
setPartialOAuth2Config
=
(
state
:
Partial
<
IdentityProviderOAuth2Config
>
)
=>
{
...
...
web/src/components/CreateStorageServiceDialog.tsx
View file @
84fb8b22
import
{
useEffect
,
useState
}
from
"react"
;
import
{
useEffect
,
useState
}
from
"react"
;
import
{
useTranslation
}
from
"react-i18next"
;
import
{
useTranslation
}
from
"react-i18next"
;
import
{
Button
,
Input
,
Typography
}
from
"@mui/joy"
;
import
{
Button
,
Input
,
Typography
}
from
"@mui/joy"
;
import
{
useStorageStore
}
from
"../store/module
"
;
import
*
as
api
from
"../helpers/api
"
;
import
{
generateDialog
}
from
"./Dialog"
;
import
{
generateDialog
}
from
"./Dialog"
;
import
Icon
from
"./Icon"
;
import
Icon
from
"./Icon"
;
import
toastHelper
from
"./Toast"
;
import
toastHelper
from
"./Toast"
;
import
{
showCommonDialog
}
from
"./Dialog/CommonDialog"
;
interface
Props
extends
DialogProps
{
interface
Props
extends
DialogProps
{
storage
?:
Storage
;
storage
?:
Storage
;
confirmCallback
?:
()
=>
void
;
}
}
const
CreateStorageServiceDialog
:
React
.
FC
<
Props
>
=
(
props
:
Props
)
=>
{
const
CreateStorageServiceDialog
:
React
.
FC
<
Props
>
=
(
props
:
Props
)
=>
{
const
{
destroy
,
storage
}
=
props
;
const
{
destroy
,
storage
,
confirmCallback
}
=
props
;
const
{
t
}
=
useTranslation
();
const
{
t
}
=
useTranslation
();
const
storageStore
=
useStorageStore
();
const
[
storageCreate
,
setStorageCreate
]
=
useState
<
StorageCreate
>
({
const
[
storageCreate
,
setStorageCreate
]
=
useState
<
StorageCreate
>
({
name
:
""
,
name
:
""
,
endPoint
:
""
,
endPoint
:
""
,
...
@@ -53,9 +52,9 @@ const CreateStorageServiceDialog: React.FC<Props> = (props: Props) => {
...
@@ -53,9 +52,9 @@ const CreateStorageServiceDialog: React.FC<Props> = (props: Props) => {
const
handleConfirmBtnClick
=
async
()
=>
{
const
handleConfirmBtnClick
=
async
()
=>
{
try
{
try
{
if
(
isCreating
)
{
if
(
isCreating
)
{
await
storageStore
.
createStorage
(
storageCreate
);
await
api
.
createStorage
(
storageCreate
);
}
else
{
}
else
{
await
storageStore
.
patchStorage
({
await
api
.
patchStorage
({
id
:
storage
.
id
,
id
:
storage
.
id
,
...
storageCreate
,
...
storageCreate
,
});
});
...
@@ -64,29 +63,10 @@ const CreateStorageServiceDialog: React.FC<Props> = (props: Props) => {
...
@@ -64,29 +63,10 @@ const CreateStorageServiceDialog: React.FC<Props> = (props: Props) => {
console
.
error
(
error
);
console
.
error
(
error
);
toastHelper
.
error
(
error
.
response
.
data
.
message
);
toastHelper
.
error
(
error
.
response
.
data
.
message
);
}
}
destroy
();
if
(
confirmCallback
)
{
};
confirmCallback
();
const
handleDeleteBtnClick
=
async
()
=>
{
if
(
isCreating
)
{
return
;
}
}
destroy
();
showCommonDialog
({
title
:
t
(
"setting.storage-section.delete-storage"
),
content
:
t
(
"setting.storage-section.warning-text"
),
style
:
"warning"
,
dialogName
:
"delete-storage-dialog"
,
onConfirm
:
async
()
=>
{
try
{
await
storageStore
.
deleteStorageById
(
storage
.
id
);
}
catch
(
error
:
any
)
{
console
.
error
(
error
);
toastHelper
.
error
(
error
.
response
.
data
.
message
);
}
destroy
();
},
});
};
};
const
handleNameChange
=
(
event
:
React
.
ChangeEvent
<
HTMLInputElement
>
)
=>
{
const
handleNameChange
=
(
event
:
React
.
ChangeEvent
<
HTMLInputElement
>
)
=>
{
...
@@ -195,11 +175,6 @@ const CreateStorageServiceDialog: React.FC<Props> = (props: Props) => {
...
@@ -195,11 +175,6 @@ const CreateStorageServiceDialog: React.FC<Props> = (props: Props) => {
<
Button
variant=
"plain"
color=
"neutral"
onClick=
{
handleCloseBtnClick
}
>
<
Button
variant=
"plain"
color=
"neutral"
onClick=
{
handleCloseBtnClick
}
>
Cancel
Cancel
</
Button
>
</
Button
>
{
!
isCreating
&&
(
<
Button
color=
"danger"
onClick=
{
handleDeleteBtnClick
}
>
Delete
</
Button
>
)
}
<
Button
onClick=
{
handleConfirmBtnClick
}
disabled=
{
!
allowConfirmAction
()
}
>
<
Button
onClick=
{
handleConfirmBtnClick
}
disabled=
{
!
allowConfirmAction
()
}
>
{
isCreating
?
"Create"
:
"Update"
}
{
isCreating
?
"Create"
:
"Update"
}
</
Button
>
</
Button
>
...
@@ -209,14 +184,14 @@ const CreateStorageServiceDialog: React.FC<Props> = (props: Props) => {
...
@@ -209,14 +184,14 @@ const CreateStorageServiceDialog: React.FC<Props> = (props: Props) => {
);
);
};
};
function
showCreateStorageServiceDialog
(
storage
?:
Storage
)
{
function
showCreateStorageServiceDialog
(
storage
?:
Storage
,
confirmCallback
?:
()
=>
void
)
{
generateDialog
(
generateDialog
(
{
{
className
:
"create-storage-service-dialog"
,
className
:
"create-storage-service-dialog"
,
dialogName
:
"create-storage-service-dialog"
,
dialogName
:
"create-storage-service-dialog"
,
},
},
CreateStorageServiceDialog
,
CreateStorageServiceDialog
,
{
storage
}
{
storage
,
confirmCallback
}
);
);
}
}
...
...
web/src/components/Settings/StorageSection.tsx
View file @
84fb8b22
import
{
Radio
}
from
"@mui/joy"
;
import
{
Divider
,
Select
,
Option
}
from
"@mui/joy"
;
import
React
,
{
useEffect
,
useState
}
from
"react"
;
import
{
useEffect
,
useState
}
from
"react"
;
import
{
useTranslation
}
from
"react-i18next"
;
import
{
useTranslation
}
from
"react-i18next"
;
import
{
useGlobalStore
,
useStorageStore
}
from
"../../store/module"
;
import
{
useGlobalStore
}
from
"../../store/module"
;
import
*
as
api
from
"../../helpers/api"
;
import
*
as
api
from
"../../helpers/api"
;
import
showCreateStorageServiceDialog
from
"../CreateStorageServiceDialog"
;
import
showCreateStorageServiceDialog
from
"../CreateStorageServiceDialog"
;
import
Dropdown
from
"../common/Dropdown"
;
import
{
showCommonDialog
}
from
"../Dialog/CommonDialog"
;
import
toastHelper
from
"../Toast"
;
const
StorageSection
=
()
=>
{
const
StorageSection
=
()
=>
{
const
{
t
}
=
useTranslation
();
const
{
t
}
=
useTranslation
();
const
storageStore
=
useStorageStore
();
const
storages
=
storageStore
.
state
.
storages
;
const
globalStore
=
useGlobalStore
();
const
globalStore
=
useGlobalStore
();
const
systemStatus
=
globalStore
.
state
.
systemStatus
;
const
systemStatus
=
globalStore
.
state
.
systemStatus
;
const
[
storageServiceId
,
setStorageServiceId
]
=
useState
(
systemStatus
.
storageServiceId
);
const
[
storageServiceId
,
setStorageServiceId
]
=
useState
(
systemStatus
.
storageServiceId
);
const
[
storageList
,
setStorageList
]
=
useState
<
Storage
[]
>
([]);
useEffect
(()
=>
{
useEffect
(()
=>
{
storageStore
.
fetchStorages
();
fetchStorageList
();
globalStore
.
fetchSystemStatus
();
},
[]);
},
[]);
useEffect
(()
=>
{
useEffect
(()
=>
{
setStorageServiceId
(
systemStatus
.
storageServiceId
);
setStorageServiceId
(
systemStatus
.
storageServiceId
);
},
[
systemStatus
]);
},
[
systemStatus
]);
const
handleActiveStorageServiceChanged
=
async
(
event
:
React
.
ChangeEvent
<
HTMLInputElement
>
)
=>
{
const
fetchStorageList
=
async
()
=>
{
const
value
=
parseInt
(
event
.
target
.
value
);
const
{
setStorageServiceId
(
value
);
data
:
{
data
:
storageList
},
}
=
await
api
.
getStorageList
();
setStorageList
(
storageList
);
};
const
handleActiveStorageServiceChanged
=
async
(
storageId
:
StorageId
)
=>
{
await
api
.
upsertSystemSetting
({
await
api
.
upsertSystemSetting
({
name
:
"storageServiceId"
,
name
:
"storageServiceId"
,
value
:
JSON
.
stringify
(
value
),
value
:
JSON
.
stringify
(
storageId
),
});
});
setStorageServiceId
(
storageId
);
};
};
const
handleStorageServiceUpdate
=
async
(
event
:
React
.
MouseEvent
,
storage
:
Storage
)
=>
{
const
handleDeleteStorage
=
(
storage
:
Storage
)
=>
{
event
.
preventDefault
();
showCommonDialog
({
showCreateStorageServiceDialog
(
storage
);
title
:
t
(
"setting.storage-section.delete-storage"
),
content
:
t
(
"setting.storage-section.warning-text"
),
style
:
"warning"
,
dialogName
:
"delete-storage-dialog"
,
onConfirm
:
async
()
=>
{
try
{
await
api
.
deleteStorage
(
storage
.
id
);
}
catch
(
error
:
any
)
{
console
.
error
(
error
);
toastHelper
.
error
(
error
.
response
.
data
.
message
);
}
await
fetchStorageList
();
},
});
};
};
return
(
return
(
<
div
className=
"section-container"
>
<
div
className=
"section-container"
>
<
div
className=
"mt-4 mb-2 w-full flex flex-row justify-start items-center"
>
<
span
className=
"font-mono text-sm text-gray-400 mr-2"
>
Current storage
</
span
>
</
div
>
<
Select
className=
"w-full mb-4"
value=
{
storageServiceId
}
onChange=
{
(
_
,
storageId
)
=>
{
handleActiveStorageServiceChanged
(
storageId
||
0
);
}
}
>
{
storageList
.
map
((
storage
)
=>
(
<
Option
key=
{
storage
.
id
}
value=
{
storage
.
id
}
>
{
storage
.
name
}
</
Option
>
))
}
<
Option
value=
{
0
}
>
Database
</
Option
>
</
Select
>
<
Divider
/>
<
div
className=
"mt-4 mb-2 w-full flex flex-row justify-start items-center"
>
<
div
className=
"mt-4 mb-2 w-full flex flex-row justify-start items-center"
>
<
span
className=
"font-mono text-sm text-gray-400 mr-2"
>
{
t
(
"setting.storage-section.storage-services-list"
)
}
</
span
>
<
span
className=
"font-mono text-sm text-gray-400 mr-2"
>
{
t
(
"setting.storage-section.storage-services-list"
)
}
</
span
>
<
button
className=
"btn-normal px-2 py-0 leading-7"
onClick=
{
()
=>
showCreateStorageServiceDialog
()
}
>
<
button
className=
"btn-normal px-2 py-0 leading-7"
onClick=
{
()
=>
showCreateStorageServiceDialog
(
undefined
,
fetchStorageList
)
}
>
{
t
(
"common.create"
)
}
{
t
(
"common.create"
)
}
</
button
>
</
button
>
</
div
>
</
div
>
{
storages
.
map
((
storage
)
=>
(
<
div
className=
"mt-2 w-full flex flex-col"
>
<
label
className=
"w-full my-2 flex flex-row justify-between items-center"
key=
{
storage
.
id
}
>
{
storageList
.
map
((
storage
)
=>
(
<
span
className=
"mr-2 text-sm underline cursor-pointer"
onClick=
{
(
event
)
=>
handleStorageServiceUpdate
(
event
,
storage
)
}
>
<
div
key=
{
storage
.
id
}
className=
"py-2 w-full border-t last:border-b flex flex-row items-center justify-between"
>
{
storage
.
name
}
<
div
className=
"flex flex-row items-center"
>
</
span
>
<
p
className=
"ml-2"
>
{
storage
.
name
}
</
p
>
<
Radio
value=
{
storage
.
id
}
checked=
{
storageServiceId
===
storage
.
id
}
onChange=
{
handleActiveStorageServiceChanged
}
/>
</
div
>
</
label
>
<
div
className=
"flex flex-row items-center"
>
))
}
<
Dropdown
<
label
className=
"w-full my-2 flex flex-row justify-between items-center"
>
actionsClassName=
"!w-28"
<
span
className=
"mr-2 text-sm"
>
{
t
(
"common.database"
)
}
</
span
>
actions=
{
<
Radio
value=
{
0
}
checked=
{
storageServiceId
===
0
}
onChange=
{
handleActiveStorageServiceChanged
}
/>
<>
</
label
>
<
button
className=
"w-full text-left text-sm leading-6 py-1 px-3 cursor-pointer rounded hover:bg-gray-100 dark:hover:bg-zinc-600"
onClick=
{
()
=>
showCreateStorageServiceDialog
(
storage
,
fetchStorageList
)
}
>
Edit
</
button
>
<
button
className=
"w-full text-left text-sm leading-6 py-1 px-3 cursor-pointer rounded text-red-600 hover:bg-gray-100 dark:hover:bg-zinc-600"
onClick=
{
()
=>
handleDeleteStorage
(
storage
)
}
>
{
t
(
"common.delete"
)
}
</
button
>
</>
}
/>
</
div
>
</
div
>
))
}
</
div
>
</
div
>
</
div
>
);
);
};
};
...
...
web/src/store/index.ts
View file @
84fb8b22
...
@@ -9,7 +9,6 @@ import locationReducer from "./reducer/location";
...
@@ -9,7 +9,6 @@ import locationReducer from "./reducer/location";
import
resourceReducer
from
"./reducer/resource"
;
import
resourceReducer
from
"./reducer/resource"
;
import
dialogReducer
from
"./reducer/dialog"
;
import
dialogReducer
from
"./reducer/dialog"
;
import
tagReducer
from
"./reducer/tag"
;
import
tagReducer
from
"./reducer/tag"
;
import
storageReducer
from
"./reducer/storage"
;
const
store
=
configureStore
({
const
store
=
configureStore
({
reducer
:
{
reducer
:
{
...
@@ -22,7 +21,6 @@ const store = configureStore({
...
@@ -22,7 +21,6 @@ const store = configureStore({
location
:
locationReducer
,
location
:
locationReducer
,
resource
:
resourceReducer
,
resource
:
resourceReducer
,
dialog
:
dialogReducer
,
dialog
:
dialogReducer
,
storage
:
storageReducer
,
},
},
});
});
...
...
web/src/store/module/index.ts
View file @
84fb8b22
...
@@ -7,4 +7,3 @@ export * from "./resource";
...
@@ -7,4 +7,3 @@ export * from "./resource";
export
*
from
"./shortcut"
;
export
*
from
"./shortcut"
;
export
*
from
"./user"
;
export
*
from
"./user"
;
export
*
from
"./dialog"
;
export
*
from
"./dialog"
;
export
*
from
"./storage"
;
web/src/store/module/storage.ts
deleted
100644 → 0
View file @
6d2d3221
import
store
,
{
useAppSelector
}
from
".."
;
import
*
as
api
from
"../../helpers/api"
;
import
{
setStorages
,
createStorage
,
patchStorage
,
deleteStorage
}
from
"../reducer/storage"
;
export
const
useStorageStore
=
()
=>
{
const
state
=
useAppSelector
((
state
)
=>
state
.
storage
);
return
{
state
,
getState
:
()
=>
{
return
store
.
getState
().
storage
;
},
fetchStorages
:
async
()
=>
{
const
{
data
}
=
(
await
api
.
getStorageList
()).
data
;
store
.
dispatch
(
setStorages
(
data
));
},
createStorage
:
async
(
storageCreate
:
StorageCreate
)
=>
{
const
{
data
:
storage
}
=
(
await
api
.
createStorage
(
storageCreate
)).
data
;
store
.
dispatch
(
createStorage
(
storage
));
return
storage
;
},
patchStorage
:
async
(
storagePatch
:
StoragePatch
)
=>
{
const
{
data
:
storage
}
=
(
await
api
.
patchStorage
(
storagePatch
)).
data
;
store
.
dispatch
(
patchStorage
(
storage
));
return
storage
;
},
deleteStorageById
:
async
(
storageId
:
StorageId
)
=>
{
await
api
.
deleteStorage
(
storageId
);
store
.
dispatch
(
deleteStorage
(
storageId
));
},
};
};
web/src/store/reducer/storage.ts
deleted
100644 → 0
View file @
6d2d3221
import
{
createSlice
,
PayloadAction
}
from
"@reduxjs/toolkit"
;
interface
State
{
storages
:
Storage
[];
}
const
storageSlice
=
createSlice
({
name
:
"storage"
,
initialState
:
{
storages
:
[],
}
as
State
,
reducers
:
{
setStorages
:
(
state
,
action
:
PayloadAction
<
Storage
[]
>
)
=>
{
return
{
...
state
,
storages
:
action
.
payload
,
};
},
createStorage
:
(
state
,
action
:
PayloadAction
<
Storage
>
)
=>
{
return
{
...
state
,
storages
:
[
action
.
payload
].
concat
(
state
.
storages
),
};
},
patchStorage
:
(
state
,
action
:
PayloadAction
<
Partial
<
Storage
>>
)
=>
{
return
{
...
state
,
storages
:
state
.
storages
.
map
((
storage
)
=>
{
if
(
storage
.
id
===
action
.
payload
.
id
)
{
return
{
...
storage
,
...
action
.
payload
,
};
}
else
{
return
storage
;
}
}),
};
},
deleteStorage
:
(
state
,
action
:
PayloadAction
<
StorageId
>
)
=>
{
return
{
...
state
,
storages
:
state
.
storages
.
filter
((
storage
)
=>
{
return
storage
.
id
!==
action
.
payload
;
}),
};
},
},
});
export
const
{
setStorages
,
createStorage
,
patchStorage
,
deleteStorage
}
=
storageSlice
.
actions
;
export
default
storageSlice
.
reducer
;
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