|
| 1 | +package appstructure |
| 2 | + |
| 3 | +import ( |
| 4 | + "encoding/json" |
| 5 | + "github.com/qlik-oss/gopherciser/enummap" |
| 6 | +) |
| 7 | + |
| 8 | +type ( |
| 9 | + |
| 10 | + // MetaDef meta information for Library objects such as dimension and measure |
| 11 | + MetaDef struct { |
| 12 | + // Title of library item |
| 13 | + Title string `json:"title,omitempty"` |
| 14 | + // Description of library item |
| 15 | + Description string `json:"description,omitempty"` |
| 16 | + // Tags of of library item |
| 17 | + Tags []string `json:"tags,omitempty"` |
| 18 | + } |
| 19 | + |
| 20 | + // AppObjectDef title and ID of a Sense object |
| 21 | + AppObjectDef struct { |
| 22 | + // Id of object |
| 23 | + Id string `json:"id"` |
| 24 | + // Type of Sense object |
| 25 | + Type string `json:"type"` |
| 26 | + } |
| 27 | + |
| 28 | + AppStructureMeasureMeta struct { |
| 29 | + // Meta information, only included for library items |
| 30 | + Meta *MetaDef `json:"meta,omitempty"` |
| 31 | + // LibraryId connects measure to separately defined measure |
| 32 | + LibraryId string `json:"libraryId,omitempty"` |
| 33 | + // Label of on measure |
| 34 | + Label string `json:"label,omitempty"` |
| 35 | + // Def the actual measure definition |
| 36 | + Def string `json:"def,omitempty"` |
| 37 | + } |
| 38 | + |
| 39 | + AppStructureDimensionMeta struct { |
| 40 | + // Meta information, only included for library items |
| 41 | + Meta *MetaDef `json:"meta,omitempty"` |
| 42 | + // LibraryId connects dimension to separately defined dimension |
| 43 | + LibraryId string `json:"libraryId,omitempty"` |
| 44 | + // LabelExpression optional parameter with label expression |
| 45 | + LabelExpression string `json:"labelExpression,omitempty"` |
| 46 | + // Defs definitions of dimension |
| 47 | + Defs []string `json:"defs,omitempty"` |
| 48 | + // Labels of dimension |
| 49 | + Labels []string `json:"labels,omitempty"` |
| 50 | + } |
| 51 | + |
| 52 | + // AppStructureObject sense object structure |
| 53 | + AppStructureObject struct { |
| 54 | + AppObjectDef |
| 55 | + MetaDef |
| 56 | + // RawBaseProperties of Sense object |
| 57 | + RawBaseProperties json.RawMessage `json:"rawBaseProperties,omitempty"` |
| 58 | + // RawExtendedProperties of extended Sense object |
| 59 | + RawExtendedProperties json.RawMessage `json:"rawExtendedProperties,omitempty"` |
| 60 | + // RawGeneratedProperties inner generated properties of auto-chart |
| 61 | + RawGeneratedProperties json.RawMessage `json:"rawGeneratedProperties,omitempty"` |
| 62 | + // Children to the sense object |
| 63 | + Children map[string]string `json:"children,omitempty"` |
| 64 | + // Selectable true if select can be done in object |
| 65 | + Selectable bool `json:"selectable"` |
| 66 | + // Dimensions meta information of dimensions defined in object |
| 67 | + Dimensions []AppStructureDimensionMeta `json:"dimensions,omitempty"` |
| 68 | + // Measures meta information of measures defined in object |
| 69 | + Measures []AppStructureMeasureMeta `json:"measures,omitempty"` |
| 70 | + // ExtendsId ID of linked object |
| 71 | + ExtendsId string `json:"extendsId,omitempty"` |
| 72 | + // Visualization visualization of object, if exists |
| 73 | + Visualization string `json:"visualization,omitempty"` |
| 74 | + } |
| 75 | + |
| 76 | + // AppStructureAppMeta meta information about the app |
| 77 | + AppStructureAppMeta struct { |
| 78 | + // Title of the app |
| 79 | + Title string `json:"title"` |
| 80 | + // Guid of the app |
| 81 | + Guid string `json:"guid"` |
| 82 | + } |
| 83 | + |
| 84 | + // AppStructureBookmark list of bookmarks in the app |
| 85 | + AppStructureBookmark struct { |
| 86 | + // ID of bookmark |
| 87 | + ID string `json:"id"` |
| 88 | + // Title of bookmark |
| 89 | + Title string `json:"title"` |
| 90 | + // Description of bookmark |
| 91 | + Description string `json:"description"` |
| 92 | + // SheetId connected sheet ID, null if none |
| 93 | + SheetId *string `json:"sheetId,omitempty"` |
| 94 | + // SelectionFields fields bookmark would select in |
| 95 | + SelectionFields string `json:"selectionFields"` |
| 96 | + // RawProperties of Bookmark object |
| 97 | + RawProperties json.RawMessage `json:"rawProperties,omitempty"` |
| 98 | + } |
| 99 | + |
| 100 | + // AppStructure of Sense app |
| 101 | + AppStructure struct { |
| 102 | + AppMeta AppStructureAppMeta `json:"meta"` |
| 103 | + // Objects in Sense app |
| 104 | + Objects map[string]AppStructureObject `json:"objects"` |
| 105 | + // Bookmark list of bookmarks in the app |
| 106 | + Bookmarks map[string]AppStructureBookmark `json:"bookmarks"` |
| 107 | + } |
| 108 | + |
| 109 | + // AppStructurePopulatedObjects is the type returned by an action when prompted for selectable objects |
| 110 | + AppStructurePopulatedObjects struct { |
| 111 | + // Parent id of the parent object |
| 112 | + Parent string |
| 113 | + // Objects first level app objects returned by the current action |
| 114 | + Objects []AppStructureObject |
| 115 | + // Bookmark bookmarks returned by the current action |
| 116 | + Bookmarks []AppStructureBookmark |
| 117 | + } |
| 118 | + |
| 119 | + ObjectType int |
| 120 | + AppStructureObjectNotFoundError string |
| 121 | + AppStructureNoScenarioActionsError struct{} |
| 122 | +) |
| 123 | + |
| 124 | +const ( |
| 125 | + ObjectTypeDefault ObjectType = iota |
| 126 | + ObjectTypeDimension |
| 127 | + ObjectTypeMeasure |
| 128 | + ObjectTypeBookmark |
| 129 | + ObjectTypeMasterObject |
| 130 | + ObjectTypeAutoChart |
| 131 | + ObjectSheet |
| 132 | + ObjectLoadModel |
| 133 | + ObjectAppprops |
| 134 | +) |
| 135 | + |
| 136 | +var ( |
| 137 | + ObjectTypeEnumMap, _ = enummap.NewEnumMap(map[string]int{ |
| 138 | + "dimension": int(ObjectTypeDimension), |
| 139 | + "measure": int(ObjectTypeMeasure), |
| 140 | + "bookmark": int(ObjectTypeBookmark), |
| 141 | + "masterobject": int(ObjectTypeMasterObject), |
| 142 | + "auto-chart": int(ObjectTypeAutoChart), |
| 143 | + "sheet": int(ObjectSheet), |
| 144 | + "loadmodel": int(ObjectLoadModel), |
| 145 | + "appprops": int(ObjectAppprops), |
| 146 | + }) |
| 147 | +) |
| 148 | + |
| 149 | +// Error object was not found in app structure |
| 150 | +func (err AppStructureObjectNotFoundError) Error() string { |
| 151 | + return string(err) |
| 152 | +} |
| 153 | + |
| 154 | +// Error no applicable actions found in scenario |
| 155 | +func (err AppStructureNoScenarioActionsError) Error() string { |
| 156 | + return "no applicable actions in scenario" |
| 157 | +} |
| 158 | + |
| 159 | +// GetSelectables get selectable objects from app structure |
| 160 | +func (structure *AppStructure) GetSelectables(rooObject string) ([]AppStructureObject, error) { |
| 161 | + rootObj, ok := structure.Objects[rooObject] |
| 162 | + if !ok { |
| 163 | + return nil, AppStructureObjectNotFoundError(rooObject) |
| 164 | + } |
| 165 | + |
| 166 | + return structure.addSelectableChildren(rootObj), nil |
| 167 | +} |
| 168 | + |
| 169 | +func (structure *AppStructure) addSelectableChildren(obj AppStructureObject) []AppStructureObject { |
| 170 | + selectables := make([]AppStructureObject, 0, 1) |
| 171 | + if obj.Selectable { |
| 172 | + selectables = append(selectables, obj) |
| 173 | + } |
| 174 | + |
| 175 | + for id := range obj.Children { |
| 176 | + child, ok := structure.Objects[id] |
| 177 | + if !ok { |
| 178 | + continue |
| 179 | + } |
| 180 | + |
| 181 | + selectableChildren := structure.addSelectableChildren(child) |
| 182 | + selectables = append(selectables, selectableChildren...) |
| 183 | + } |
| 184 | + return selectables |
| 185 | +} |
0 commit comments