feat: publish workspace lifecycle events
This commit is contained in:
parent
1f1001108b
commit
d46bc9436d
|
|
@ -38,6 +38,10 @@ const pluginEventRuntimeName = "verstak:plugin-event"
|
||||||
const activityGlobalKey = "events:global"
|
const activityGlobalKey = "events:global"
|
||||||
const activityWorkspacePrefix = "events:workspace:"
|
const activityWorkspacePrefix = "events:workspace:"
|
||||||
const maxActivityEvents = 250
|
const maxActivityEvents = 250
|
||||||
|
const workspaceCreatedEventName = "workspace.created"
|
||||||
|
const workspaceRenamedEventName = "workspace.renamed"
|
||||||
|
const workspaceTrashedEventName = "workspace.trashed"
|
||||||
|
const workspaceSelectedEventName = "workspace.selected"
|
||||||
|
|
||||||
// App is the main application struct exposed to the Wails frontend.
|
// App is the main application struct exposed to the Wails frontend.
|
||||||
type App struct {
|
type App struct {
|
||||||
|
|
@ -1051,6 +1055,33 @@ func workspaceRootFromRelativePath(relativePath string) string {
|
||||||
return path
|
return path
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *App) publishWorkspaceLifecycleEvent(eventName string, payload map[string]interface{}) {
|
||||||
|
if a.eventBus == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if payload == nil {
|
||||||
|
payload = map[string]interface{}{}
|
||||||
|
}
|
||||||
|
workspaceRoot := strings.TrimSpace(fmt.Sprint(payload["workspaceRootPath"]))
|
||||||
|
if workspaceRoot == "" || workspaceRoot == "<nil>" {
|
||||||
|
workspaceRoot = strings.TrimSpace(fmt.Sprint(payload["workspaceName"]))
|
||||||
|
}
|
||||||
|
if workspaceRoot != "" && workspaceRoot != "<nil>" {
|
||||||
|
payload["workspaceRootPath"] = workspaceRoot
|
||||||
|
if _, ok := payload["workspaceName"]; !ok {
|
||||||
|
payload["workspaceName"] = workspaceRoot
|
||||||
|
}
|
||||||
|
if _, ok := payload["title"]; !ok {
|
||||||
|
payload["title"] = workspaceRoot
|
||||||
|
}
|
||||||
|
}
|
||||||
|
a.eventBus.Publish(events.Event{
|
||||||
|
Name: eventName,
|
||||||
|
Timestamp: time.Now().UTC().Format(time.RFC3339Nano),
|
||||||
|
Payload: payload,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func syncEntityTypeForFileType(fileType corefiles.FileType) string {
|
func syncEntityTypeForFileType(fileType corefiles.FileType) string {
|
||||||
if fileType == corefiles.FileTypeFolder {
|
if fileType == corefiles.FileTypeFolder {
|
||||||
return syncsvc.EntityFolder
|
return syncsvc.EntityFolder
|
||||||
|
|
@ -1345,6 +1376,12 @@ func (a *App) CreateWorkspace(name, templateID string) (workspace.Workspace, str
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return workspace.Workspace{}, err.Error()
|
return workspace.Workspace{}, err.Error()
|
||||||
}
|
}
|
||||||
|
a.publishWorkspaceLifecycleEvent(workspaceCreatedEventName, map[string]interface{}{
|
||||||
|
"operation": "create",
|
||||||
|
"workspaceRootPath": ws.RootPath,
|
||||||
|
"workspaceName": ws.Name,
|
||||||
|
"templateId": templateID,
|
||||||
|
})
|
||||||
return ws, ""
|
return ws, ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1356,6 +1393,13 @@ func (a *App) RenameWorkspace(oldName, newName string) string {
|
||||||
if err := a.workspace.RenameWorkspace(oldName, newName); err != nil {
|
if err := a.workspace.RenameWorkspace(oldName, newName); err != nil {
|
||||||
return err.Error()
|
return err.Error()
|
||||||
}
|
}
|
||||||
|
a.publishWorkspaceLifecycleEvent(workspaceRenamedEventName, map[string]interface{}{
|
||||||
|
"operation": "rename",
|
||||||
|
"workspaceRootPath": newName,
|
||||||
|
"workspaceName": newName,
|
||||||
|
"previousWorkspaceRootPath": oldName,
|
||||||
|
"previousWorkspaceName": oldName,
|
||||||
|
})
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1368,6 +1412,14 @@ func (a *App) TrashWorkspace(name string) (workspace.TrashResult, string) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return workspace.TrashResult{}, err.Error()
|
return workspace.TrashResult{}, err.Error()
|
||||||
}
|
}
|
||||||
|
a.publishWorkspaceLifecycleEvent(workspaceTrashedEventName, map[string]interface{}{
|
||||||
|
"operation": "trash",
|
||||||
|
"workspaceRootPath": name,
|
||||||
|
"workspaceName": name,
|
||||||
|
"trashId": result.TrashID,
|
||||||
|
"trashPath": result.TrashPath,
|
||||||
|
"deletedAt": result.DeletedAt,
|
||||||
|
})
|
||||||
return result, ""
|
return result, ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1418,6 +1470,11 @@ func (a *App) SetCurrentWorkspace(name string) string {
|
||||||
if err := a.workspace.SetCurrentNode(name); err != nil {
|
if err := a.workspace.SetCurrentNode(name); err != nil {
|
||||||
return err.Error()
|
return err.Error()
|
||||||
}
|
}
|
||||||
|
a.publishWorkspaceLifecycleEvent(workspaceSelectedEventName, map[string]interface{}{
|
||||||
|
"operation": "select",
|
||||||
|
"workspaceRootPath": name,
|
||||||
|
"workspaceName": name,
|
||||||
|
})
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1079,6 +1079,62 @@ func TestWorkspaceAPIUsesTopLevelFoldersAndMetadataSnapshot(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestWorkspaceAPIPublishesLifecycleEvents(t *testing.T) {
|
||||||
|
app, vaultDir := newFilesTestApp(t, []string{"files.read"})
|
||||||
|
app.workspace = workspace.NewManager(vaultDir)
|
||||||
|
app.eventBus = events.NewBus()
|
||||||
|
if err := app.workspace.Load(); err != nil {
|
||||||
|
t.Fatalf("workspace Load: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
received := map[string]map[string]interface{}{}
|
||||||
|
for _, eventName := range []string{"workspace.created", "workspace.selected", "workspace.renamed", "workspace.trashed"} {
|
||||||
|
name := eventName
|
||||||
|
app.eventBus.Subscribe(name, func(event events.Event) {
|
||||||
|
payload, ok := event.Payload.(map[string]interface{})
|
||||||
|
if !ok {
|
||||||
|
t.Fatalf("%s payload type = %T", name, event.Payload)
|
||||||
|
}
|
||||||
|
received[name] = payload
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, errStr := app.CreateWorkspace("Project", "client-project"); errStr != "" {
|
||||||
|
t.Fatalf("CreateWorkspace: %s", errStr)
|
||||||
|
}
|
||||||
|
if errStr := app.SetCurrentWorkspace("Project"); errStr != "" {
|
||||||
|
t.Fatalf("SetCurrentWorkspace: %s", errStr)
|
||||||
|
}
|
||||||
|
if errStr := app.RenameWorkspace("Project", "Renamed"); errStr != "" {
|
||||||
|
t.Fatalf("RenameWorkspace: %s", errStr)
|
||||||
|
}
|
||||||
|
if _, errStr := app.TrashWorkspace("Renamed"); errStr != "" {
|
||||||
|
t.Fatalf("TrashWorkspace: %s", errStr)
|
||||||
|
}
|
||||||
|
|
||||||
|
if got := received["workspace.created"]["workspaceRootPath"]; got != "Project" {
|
||||||
|
t.Fatalf("workspace.created workspaceRootPath = %#v, want Project", got)
|
||||||
|
}
|
||||||
|
if got := received["workspace.created"]["templateId"]; got != "client-project" {
|
||||||
|
t.Fatalf("workspace.created templateId = %#v, want client-project", got)
|
||||||
|
}
|
||||||
|
if got := received["workspace.selected"]["workspaceRootPath"]; got != "Project" {
|
||||||
|
t.Fatalf("workspace.selected workspaceRootPath = %#v, want Project", got)
|
||||||
|
}
|
||||||
|
if got := received["workspace.renamed"]["workspaceRootPath"]; got != "Renamed" {
|
||||||
|
t.Fatalf("workspace.renamed workspaceRootPath = %#v, want Renamed", got)
|
||||||
|
}
|
||||||
|
if got := received["workspace.renamed"]["previousWorkspaceRootPath"]; got != "Project" {
|
||||||
|
t.Fatalf("workspace.renamed previousWorkspaceRootPath = %#v, want Project", got)
|
||||||
|
}
|
||||||
|
if got := received["workspace.trashed"]["workspaceRootPath"]; got != "Renamed" {
|
||||||
|
t.Fatalf("workspace.trashed workspaceRootPath = %#v, want Renamed", got)
|
||||||
|
}
|
||||||
|
if got := received["workspace.trashed"]["trashPath"]; got == "" {
|
||||||
|
t.Fatalf("workspace.trashed trashPath = %#v, want non-empty", got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestMoveWorkspaceNodeCompatibilityIsUnsupported(t *testing.T) {
|
func TestMoveWorkspaceNodeCompatibilityIsUnsupported(t *testing.T) {
|
||||||
app, vaultDir := newFilesTestApp(t, []string{"files.read"})
|
app, vaultDir := newFilesTestApp(t, []string{"files.read"})
|
||||||
app.workspace = workspace.NewManager(vaultDir)
|
app.workspace = workspace.NewManager(vaultDir)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue