summaryrefslogtreecommitdiff
path: root/Hutch/Views/Repositories/RepositorySettingsViewModel.swift
diff options
context:
space:
mode:
authorChristian Cleberg <[email protected]>2026-04-12 22:16:14 -0500
committerChristian Cleberg <[email protected]>2026-04-12 22:16:14 -0500
commit7a875798fea9321bad2636040d9be2c30bc0fa8f (patch)
treeb0569f6413454f423c4ddaa6b25307bc987ef81d /Hutch/Views/Repositories/RepositorySettingsViewModel.swift
parent86bcd9452d3107f68aca085e03e69b02667c0dbb (diff)
downloadhutch-7a875798fea9321bad2636040d9be2c30bc0fa8f.tar.gz
hutch-7a875798fea9321bad2636040d9be2c30bc0fa8f.tar.bz2
hutch-7a875798fea9321bad2636040d9be2c30bc0fa8f.zip
feat: add repository acl management
Implements: https://todo.sr.ht/~ccleberg/hutch/39 Implements: https://todo.sr.ht/~ccleberg/hutch/40 Implements: https://todo.sr.ht/~ccleberg/hutch/41
Diffstat (limited to 'Hutch/Views/Repositories/RepositorySettingsViewModel.swift')
-rw-r--r--Hutch/Views/Repositories/RepositorySettingsViewModel.swift157
1 files changed, 0 insertions, 157 deletions
diff --git a/Hutch/Views/Repositories/RepositorySettingsViewModel.swift b/Hutch/Views/Repositories/RepositorySettingsViewModel.swift
index 571ae85..30fe040 100644
--- a/Hutch/Views/Repositories/RepositorySettingsViewModel.swift
+++ b/Hutch/Views/Repositories/RepositorySettingsViewModel.swift
@@ -22,31 +22,6 @@ private struct UpdatedRepoInfo: Decodable, Sendable {
let id: Int
}
-private struct ACLResponse: Decodable, Sendable {
- let repository: ACLRepository?
-}
-
-private struct ACLRepository: Decodable, Sendable {
- let acls: ACLPage
-}
-
-private struct ACLPage: Decodable, Sendable {
- let results: [ACLEntry]
- let cursor: String?
-}
-
-private struct UpdateACLResponse: Decodable, Sendable {
- let updateACL: ACLEntry
-}
-
-private struct DeleteACLResponse: Decodable, Sendable {
- let deleteACL: DeletedACL
-}
-
-private struct DeletedACL: Decodable, Sendable {
- let id: Int
-}
-
private struct DeleteRepoResponse: Decodable, Sendable {
let deleteRepository: DeletedRepo
}
@@ -55,14 +30,6 @@ private struct DeletedRepo: Decodable, Sendable {
let id: Int
}
-// MARK: - ACL Model
-
-struct ACLEntry: Decodable, Sendable, Identifiable {
- let id: Int
- let mode: String
- let entity: Entity
-}
-
// MARK: - View Model
@Observable
@@ -87,15 +54,6 @@ final class RepositorySettingsViewModel {
var editedName: String
var isRenaming = false
- // MARK: - ACL state
-
- private(set) var acls: [ACLEntry] = []
- private(set) var isLoadingACLs = false
- var newACLEntity = ""
- var newACLMode = "RO"
- var isAddingACL = false
- var isDeletingACL = false
-
// MARK: - Delete state
var isDeleting = false
@@ -202,103 +160,6 @@ final class RepositorySettingsViewModel {
}
}
- // MARK: - ACLs
-
- private static let aclsQuery = """
- query acls($rid: ID!) {
- repository(rid: $rid) {
- acls {
- results {
- id
- mode
- entity { canonicalName }
- }
- cursor
- }
- }
- }
- """
-
- private static let updateACLMutation = """
- mutation updateACL($repoId: Int!, $mode: AccessMode!, $entity: String!) {
- updateACL(repoId: $repoId, mode: $mode, entity: $entity) {
- id mode entity { canonicalName }
- }
- }
- """
-
- private static let deleteACLMutation = """
- mutation deleteACL($id: Int!) {
- deleteACL(id: $id) { id }
- }
- """
-
- private static let userLookupQuery = """
- query userLookup($username: String!) {
- user(username: $username) {
- id
- username
- canonicalName
- }
- }
- """
-
- func loadACLs() async {
- guard !isLoadingACLs else { return }
- isLoadingACLs = true
- defer { isLoadingACLs = false }
-
- do {
- let result = try await client.execute(
- service: service,
- query: Self.aclsQuery,
- variables: ["rid": repositoryRid],
- responseType: ACLResponse.self
- )
- acls = result.repository?.acls.results ?? []
- } catch {
- self.error = error.userFacingMessage
- }
- }
-
- func addACL() async {
- let rawEntity = newACLEntity.trimmingCharacters(in: .whitespacesAndNewlines)
- guard !rawEntity.isEmpty else { return }
- let entity = Self.gitCanonicalEntity(from: rawEntity)
- isAddingACL = true
- defer { isAddingACL = false }
- error = nil
-
- do {
- let result = try await client.execute(
- service: service,
- query: Self.updateACLMutation,
- variables: [
- "repoId": repositoryId,
- "mode": newACLMode,
- "entity": entity
- ],
- responseType: UpdateACLResponse.self
- )
- // Replace existing entry or append
- if let index = acls.firstIndex(where: { $0.id == result.updateACL.id }) {
- acls[index] = result.updateACL
- } else {
- acls.append(result.updateACL)
- }
- newACLEntity = ""
- } catch {
- self.error = error.userFacingMessage
- }
- }
-
- static func gitCanonicalEntity(from input: String) -> String {
- let trimmed = input.trimmingCharacters(in: .whitespacesAndNewlines)
- guard !trimmed.isEmpty else { return trimmed }
- let username = trimmed.hasPrefix("~") ? String(trimmed.dropFirst()) : trimmed
- return "~\(username)"
- }
-
static func gitHeadReference(from input: String) -> String {
let trimmed = input.trimmingCharacters(in: .whitespacesAndNewlines)
guard !trimmed.isEmpty else { return trimmed }
@@ -319,24 +180,6 @@ final class RepositorySettingsViewModel {
}?.name
}
- func deleteACL(_ entry: ACLEntry) async {
- isDeletingACL = true
- defer { isDeletingACL = false }
- error = nil
-
- do {
- _ = try await client.execute(
- service: service,
- query: Self.deleteACLMutation,
- variables: ["id": entry.id],
- responseType: DeleteACLResponse.self
- )
- acls.removeAll { $0.id == entry.id }
- } catch {
- self.error = error.userFacingMessage
- }
- }
-
// MARK: - Delete Repository
private static let deleteRepoMutation = """