handles hyperlink columns and fields (#4971)
Hyperlink column of a list item is not identifiable from GRAPH's response. Hence this is a workaround to handle such fields until a column definition is introduced for `Hyperlink`. #### Does this PR need a docs update or release note? - [x] ⛔ No #### Type of change <!--- Please check the type of change your PR introduces: ---> - [x] 🌻 Feature #### Issue(s) #4754 #### Test Plan <!-- How will this be tested prior to merging.--> - [x] 💪 Manual - [x] ⚡ Unit test - [x] 💚 E2E
This commit is contained in:
parent
06afd53660
commit
8989fcd7cd
@ -1,5 +1,9 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"github.com/alcionai/corso/src/internal/common/keys"
|
||||
)
|
||||
|
||||
// Well knwon Folder Names
|
||||
// Mail Definitions: https://docs.microsoft.com/en-us/graph/api/resources/mailfolder?view=graph-rest-1.0
|
||||
const (
|
||||
@ -11,3 +15,82 @@ const (
|
||||
// Kiota JSON invalid JSON error message.
|
||||
invalidJSON = "invalid json type"
|
||||
)
|
||||
|
||||
// ************** Lists starts *****************
|
||||
|
||||
const (
|
||||
AttachmentsColumnName = "Attachments"
|
||||
EditColumnName = "Edit"
|
||||
ContentTypeColumnName = "ContentType"
|
||||
CreatedColumnName = "Created"
|
||||
ModifiedColumnName = "Modified"
|
||||
AuthorLookupIDColumnName = "AuthorLookupId"
|
||||
EditorLookupIDColumnName = "EditorLookupId"
|
||||
AppAuthorLookupIDColumnName = "AppAuthorLookupId"
|
||||
TitleColumnName = "Title"
|
||||
|
||||
ContentTypeColumnDisplayName = "Content Type"
|
||||
|
||||
AddressKey = "address"
|
||||
CoordinatesKey = "coordinates"
|
||||
DisplayNameKey = "displayName"
|
||||
LocationURIKey = "locationUri"
|
||||
UniqueIDKey = "uniqueId"
|
||||
|
||||
// entries that are nested within a second layer
|
||||
CityKey = "city"
|
||||
CountryKey = "countryOrRegion"
|
||||
PostalCodeKey = "postalCode"
|
||||
StateKey = "state"
|
||||
StreetKey = "street"
|
||||
LatitudeKey = "latitude"
|
||||
LongitudeKey = "longitude"
|
||||
|
||||
CountryOrRegionFN = "CountryOrRegion"
|
||||
StateFN = "State"
|
||||
CityFN = "City"
|
||||
PostalCodeFN = "PostalCode"
|
||||
StreetFN = "Street"
|
||||
GeoLocFN = "GeoLoc"
|
||||
DispNameFN = "DispName"
|
||||
|
||||
HyperlinkDescriptionKey = "Description"
|
||||
HyperlinkURLKey = "Url"
|
||||
|
||||
LinkTitleFieldNamePart = "LinkTitle"
|
||||
ChildCountFieldNamePart = "ChildCount"
|
||||
LookupIDFieldNamePart = "LookupId"
|
||||
|
||||
ReadOnlyOrHiddenFieldNamePrefix = "_"
|
||||
DescoratorFieldNamePrefix = "@"
|
||||
|
||||
WebTemplateExtensionsListTemplate = "webTemplateExtensionsList"
|
||||
// This issue https://github.com/alcionai/corso/issues/4932
|
||||
// tracks to backup/restore supportability of `documentLibrary` templated lists
|
||||
DocumentLibraryListTemplate = "documentLibrary"
|
||||
SharingLinksListTemplate = "sharingLinks"
|
||||
AccessRequestsListTemplate = "accessRequest"
|
||||
)
|
||||
|
||||
var addressFieldNames = []string{
|
||||
AddressKey,
|
||||
CoordinatesKey,
|
||||
DisplayNameKey,
|
||||
LocationURIKey,
|
||||
UniqueIDKey,
|
||||
}
|
||||
|
||||
var legacyColumns = keys.Set{
|
||||
AttachmentsColumnName: {},
|
||||
EditColumnName: {},
|
||||
ContentTypeColumnDisplayName: {},
|
||||
}
|
||||
|
||||
var SkipListTemplates = keys.Set{
|
||||
WebTemplateExtensionsListTemplate: {},
|
||||
DocumentLibraryListTemplate: {},
|
||||
SharingLinksListTemplate: {},
|
||||
AccessRequestsListTemplate: {},
|
||||
}
|
||||
|
||||
// ************** Lists ends *****************
|
||||
|
||||
@ -18,78 +18,6 @@ import (
|
||||
|
||||
var ErrSkippableListTemplate = clues.New("unable to create lists with skippable templates")
|
||||
|
||||
const (
|
||||
AttachmentsColumnName = "Attachments"
|
||||
EditColumnName = "Edit"
|
||||
ContentTypeColumnName = "ContentType"
|
||||
CreatedColumnName = "Created"
|
||||
ModifiedColumnName = "Modified"
|
||||
AuthorLookupIDColumnName = "AuthorLookupId"
|
||||
EditorLookupIDColumnName = "EditorLookupId"
|
||||
AppAuthorLookupIDColumnName = "AppAuthorLookupId"
|
||||
TitleColumnName = "Title"
|
||||
|
||||
ContentTypeColumnDisplayName = "Content Type"
|
||||
|
||||
AddressKey = "address"
|
||||
CoordinatesKey = "coordinates"
|
||||
DisplayNameKey = "displayName"
|
||||
LocationURIKey = "locationUri"
|
||||
UniqueIDKey = "uniqueId"
|
||||
|
||||
// entries that are nested within a second layer
|
||||
CityKey = "city"
|
||||
CountryKey = "countryOrRegion"
|
||||
PostalCodeKey = "postalCode"
|
||||
StateKey = "state"
|
||||
StreetKey = "street"
|
||||
LatitudeKey = "latitude"
|
||||
LongitudeKey = "longitude"
|
||||
|
||||
CountryOrRegionFN = "CountryOrRegion"
|
||||
StateFN = "State"
|
||||
CityFN = "City"
|
||||
PostalCodeFN = "PostalCode"
|
||||
StreetFN = "Street"
|
||||
GeoLocFN = "GeoLoc"
|
||||
DispNameFN = "DispName"
|
||||
|
||||
LinkTitleFieldNamePart = "LinkTitle"
|
||||
ChildCountFieldNamePart = "ChildCount"
|
||||
LookupIDFieldNamePart = "LookupId"
|
||||
|
||||
ReadOnlyOrHiddenFieldNamePrefix = "_"
|
||||
DescoratorFieldNamePrefix = "@"
|
||||
|
||||
WebTemplateExtensionsListTemplate = "webTemplateExtensionsList"
|
||||
// This issue https://github.com/alcionai/corso/issues/4932
|
||||
// tracks to backup/restore supportability of `documentLibrary` templated lists
|
||||
DocumentLibraryListTemplate = "documentLibrary"
|
||||
SharingLinksListTemplate = "sharingLinks"
|
||||
AccessRequestsListTemplate = "accessRequest"
|
||||
)
|
||||
|
||||
var addressFieldNames = []string{
|
||||
AddressKey,
|
||||
CoordinatesKey,
|
||||
DisplayNameKey,
|
||||
LocationURIKey,
|
||||
UniqueIDKey,
|
||||
}
|
||||
|
||||
var legacyColumns = keys.Set{
|
||||
AttachmentsColumnName: {},
|
||||
EditColumnName: {},
|
||||
ContentTypeColumnDisplayName: {},
|
||||
}
|
||||
|
||||
var SkipListTemplates = keys.Set{
|
||||
WebTemplateExtensionsListTemplate: {},
|
||||
DocumentLibraryListTemplate: {},
|
||||
SharingLinksListTemplate: {},
|
||||
AccessRequestsListTemplate: {},
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// controller
|
||||
// ---------------------------------------------------------------------------
|
||||
@ -507,6 +435,11 @@ func retrieveFieldData(orig models.FieldValueSetable, columnNames map[string]any
|
||||
additionalData[fieldName] = concatenatedAddress
|
||||
}
|
||||
|
||||
if hyperLinkField, fieldName, ok := hasHyperLinkFields(additionalData); ok {
|
||||
concatenatedHyperlink := concatenateHyperLinkFields(hyperLinkField)
|
||||
additionalData[fieldName] = concatenatedHyperlink
|
||||
}
|
||||
|
||||
fields.SetAdditionalData(additionalData)
|
||||
|
||||
return fields
|
||||
@ -547,6 +480,22 @@ func hasAddressFields(additionalData map[string]any) (map[string]any, string, bo
|
||||
return nil, "", false
|
||||
}
|
||||
|
||||
func hasHyperLinkFields(additionalData map[string]any) (map[string]any, string, bool) {
|
||||
for fieldName, value := range additionalData {
|
||||
nestedFields, ok := value.(map[string]any)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
if keys.HasKeys(nestedFields,
|
||||
[]string{HyperlinkDescriptionKey, HyperlinkURLKey}...) {
|
||||
return nestedFields, fieldName, true
|
||||
}
|
||||
}
|
||||
|
||||
return nil, "", false
|
||||
}
|
||||
|
||||
func concatenateAddressFields(addressFields map[string]any) string {
|
||||
parts := make([]string, 0)
|
||||
|
||||
@ -574,6 +523,24 @@ func concatenateAddressFields(addressFields map[string]any) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func concatenateHyperLinkFields(hyperlinkFields map[string]any) string {
|
||||
parts := make([]string, 0)
|
||||
|
||||
if v, err := str.AnyValueToString(HyperlinkURLKey, hyperlinkFields); err == nil {
|
||||
parts = append(parts, v)
|
||||
}
|
||||
|
||||
if v, err := str.AnyValueToString(HyperlinkDescriptionKey, hyperlinkFields); err == nil {
|
||||
parts = append(parts, v)
|
||||
}
|
||||
|
||||
if len(parts) > 0 {
|
||||
return strings.Join(parts, ",")
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func addressKeyToVal(fields map[string]any, key string) string {
|
||||
if v, err := str.AnyValueToString(key, fields); err == nil {
|
||||
return v
|
||||
|
||||
@ -650,6 +650,59 @@ func (suite *ListsUnitSuite) TestHasAddressFields() {
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *ListsUnitSuite) TestConcatenateHyperlinkFields() {
|
||||
t := suite.T()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
hyperlinkFields map[string]any
|
||||
expectedResult string
|
||||
}{
|
||||
{
|
||||
name: "Valid Hyperlink",
|
||||
hyperlinkFields: map[string]any{
|
||||
HyperlinkURLKey: ptr.To("https://www.example.com"),
|
||||
HyperlinkDescriptionKey: ptr.To("Example Website"),
|
||||
},
|
||||
expectedResult: "https://www.example.com,Example Website",
|
||||
},
|
||||
{
|
||||
name: "Empty Hyperlink Fields",
|
||||
hyperlinkFields: map[string]any{
|
||||
HyperlinkURLKey: nil,
|
||||
HyperlinkDescriptionKey: nil,
|
||||
},
|
||||
expectedResult: "",
|
||||
},
|
||||
{
|
||||
name: "Missing Description",
|
||||
hyperlinkFields: map[string]any{
|
||||
HyperlinkURLKey: ptr.To("https://www.example.com"),
|
||||
},
|
||||
expectedResult: "https://www.example.com",
|
||||
},
|
||||
{
|
||||
name: "Missing URL",
|
||||
hyperlinkFields: map[string]any{
|
||||
HyperlinkDescriptionKey: ptr.To("Example Website"),
|
||||
},
|
||||
expectedResult: "Example Website",
|
||||
},
|
||||
{
|
||||
name: "Empty Input",
|
||||
hyperlinkFields: map[string]any{},
|
||||
expectedResult: "",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
suite.Run(test.name, func() {
|
||||
result := concatenateHyperLinkFields(test.hyperlinkFields)
|
||||
assert.Equal(t, test.expectedResult, result)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
type ListsAPIIntgSuite struct {
|
||||
tester.Suite
|
||||
its intgTesterSetup
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user