Skip to content

Commit 6b3eef6

Browse files
feat: 🎸 jira 2286 sort & filter for SwiftUI project (#606)
* feat: 🎸 jira 2286 sort & filter for SwiftUI project A SwiftUI component for configuration criteria of performing sorting and filter. SortFilterMenu and SortFilterFullCFG are provided. ✅ Closes: 1 * feat: 🎸 jira 2286 sort & filter for SwiftUI project A SwiftUI component for configuration criteria of performing sorting and filter. SortFilterMenu and SortFilterFullCFG are provided. ✅ Closes: 1 * feat: 🎸 jira 2286 sort & filter for SwiftUI project A SwiftUI component for configuration criteria of performing sorting and filter. SortFilterMenu and SortFilterFullCFG are provided. ✅ Closes: 1 * merge changes from upstream * refactor * Support disabled reset button and refactor * renaming * improvement for designer review * improvement for designer review 2 * refactor & review * refactor & review * refactor & review * refactor & review * refactor & review * refactor & review * refactor & review * refactor & review * refactor & review * refactor & review * refactor & review * refactor & review * feat: refactor & review --------- Co-authored-by: dyongxu <[email protected]>
1 parent 088aef8 commit 6b3eef6

File tree

159 files changed

+4088
-160
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

159 files changed

+4088
-160
lines changed

Apps/Examples/Examples.xcodeproj/project.pbxproj

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@
100100
B8D4376F25F980340024EE7D /* ObjectCell_Spec_Jan2018.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8D4376E25F980340024EE7D /* ObjectCell_Spec_Jan2018.swift */; };
101101
B8D4377125F983730024EE7D /* ObjectCell_Rules_Alignment.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8D4377025F983730024EE7D /* ObjectCell_Rules_Alignment.swift */; };
102102
B8D437732609479E0024EE7D /* SingleActionFollowButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8D437722609479E0024EE7D /* SingleActionFollowButton.swift */; };
103+
C1A0FDB32AD893FA0001738E /* SortFilterView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1A0FDB22AD893FA0001738E /* SortFilterView+Extensions.swift */; };
104+
C1C764882A818BEC00BCB0F7 /* SortFilterExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1C764872A818BEC00BCB0F7 /* SortFilterExample.swift */; };
103105
/* End PBXBuildFile section */
104106

105107
/* Begin PBXContainerItemProxy section */
@@ -240,6 +242,8 @@
240242
B8D4376E25F980340024EE7D /* ObjectCell_Spec_Jan2018.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ObjectCell_Spec_Jan2018.swift; sourceTree = "<group>"; };
241243
B8D4377025F983730024EE7D /* ObjectCell_Rules_Alignment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ObjectCell_Rules_Alignment.swift; sourceTree = "<group>"; };
242244
B8D437722609479E0024EE7D /* SingleActionFollowButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SingleActionFollowButton.swift; sourceTree = "<group>"; };
245+
C1A0FDB22AD893FA0001738E /* SortFilterView+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SortFilterView+Extensions.swift"; sourceTree = "<group>"; };
246+
C1C764872A818BEC00BCB0F7 /* SortFilterExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SortFilterExample.swift; sourceTree = "<group>"; };
243247
/* End PBXFileReference section */
244248

