diff --git a/api/user.go b/api/user.go index b8e91e22..22da9056 100644 --- a/api/user.go +++ b/api/user.go @@ -16,6 +16,7 @@ type contentURLAPI struct { ReviewTask string `json:"review_task"` Signal string `json:"signal"` Upload string `json:"upload"` + Users string `json:"users"` } type contentURLs struct { API contentURLAPI `json:"api"` @@ -48,6 +49,7 @@ func getUserSelf(ctx context.Context, r *http.Request, user platform.User, query ReviewTask: config.MakeURLNidus("/api/review-task"), Signal: config.MakeURLNidus("/api/signal"), Upload: config.MakeURLNidus("/api/upload"), + Users: config.MakeURLNidus("/api/user"), }, Tegola: urls.Tegola, Tile: config.MakeURLNidus("/api/tile/{z}/{y}/{x}"), @@ -56,20 +58,30 @@ func getUserSelf(ctx context.Context, r *http.Request, user platform.User, query } type responseListUser struct { - Users []platform.User `json:"users"` + Users []*platform.User `json:"users"` } func listUser(ctx context.Context, r *http.Request, user platform.User, query queryParams) (*responseListUser, *nhttp.ErrorWithStatus) { + users, err := platform.UsersByOrg(ctx, user.Organization) + if err != nil { + return nil, nhttp.NewError("list users: %w", err) + } + results := make([]*platform.User, len(users)) + i := 0 + for _, v := range users { + results[i] = v + i++ + } return &responseListUser{ - Users: []platform.User{}, + Users: results, }, nil } type responseListUserSuggestion struct { - Users []platform.User `json:"users"` + Users []*platform.User `json:"users"` } -func listUserSuggestion(ctx context.Context, r *http.Request, user platform.User, query queryParams) (*responseListUser, *nhttp.ErrorWithStatus) { +func listUserSuggestion(ctx context.Context, r *http.Request, user platform.User, query queryParams) (*responseListUserSuggestion, *nhttp.ErrorWithStatus) { if query.Query == nil { return nil, nhttp.NewErrorStatus(http.StatusBadRequest, "you need to include a query") } @@ -77,7 +89,7 @@ func listUserSuggestion(ctx context.Context, r *http.Request, user platform.User if err != nil { return nil, nhttp.NewError("query suggestions: %w", err) } - return &responseListUser{ + return &responseListUserSuggestion{ Users: users, }, nil } diff --git a/platform/user.go b/platform/user.go index 4032689f..83ce5c5e 100644 --- a/platform/user.go +++ b/platform/user.go @@ -114,7 +114,7 @@ func UsersByOrg(ctx context.Context, org Organization) (map[int32]*User, error) } return results, nil } -func UserSuggestion(ctx context.Context, user User, query string) ([]User, error) { +func UserSuggestion(ctx context.Context, user User, query string) ([]*User, error) { query_arg := "%" + query + "%" if user.HasRoot() { return userSuggestionRoot(ctx, user, query_arg) @@ -122,7 +122,7 @@ func UserSuggestion(ctx context.Context, user User, query string) ([]User, error return userSuggestionNonRoot(ctx, user, query_arg) } } -func userSuggestionNonRoot(ctx context.Context, user User, query_arg string) ([]User, error) { +func userSuggestionNonRoot(ctx context.Context, user User, query_arg string) ([]*User, error) { users, err := models.Users.Query( sm.Where( psql.Or( @@ -137,13 +137,14 @@ func userSuggestionNonRoot(ctx context.Context, user User, query_arg string) ([] if err != nil { return nil, fmt.Errorf("query users: %w", err) } - results := make([]User, len(users)) + results := make([]*User, len(users)) for i, user := range users { - results[i] = toUser(user) + u := toUser(user) + results[i] = &u } return results, nil } -func userSuggestionRoot(ctx context.Context, user User, query_arg string) ([]User, error) { +func userSuggestionRoot(ctx context.Context, user User, query_arg string) ([]*User, error) { users, err := models.Users.Query( sm.Where( psql.Or( @@ -171,14 +172,14 @@ func userSuggestionRoot(ctx context.Context, user User, query_arg string) ([]Use for _, org := range orgs { org_map[org.ID] = org } - results := make([]User, len(users)) + results := make([]*User, len(users)) for i, user := range users { u := toUser(user) org := org_map[user.OrganizationID] u.Organization = Organization{ model: org, } - results[i] = u + results[i] = &u } return results, nil } diff --git a/ts/store/users.ts b/ts/store/users.ts new file mode 100644 index 00000000..3c4f31ae --- /dev/null +++ b/ts/store/users.ts @@ -0,0 +1,83 @@ +import { defineStore } from "pinia"; +import { ref } from "vue"; +import { User } from "../types"; +import { SSEManager } from "../SSEManager"; +import { useUserStore } from "./user"; + +export const useUsersStore = defineStore("users", () => { + // State + const _byID = ref>(new Map()); + const all = ref(null); + const loading = ref(false); + const error = ref(null); + + // Subscription + SSEManager.subscribe("*", (e) => { + if (e.resource.startsWith("users")) { + fetchAll(); + } + }); + // Actions + function byID(id: int) { + return _byID.value.get(id); + } + async function fetchAll() { + const userStore = useUserStore(); + if (userStore.urls == null) { + throw new Error("can't fetch without user URL data"); + } + + loading.value = true; + error.value = null; + try { + const params = new URLSearchParams(); + params.append("sort", "-created"); + //if (typeFilter.value) params.append("type", typeFilter.value); + + const response = await fetch(`${userStore.urls.api.users}?${params}`); + + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + const data = await response.json(); + all.value = data.users; + for (const u of data.users) { + _byID.value.set(u.id, u); + } + } catch (err) { + console.error("Error loading users:", err); + throw err; + } + } + async function fetchOne(id: int) { + const userStore = useUserStore(); + if (userStore.urls == null) { + throw new Error("can't fetch without user URL data"); + } + + loading.value = true; + error.value = null; + try { + const response = await fetch(`${userStore.urls.api.user}/${id}`); + + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + const data = await response.json(); + _byID.value.set(data.id, data); + return data; + } catch (err) { + console.error("Error loading users:", err); + throw err; + } + } + + return { + // State + all, + // Actions + byID, + fetchAll, + fetchOne, + }; +}); diff --git a/ts/view/configuration/User.vue b/ts/view/configuration/User.vue index 7f1718a3..0cdca58c 100644 --- a/ts/view/configuration/User.vue +++ b/ts/view/configuration/User.vue @@ -1,4 +1,4 @@ -