Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New full-page edit option for Records #295

Merged
merged 6 commits into from
Oct 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions KlockWork.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@
536040A82CB9F5970030D72D /* AssessmentFactor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 536040A72CB9F5930030D72D /* AssessmentFactor.swift */; };
536040AA2CB9F5F10030D72D /* ActionType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 536040A92CB9F5F10030D72D /* ActionType.swift */; };
536040AC2CB9FC850030D72D /* FactorProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 536040AB2CB9FC850030D72D /* FactorProxy.swift */; };
5360429D2CBA35050030D72D /* RecordDetail.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5360429C2CBA35020030D72D /* RecordDetail.swift */; };
5363B6782A6BB2CC00C2FBB8 /* CompanyDashboard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5363B6772A6BB2CC00C2FBB8 /* CompanyDashboard.swift */; };
5363B67A2A6BB75F00C2FBB8 /* CompanyBlock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5363B6792A6BB75F00C2FBB8 /* CompanyBlock.swift */; };
5363B67C2A6BB78900C2FBB8 /* CompanyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5363B67B2A6BB78900C2FBB8 /* CompanyView.swift */; };
Expand Down Expand Up @@ -404,6 +405,7 @@
536040A72CB9F5930030D72D /* AssessmentFactor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssessmentFactor.swift; sourceTree = "<group>"; };
536040A92CB9F5F10030D72D /* ActionType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionType.swift; sourceTree = "<group>"; };
536040AB2CB9FC850030D72D /* FactorProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FactorProxy.swift; sourceTree = "<group>"; };
5360429C2CBA35020030D72D /* RecordDetail.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordDetail.swift; sourceTree = "<group>"; };
5363B6772A6BB2CC00C2FBB8 /* CompanyDashboard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompanyDashboard.swift; sourceTree = "<group>"; };
5363B6792A6BB75F00C2FBB8 /* CompanyBlock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompanyBlock.swift; sourceTree = "<group>"; };
5363B67B2A6BB78900C2FBB8 /* CompanyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompanyView.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -669,6 +671,7 @@
53152CDF296BC74900A14E43 /* Today */ = {
isa = PBXGroup;
children = (
5360429C2CBA35020030D72D /* RecordDetail.swift */,
53BDA6932B41BBE400A61BE8 /* Calendar */,
5371BA352A7B410D00DEEC21 /* Sidebars */,
53EFCE7729637EA0004E45EC /* LogTable */,
Expand Down Expand Up @@ -1807,6 +1810,7 @@
53B0BE8E29731D41007CB663 /* FancyTextLink.swift in Sources */,
53152CD4296A296A00A14E43 /* FancyButton.swift in Sources */,
5354C8E62AA03C40001C1779 /* Planning.Group.swift in Sources */,
5360429D2CBA35050030D72D /* RecordDetail.swift in Sources */,
5371BA372A7B412300DEEC21 /* TodaySidebar.swift in Sources */,
53842B2A2B4C9B100029AC73 /* FancyToggle.swift in Sources */,
5363B6782A6BB2CC00C2FBB8 /* CompanyDashboard.swift in Sources */,
Expand Down
8 changes: 6 additions & 2 deletions KlockWork/Utils/Navigation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import EventKit
public enum Page {
typealias Conf = PageConfiguration.AppPage
case dashboard, today, notes, tasks, projects, projectDetail, jobs, companies, companyDetail, planning,
terms, definitionDetail, taskDetail, noteDetail, people, peopleDetail, explore, activityFlashcards, activityCalendar
terms, definitionDetail, taskDetail, noteDetail, people, peopleDetail, explore, activityFlashcards, activityCalendar, recordDetail

var appPage: Conf {
switch self {
Expand Down Expand Up @@ -58,6 +58,7 @@ public enum Page {
case .explore: return "Explore"
case .activityCalendar: return "Activity Calendar"
case .activityFlashcards: return "Flashcards"
case .recordDetail: return "Record"
}
}

Expand All @@ -69,6 +70,7 @@ public enum Page {
case .noteDetail: return .notes
case .peopleDetail: return .people
case .activityCalendar, .activityFlashcards: return .explore
case .recordDetail: return .today
default: return nil
}
}
Expand Down Expand Up @@ -569,11 +571,13 @@ extension Navigation {
sidebar: AnyView(DashboardSidebar()),
title: "Dashboard"
)


// @TODO: migrate most of the other props within HistoryPage into Page
public let all: [HistoryPage] = [
HistoryPage(page: .dashboard, view: AnyView(Dashboard()), sidebar: AnyView(DashboardSidebar()), title: "Dashboard"),
HistoryPage(page: .planning, view: AnyView(Planning()), sidebar: AnyView(DefaultPlanningSidebar()), title: "Planning"),
HistoryPage(page: .today, view: AnyView(Today()), sidebar: AnyView(TodaySidebar()), title: "Today", navButtons: [.CLIFilter, .CLIMode, .resetUserChoices]),
HistoryPage(page: .recordDetail, view: AnyView(RecordDetail()), sidebar: AnyView(TodaySidebar()), title: "Record"),
HistoryPage(page: .companies, view: AnyView(CompanyDashboard()), sidebar: AnyView(DefaultCompanySidebar()), title: "Companies & Projects", navButtons: [.createCompany, .createProject]),
HistoryPage(page: .companyDetail, view: AnyView(CompanyView()), sidebar: AnyView(DefaultCompanySidebar()), title: "Company"),
HistoryPage(page: .jobs, view: AnyView(JobDashboardRedux()), sidebar: AnyView(JobDashboardSidebar()), title: "Jobs", navButtons: [.resetUserChoices, .createJob]),
Expand Down
12 changes: 11 additions & 1 deletion KlockWork/Views/Entities/Today/LogTable/RowTypes/LogRow.swift
Original file line number Diff line number Diff line change
Expand Up @@ -160,9 +160,10 @@ struct LogRow: View, Identifiable {

@ViewBuilder private var contextMenu: some View {
if entry.jobObject != nil {
Button("Edit record") {
Button("Quick edit") {
isEditing = true
}
.disabled(entry.jobObject?.jid ?? 0 == 0)

if let uri = entry.jobObject!.uri {
if uri.absoluteString != "" && uri.absoluteString != "https://" {
Expand Down Expand Up @@ -197,6 +198,15 @@ struct LogRow: View, Identifiable {
}

Menu("Go to"){
Button {
self.nav.session.job = entry.jobObject
self.nav.session.record = self.record
self.nav.to(.recordDetail)
} label: {
Text(PageConfiguration.EntityType.records.enSingular)
}
.disabled(entry.jobObject?.jid ?? 0 == 0)

Button {
self.nav.session.job = entry.jobObject
self.nav.to(.tasks)
Expand Down
135 changes: 135 additions & 0 deletions KlockWork/Views/Entities/Today/RecordDetail.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
//
// RecordDetail.swift
// KlockWork
//
// Created by Ryan Priebe on 2024-10-11.
// Copyright © 2024 YegCollective. All rights reserved.
//

import SwiftUI
import KWCore

struct RecordDetail: View {
@EnvironmentObject public var state: Navigation
@Environment(\.dismiss) private var dismiss
@State public var record: LogRecord?
private let page: PageConfiguration.AppPage = .explore
private let eType: PageConfiguration.EntityType = .records
@State private var message: String = ""
@State private var alive: Bool = true
@State private var job: Job?
@State private var isDeleteAlertPresented: Bool = false

var body: some View {
VStack(alignment: .leading, spacing: 0) {
HStack(alignment: .center, spacing: 8) {
Title(text: self.eType.enSingular, imageAsImage: self.eType.icon)
Spacer()

if self.record != nil {
FancyButtonv2(
text: "Delete",
action: {isDeleteAlertPresented = true},
icon: "trash",
showLabel: false,
type: .destructive
)
.alert("Are you sure you want to delete this record?", isPresented: $isDeleteAlertPresented) {
Button("Yes", role: .destructive) {
self.actionOnSoftDelete()
}
Button("No", role: .cancel) {}
}
.disabled(self.state.session.job == nil)
.opacity(self.state.session.job == nil ? 0.5 : 1)
}

FancyButtonv2(text: "Cancel", action: self.actionOnCancel, showIcon: false)
.disabled(self.state.session.job == nil)
.opacity(self.state.session.job == nil ? 0.5 : 1)
FancyButtonv2(text: "Save", action: self.actionOnSave, showIcon: false, type: .primary)
.disabled(self.state.session.job == nil)
.opacity(self.state.session.job == nil ? 0.5 : 1)
}
.padding(.bottom)

VStack(alignment: .leading, spacing: 0) {
Toggle("Published", isOn: $alive)

FancyTextField(
placeholder: "Message",
lineLimit: 11,
onSubmit: self.actionOnSave,
text: $message
)
.disabled(self.state.session.job == nil)
.opacity(self.state.session.job == nil ? 0.5 : 1)

if self.state.session.job == nil {
FancyHelpText(
text: "Select a job from the sidebar to get started.",
page: self.page
)
}
}
Spacer()
}
.padding()
.background(self.page.primaryColour)
.onAppear(perform: self.actionOnAppear)
.onChange(of: self.state.session.record) { self.actionOnAppear() }
.onChange(of: self.state.session.job) { self.job = self.state.session.job }
}
}

extension RecordDetail {
/// Onload handler
/// - Returns: Void
private func actionOnAppear() -> Void {
if let stored = self.state.session.record {
self.record = stored
self.state.session.record = nil
}

self.message = self.record?.message ?? ""
self.alive = self.record?.alive ?? false
self.job = self.record?.job
}

/// Callback that fires when cancel button clicked/tapped
/// - Returns: Void
private func actionOnCancel() -> Void {
self.state.to(.today)
self.dismiss()
}

/// Callback that fires when save button clicked/tapped
/// - Returns: Void
private func actionOnSave() -> Void {
if self.record != nil {
self.record?.message = self.message
self.record?.alive = self.alive
self.record?.job = self.state.session.job
} else {
if let job = self.job {
CoreDataRecords(moc: self.state.moc).createWithJob(
job: job,
date: self.state.session.date,
text: self.message
)
}
}

PersistenceController.shared.save()
self.state.to(.today)
}

/// Fires when user chooses to unpublish a definition
/// - Returns: Void
private func actionOnSoftDelete() -> Void {
self.alive = false
self.record?.alive = false
PersistenceController.shared.save()
self.state.to(.today)
}
}