feat(explore): allow deleting source categories

This commit is contained in:
2026-07-24 10:37:46 +08:00
parent fd8a2110a1
commit 7c9d5e4560
5 changed files with 7 additions and 15 deletions

View File

@@ -710,6 +710,7 @@
.explore-source-row { .explore-source-row {
min-width: 0; min-width: 0;
row-gap: 12px;
} }
.explore-source-card.arco-card { .explore-source-card.arco-card {
@@ -1078,10 +1079,6 @@
max-width: 100%; max-width: 100%;
} }
.explore-source-row {
row-gap: 10px;
}
.explore-reader-layout { .explore-reader-layout {
grid-template-columns: minmax(0, 1fr); grid-template-columns: minmax(0, 1fr);
} }

View File

@@ -372,9 +372,7 @@ export function WorkspaceExplorePage({
{source.id !== 'all' ? ( {source.id !== 'all' ? (
<span className="explore-source-actions" onClick={(event) => event.stopPropagation()}> <span className="explore-source-actions" onClick={(event) => event.stopPropagation()}>
<Button aria-label={`编辑${source.name}`} type="text" size="mini" icon={<IconEdit />} onClick={() => openEditSource(source)} /> <Button aria-label={`编辑${source.name}`} type="text" size="mini" icon={<IconEdit />} onClick={() => openEditSource(source)} />
{!source.builtIn ? ( <Button aria-label={`删除${source.name}`} type="text" size="mini" status="danger" icon={<IconDelete />} onClick={() => deleteSource(source)} />
<Button aria-label={`删除${source.name}`} type="text" size="mini" status="danger" icon={<IconDelete />} onClick={() => deleteSource(source)} />
) : null}
</span> </span>
) : null} ) : null}
</Card> </Card>

View File

@@ -341,8 +341,6 @@ func writeError(c *gin.Context, err error) {
switch { switch {
case errors.Is(err, gorm.ErrRecordNotFound): case errors.Is(err, gorm.ErrRecordNotFound):
httpx.Error(c, http.StatusNotFound, "not_found", "数据源或数据条目不存在") httpx.Error(c, http.StatusNotFound, "not_found", "数据源或数据条目不存在")
case errors.Is(err, ErrBuiltInSource):
httpx.Error(c, http.StatusConflict, "built_in_source", "内置数据源不能删除,可以将其停用")
case errors.Is(err, ErrSyncInProgress): case errors.Is(err, ErrSyncInProgress):
httpx.Error(c, http.StatusConflict, "sync_in_progress", "已有数据源采集任务正在运行") httpx.Error(c, http.StatusConflict, "sync_in_progress", "已有数据源采集任务正在运行")
case errors.Is(err, ErrNameRequired), errors.Is(err, ErrKindInvalid), case errors.Is(err, ErrNameRequired), errors.Is(err, ErrKindInvalid),

View File

@@ -196,7 +196,7 @@ func TestDatasetItemsArePaginatedByOwnedSource(t *testing.T) {
require.Len(t, page.Items, 2) require.Len(t, page.Items, 2)
} }
func TestBuiltInDatasetSourceKeepsManagedFieldsAndCannotBeDeleted(t *testing.T) { func TestBuiltInDatasetSourceKeepsManagedFieldsAndCanBeDeleted(t *testing.T) {
database := newDatasetTestDatabase(t) database := newDatasetTestDatabase(t)
owner := createDatasetTestUser(t, database, "owner@example.com") owner := createDatasetTestUser(t, database, "owner@example.com")
seedKey := "built-in" seedKey := "built-in"
@@ -224,7 +224,10 @@ func TestBuiltInDatasetSourceKeepsManagedFieldsAndCannotBeDeleted(t *testing.T)
require.Equal(t, renamed, updated.Name) require.Equal(t, renamed, updated.Name)
require.False(t, updated.Enabled) require.False(t, updated.Enabled)
require.Equal(t, "https://example.com/feed", updated.URL) require.Equal(t, "https://example.com/feed", updated.URL)
require.ErrorIs(t, service.DeleteSource(owner.ID, source.Identity), ErrBuiltInSource) require.NoError(t, service.DeleteSource(owner.ID, source.Identity))
var count int64
require.NoError(t, database.Model(&models.SaDatasetSource{}).Where("id = ?", source.ID).Count(&count).Error)
require.Zero(t, count)
} }
func newDatasetTestDatabase(t *testing.T) *gorm.DB { func newDatasetTestDatabase(t *testing.T) *gorm.DB {

View File

@@ -20,7 +20,6 @@ var (
ErrURLInvalid = errors.New("dataset source url is invalid") ErrURLInvalid = errors.New("dataset source url is invalid")
ErrTitleRequired = errors.New("dataset item title is required") ErrTitleRequired = errors.New("dataset item title is required")
ErrStatusInvalid = errors.New("dataset item status is invalid") ErrStatusInvalid = errors.New("dataset item status is invalid")
ErrBuiltInSource = errors.New("built-in dataset source cannot be deleted")
ErrSyncInProgress = errors.New("dataset sync is already in progress") ErrSyncInProgress = errors.New("dataset sync is already in progress")
) )
@@ -226,9 +225,6 @@ func (s *Service) DeleteSource(userID uint, identity string) error {
if err := tx.Where("identity = ? AND owner_id = ?", identity, userID).First(&source).Error; err != nil { if err := tx.Where("identity = ? AND owner_id = ?", identity, userID).First(&source).Error; err != nil {
return err return err
} }
if source.SeedKey != nil {
return ErrBuiltInSource
}
if err := tx.Where("source_id = ?", source.ID).Delete(&models.SaDatasetItem{}).Error; err != nil { if err := tx.Where("source_id = ?", source.ID).Delete(&models.SaDatasetItem{}).Error; err != nil {
return err return err
} }