245249
/* Begin PBXFrameworksBuildPhase section */
@@ -423,6 +427,7 @@
423427
8A5579C824C1293C0098003A /* FioriSwiftUICore */ = {
424428
isa = PBXGroup;
425429
children = (
430+
C1C764862A818BD600BCB0F7 /* SortFilter */,
426431
B100639129C0623300AF0CA2 /* StepProgressIndicator */,
427432
108E43D3292DAB3E006532F3 /* EmptyStateView */,
428433
B1D41B1E291A2D2E004E64A5 /* Picker */,
@@ -575,6 +580,15 @@
575580
path = ObjectItem;
576581
sourceTree = "<group>";
577582
};
583+
C1C764862A818BD600BCB0F7 /* SortFilter */ = {
584+
isa = PBXGroup;
585+
children = (
586+
C1C764872A818BEC00BCB0F7 /* SortFilterExample.swift */,
587+
C1A0FDB22AD893FA0001738E /* SortFilterView+Extensions.swift */,
588+
);
589+
path = SortFilter;
590+
sourceTree = "<group>";
591+
};
578592
/* End PBXGroup section */
579593

580594
/* Begin PBXNativeTarget section */
@@ -728,6 +742,7 @@
728742
8A557A2424C12F380098003A /* ChartDetailView.swift in Sources */,
729743
8A5579D024C1293C0098003A /* SettingsLine.swift in Sources */,
730744
1FC30412270540FB004BEE00 /* 72-Fonts.swift in Sources */,
745+
C1A0FDB32AD893FA0001738E /* SortFilterView+Extensions.swift in Sources */,
731746
B84D24ED2652F343007F2373 /* HeaderChartExample.swift in Sources */,
732747
B100639329C0624D00AF0CA2 /* StepProgressIndicatorExample.swift in Sources */,
733748
B846F94626815CC90085044B /* ContactItemExample.swift in Sources */,
@@ -777,6 +792,7 @@
777792
8A5579D524C1293C0098003A /* SettingsSeries.swift in Sources */,
778793
8A557A2224C12C9B0098003A /* CoreContentView.swift in Sources */,
779794
8A5579D224C1293C0098003A /* Color+Extensions.swift in Sources */,
795+
C1C764882A818BEC00BCB0F7 /* SortFilterExample.swift in Sources */,
780796
B84D24EF2652F343007F2373 /* ObjectHeaderTestApp.swift in Sources */,
781797
B84D24EC2652F343007F2373 /* ObjectHeaderSpecCompact.swift in Sources */,
782798
8A5579CD24C1293C0098003A /* SettingsLabel.swift in Sources */,
@@ -920,7 +936,7 @@
920936
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
921937
GCC_WARN_UNUSED_FUNCTION = YES;
922938
GCC_WARN_UNUSED_VARIABLE = YES;
923-
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
939+
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
924940
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
925941
MTL_FAST_MATH = YES;
926942
ONLY_ACTIVE_ARCH = YES;
@@ -975,7 +991,7 @@
975991
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
976992
GCC_WARN_UNUSED_FUNCTION = YES;
977993
GCC_WARN_UNUSED_VARIABLE = YES;
978-
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
994+
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
979995
MTL_ENABLE_DEBUG_INFO = NO;
980996
MTL_FAST_MATH = YES;
981997
SDKROOT = iphoneos;
@@ -995,7 +1011,7 @@
9951011
DEVELOPMENT_TEAM = "";
9961012
ENABLE_PREVIEWS = YES;
9971013
INFOPLIST_FILE = Examples/Info.plist;
998-
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
1014+
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
9991015
LD_RUNPATH_SEARCH_PATHS = (
10001016
"$(inherited)",
10011017
"@executable_path/Frameworks",
@@ -1017,7 +1033,7 @@
10171033
DEVELOPMENT_TEAM = "";
10181034
ENABLE_PREVIEWS = YES;
10191035
INFOPLIST_FILE = Examples/Info.plist;
1020-
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
1036+
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
10211037
LD_RUNPATH_SEARCH_PATHS = (
10221038
"$(inherited)",
10231039
"@executable_path/Frameworks",

Apps/Examples/Examples/FioriSwiftUICore/CoreContentView.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,10 @@ struct CoreContentView: View {
107107
destination: EmptyStateViewExample()) {
108108
Text("EmptyStateViewExample")
109109
}
110+
111+
NavigationLink(destination: SortFilterExample()) {
112+
Text("SortFilterExample")
113+
}
110114
}
111115
}.navigationBarTitle("FioriSwiftUICore")
112116
}
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
import FioriSwiftUICore
2+
import SwiftUI
3+
4+
struct SortFilterExample: View {
5+
@State private var items: [[SortFilterItem]] = [
6+
[
7+
.switch(item: .init(name: "Favorite", value: true, icon: "heart.fill"), showsOnFilterFeedbackBar: true),
8+
.switch(item: .init(name: "Tagged", value: nil, icon: "tag"), showsOnFilterFeedbackBar: false),
9+
.picker(item: .init(name: "JIRA Status", value: [0], valueOptions: ["Received", "Started", "Hold", "Transfer", "Completed", "Pending Review", "Accepted", "Rejected"], allowsMultipleSelection: true, allowsEmptySelection: true, icon: "clock"), showsOnFilterFeedbackBar: true)
10+
],
11+
[
12+
.picker(item: .init(name: "Priority", value: [0], valueOptions: ["High", "Medium", "Low"], allowsMultipleSelection: true, allowsEmptySelection: true, icon: "filemenu.and.cursorarrow"), showsOnFilterFeedbackBar: true),
13+
.filterfeedback(item: .init(name: "Sort Order", value: [0], valueOptions: ["Ascending", "Descending"], allowsMultipleSelection: false, allowsEmptySelection: false, icon: "checkmark"))
14+
],
15+
[
16+
.slider(item: .init(name: "User Stories", value: 10, minimumValue: 0, maximumValue: 100, formatter: "%2d Stories", icon: "number"), showsOnFilterFeedbackBar: true),
17+
.slider(item: .init(name: "Number of Tasks", value: nil, minimumValue: 0, maximumValue: 100), showsOnFilterFeedbackBar: true),
18+
.datetime(item: .init(name: "Start Date", value: Date(), formatter: "yyyy-MM-dd HH:mm",icon: "calendar"), showsOnFilterFeedbackBar: true)
19+
],
20+
[
21+
.datetime(item: .init(name: "Completion Date", value: nil), showsOnFilterFeedbackBar: true)
22+
]
23+
]
24+
25+
@State private var isShowingFullCFG: Bool = false
26+
@State private var isCustomStyle: Bool = false
27+
@State private var sortFilterList: [String] = []
28+
@State private var sortFilterButtonLabel: String = "Sort & Filter"
29+
30+
var body: some View {
31+
VStack {
32+
if isCustomStyle {
33+
FilterFeedbackBar(items: $items, onUpdate: performSortAndFilter)
34+
.filterFeedbackBarStyle(font: .subheadline, foregroundColorSelected: .red, strokeColorSelected: .red, cornerRadius: 25)
35+
.optionListPickerStyle(font: .footnote, foregroundColorUnselected: .green, strokeColorSelected: .black)
36+
// .trailingFullConfigurationMenuItem(icon: "command")
37+
// .leadingFullConfigurationMenuItem(icon: "command")
38+
// .leadingFullConfigurationMenuItem(name: "All")
39+
} else {
40+
FilterFeedbackBar(items: $items, onUpdate: performSortAndFilter)
41+
}
42+
43+
List {
44+
ForEach(sortFilterList, id: \.self) { line in
45+
Text(line)
46+
}
47+
}
48+
.listStyle(PlainListStyle())
49+
50+
HStack {
51+
Toggle("Custom Style", isOn: $isCustomStyle)
52+
.fixedSize()
53+
.toggleStyle(FioriToggleStyle())
54+
55+
Button("Print") {
56+
for line in sortFilterList {
57+
print(line)
58+
}
59+
}
60+
}
61+
}
62+
.navigationTitle("Sort & Filter")
63+
.toolbar {
64+
Button(sortFilterButtonLabel) {
65+
isShowingFullCFG.toggle()
66+
}
67+
.popover(isPresented: $isShowingFullCFG, arrowEdge: .leading) {
68+
if isCustomStyle {
69+
SortFilterView(
70+
title: "Configuration",
71+
items: $items,
72+
onUpdate: performSortAndFilter
73+
)
74+
.optionListPickerStyle(font: .footnote, foregroundColorUnselected: .green, strokeColorSelected: .black)
75+
} else {
76+
SortFilterView(
77+
title: "Configuration",
78+
items: $items,
79+
onUpdate: performSortAndFilter
80+
)
81+
}
82+
}
83+
}
84+
.onAppear {
85+
performSortAndFilter()
86+
}
87+
}
88+
89+
func numberOfItems() -> Int {
90+
// randomly padding result to mimic impact of filterring
91+
for i in 0 ... Int.random(in: 0 ... 5) {
92+
self.sortFilterList.append("padding element \(i + 1)")
93+
}
94+
return self.sortFilterList.count
95+
}
96+
97+
func performSortAndFilter() {
98+
self.sortFilterList = self.items.joined().map { value(of: $0) }
99+
self.sortFilterButtonLabel = "CFG (\(self.numberOfItems()))"
100+
}
101+
}
102+
103+
#if DEBUG
104+
@available(iOS 16.0, *)
105+
struct SortFilterExample_Previews: PreviewProvider {
106+
static var previews: some View {
107+
SortFilterExample()
108+
}
109+
}
110+
#endif
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import FioriSwiftUICore
2+
import SwiftUI
3+
4+
extension View {
5+
func value(of item: SortFilterItem) -> String {
6+
switch item {
7+
case .picker(let v, _):
8+
return self.json(item: v)
9+
case .filterfeedback(let v):
10+
return self.json(item: v)
11+
case .slider(let v, _):
12+
return self.json(item: v)
13+
case .datetime(let v, _):
14+
return self.json(item: v)
15+
case .switch(let v, _):
16+
return self.json(item: v)
17+
}
18+
}
19+
20+
func json(item: SortFilterItem.PickerItem) -> String {
21+
"{name: \(item.name), value: \(item.value)}"
22+
}
23+
24+
func json(item: SortFilterItem.SliderItem) -> String {
25+
"{name: \(item.name), value: \(String(describing: item.value))}"
26+
}
27+
28+
func json(item: SortFilterItem.DateTimeItem) -> String {
29+
"{name: \(item.name), value: \(String(describing: item.value))}"
30+
}
31+
32+
func json(item: SortFilterItem.SwitchItem) -> String {
33+
"{name: \(item.name), value: \(String(describing: item.value))}"
34+
}
35+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"images" : [
3+
{
4+
"filename" : "icon.png",
5+
"idiom" : "universal",
6+
"scale" : "1x"
7+
},
8+
{
9+
"idiom" : "universal",
10+
"scale" : "2x"
11+
},
12+
{
13+
"idiom" : "universal",
14+
"scale" : "3x"
15+
}
16+
],
17+
"info" : {
18+
"author" : "xcode",
19+
"version" : 1
20+
}
21+
}
Loading

Package.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import PackageDescription
66
let package = Package(
77
name: "FioriSwiftUI",
88
defaultLocalization: "en",
9-
platforms: [.iOS(.v15), .watchOS(.v7)],
9+
platforms: [.iOS(.v16), .watchOS(.v7)],
1010
products: [
1111
.library(
1212
name: "FioriSwiftUI",

0 commit comments

Comments
 (0)