diff --git a/HISTORY.rst b/HISTORY.rst index d4e0613..3aee9b2 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -5,6 +5,15 @@ Release History --------------- +Release 3.2.9 (2016-03-10) +++++++++++++++++++ +* Enhancement for ``role hierarchy exporting`` +* Add new settings ``include_users_in_role_hierarchy`` to control whether including user in the CSV +* Deliver new feature, see issue #89 +* upgrade build-in requests lib to 2.9.1 +* change display message for list metadata in the output panel + + Release 3.2.8 (2016-02-26) ++++++++++++++++++ * Fix issue #88 diff --git a/config/commands/main.sublime-commands b/config/commands/main.sublime-commands index 3643b0b..a842fe4 100644 --- a/config/commands/main.sublime-commands +++ b/config/commands/main.sublime-commands @@ -496,5 +496,7 @@ "args": { "operation": "delete" } - } + }, + {"caption": "HaoIDE: View Id in Salesforce Web","command": "view_id_in_sfdc_web"}, + {"caption": "HaoIDE: View in Salesforce Web","command": "show_in_sfdc_web"} ] \ No newline at end of file diff --git a/config/menus/Context.sublime-menu b/config/menus/Context.sublime-menu index 7e01320..401b134 100644 --- a/config/menus/Context.sublime-menu +++ b/config/menus/Context.sublime-menu @@ -95,11 +95,11 @@ {"caption": "Preview Page in Server","command": "preview_page"}, {"caption": "-"}, - {"caption": "View File Attributes","command": "view_file_attributes"}, {"caption": "View Code Coverage","command": "view_code_coverage"}, {"caption": "View Debug Log Detail","command": "view_debug_log_detail"}, {"caption": "View Id in Salesforce Web","command": "view_id_in_sfdc_web"}, - {"caption": "Show in Salesforce Web","command": "show_in_sfdc_web"} + {"caption": "View in Salesforce Web","command": "show_in_sfdc_web"}, + {"caption": "View File Attributes","command": "view_file_attributes"} ] } ] \ No newline at end of file diff --git a/config/messages/3.2.9.md b/config/messages/3.2.9.md new file mode 100644 index 0000000..d804f88 --- /dev/null +++ b/config/messages/3.2.9.md @@ -0,0 +1,11 @@ +Build 3.2.9 +----------- +Release Date: 10 Mar 2016 + +* Enhancement for ``role hierarchy exporting`` +* Add new settings ``include_users_in_role_hierarchy`` to control whether including user in the CSV +* Deliver new feature, see issue #89 +* upgrade build-in requests lib to 2.9.1 +* change display message for list metadata in the output panel + +* Restart your sublime when new version is installed \ No newline at end of file diff --git a/config/settings/package.sublime-settings b/config/settings/package.sublime-settings index 3d4f50f..1949d58 100644 --- a/config/settings/package.sublime-settings +++ b/config/settings/package.sublime-settings @@ -1,6 +1,6 @@ { "name": "HaoIDE", - "version": "3.2.8", + "version": "3.2.9", "description": "HaoIDE is a Sublime Text 3 plugin for Salesforce and used for swift development on Force.com", "author": "Hao Liu", "email": "mouse.mliu@gmail.com", diff --git a/main.py b/main.py index c8a3ed1..4c9a04c 100644 --- a/main.py +++ b/main.py @@ -1939,7 +1939,7 @@ class ViewFileAttributes(sublime_plugin.TextCommand): def run(self, edit): view = sublime.active_window().new_file() view.run_command("new_view", { - "name": self.cname, + "name": self.cname + " Attributes", "input": json.dumps(self.component_attribute, indent=4) }) diff --git a/messages.json b/messages.json index e422266..357eeae 100644 --- a/messages.json +++ b/messages.json @@ -8,5 +8,6 @@ "3.2.6": "config/messages/3.2.6.md", "3.2.7": "config/messages/3.2.7.md", "3.2.8": "config/messages/3.2.8.md", + "3.2.9": "config/messages/3.2.9.md", "install": "config/messages/install.txt" } \ No newline at end of file diff --git a/processor.py b/processor.py index dd2d7ef..105ca42 100644 --- a/processor.py +++ b/processor.py @@ -1503,10 +1503,6 @@ def handle_thread(thread, timeout): thread = threading.Thread(target=api.create_trace_flag) thread.start() - # If succeed, keep the lastModifiedDate in the cache - threading.Thread(target=util.set_component_attribute, - args=(component_attribute, result["lastModifiedDate"], )).start() - # If not succeed, just go to the error line # Because error line in page is always at the line 1, so just work in class or trigger elif "success" in result and not result["success"]: diff --git a/salesforce/api/tooling.py b/salesforce/api/tooling.py index f989f4d..24bdbea 100644 --- a/salesforce/api/tooling.py +++ b/salesforce/api/tooling.py @@ -963,22 +963,22 @@ def save_to_server(self, component_attribute, body, is_check_only, check_save_co return result # Why do the three date value has minor difference? - # LastModifiedDate : 2016-03-09T06:52:12.000+0000 - # SystemModstamp : 2016-03-09T06:52:13.000+0000 - # LastModifiedDate in local cache : 2016-03-09T06:52:13.000+0000 - # + # Server LastModifiedDate : 2016-03-09T06:52:12.000+0000 + # Server SystemModstamp : 2016-03-09T06:52:13.000+0000 + # Local LastModifiedDate : 2016-03-09T06:52:13.000+0000 + + # Get Server Date and LastModifiedBy class_attr = result["records"][0] lastModifiedBy = class_attr["LastModifiedBy"] - serverLastModifiedDate = class_attr["SystemModstamp"] - serverLastModifiedDateZone = util.local_datetime(serverLastModifiedDate) + serverDateLiteral = class_attr["LastModifiedDate"] + serverLastModifiedDateZone = util.local_datetime(serverDateLiteral) # Get local lastModifiedDate - localLastModifiedDate = component_attribute["lastModifiedDate"] + localDateLiteral = component_attribute.get("lastModifiedDate", None) - # Check lastModifiedDate - # lastModifiedDate in server : 2016-03-09T06:37:36.000+0000 - # lastModifiedDate in local cache : 2016-03-09T06:37:36.000Z - if serverLastModifiedDate[:19] != localLastModifiedDate[:19]: + # If local date is different with server date, + # it means there has conflict + if serverDateLiteral[:19] != localDateLiteral[:19]: message = "Modified by %s at %s, continue?" % ( lastModifiedBy["Name"], serverLastModifiedDateZone ) @@ -1141,6 +1141,9 @@ def save_to_server(self, component_attribute, body, is_check_only, check_save_co if return_result["success"] and component_type == "ApexClass": sublime.set_timeout_async(self.write_symbol_table_cache(member_result["id"]), 5) + if return_result["success"]: + sublime.set_timeout_async(self.set_component_attribute(component_attribute), 5) + # Whatever succeed or failed, just delete MetadataContainerId sublime.set_timeout_async(self.delete(container_url + "/" + container_id), 100) @@ -1177,4 +1180,44 @@ def write_symbol_table_cache(self, member_id): symboltable_dict[symbol_table["name"].lower()]["inners"] = inners symbol_table_cache.set(self.settings["username"], symboltable_dict) - sublime.save_settings("symbol_table.sublime-settings") \ No newline at end of file + sublime.save_settings("symbol_table.sublime-settings") + + def set_component_attribute(self, attributes): + """ Set the LastModifiedDate for specified component + + Params: + * attributes -- component attributes + """ + # Get the LastModifiedDate by attributes + query = "SELECT LastModifiedDate FROM %s WHERE Id ='%s'" % ( + attributes["type"], + attributes["id"] + ) + component = self.query(query, True) + + # Start to write symbol table to cache + if not component or not component["records"]: return + lastModifiedDate = component["records"][0]["LastModifiedDate"] + + # If sobjects is exist in local cache, just return it + username = self.settings["username"] + s = sublime.load_settings("component_metadata.sublime-settings") + if not s.has(username): + return + + _type = attributes["type"] + fullName = attributes["name"] + attributes["extension"] + components_dict = s.get(username, {}) + + # Prevent exception if no component in org + if _type not in components_dict: + components_dict = {_type : {}} + + # Build components dict + attr = components_dict[_type][fullName.lower()] + attr["lastModifiedDate"] = lastModifiedDate + components_dict[_type][fullName.lower()] = attr + + # Save settings and show success message + s.set(username, components_dict) + sublime.save_settings("component_metadata.sublime-settings") \ No newline at end of file diff --git a/util.py b/util.py index f4a2ea0..f7a3e02 100644 --- a/util.py +++ b/util.py @@ -246,44 +246,6 @@ def populate_lighting_applications(): return aura_attributes -def set_component_attribute(attributes, lastModifiedDate): - """ Set the LastModifiedDate for specified component - - Params: - * attributes -- component attributes, such as - { - "name": "AccountFactory", - "url": "/services/data/v35.0/sobjects/ApexClass/01p90000006QGc6AAG", - "is_test": false, - "id": "01p90000006QGc6AAG", - ... - } - """ - settings = context.get_settings() - username = settings["username"] - - # If sobjects is exist in local cache, just return it - s = sublime.load_settings("component_metadata.sublime-settings") - if not s.has(username): - return - - _type = attributes["type"] - fullName = attributes["name"] + attributes["extension"] - components_dict = s.get(username, {}) - - # Prevent exception if no component in org - if _type not in components_dict: - components_dict = {_type : {}} - - # Build components dict - attr = components_dict[_type][fullName.lower()] - attr["lastModifiedDate"] = lastModifiedDate - components_dict[_type][fullName.lower()] = attr - - # Save settings and show success message - s.set(username, components_dict) - sublime.save_settings("component_metadata.sublime-settings") - def populate_sobjects_describe(): """ Get the sobjects list in org.