diff --git a/documentation/codegenerator/client/autoform.js b/documentation/codegenerator/client/autoform.js new file mode 100644 index 0000000000..ee6af08a1a --- /dev/null +++ b/documentation/codegenerator/client/autoform.js @@ -0,0 +1,54 @@ +import { HTTP } from 'meteor/http'; + +AutoForm.addHooks('downloadSDK', { + onSubmit: function (formValues, updateDoc, instance) { + // Prevent form from submitting + this.event.preventDefault(); + + // Get selected language from dropdown list + const selectedLanguage = formValues.selectLanguage; + + // Get index of selected language in global list of languages + const index = _.indexOf(instance.languageList, selectedLanguage); + + // Find mask of the language for url + const parameter = instance.urlParameters[index]; + + const host = 'https://generator.swagger.io'; + + // Create URL to send request + const url = host + '/api/gen/clients/' + parameter; + + // Get path to documentation file + const pathToFile = instance.documentationFileURL; + + // Create POST options + const options = { + 'swaggerUrl': pathToFile + }; + + // Start spinner when send request + instance.callRequest.set(true); + + // Send POST request + HTTP.post(url, { data: options }, function (error, result) { + // Get information from Swagger API response + let response = JSON.parse(result.content); + + if (result.statusCode === 200) { + // Hide modal + Modal.hide('sdkCodeGeneratorModal'); + + // Go to link and download file + window.location.href = response.link; + } else { + $('button').removeAttr('disabled'); + + // Otherwise show an error message + FlashMessages.sendError(TAPi18n.__('sdkCodeGeneratorModal_errorText')); + } + // Finish spinner + instance.callRequest.set(false); + }); + } +}); diff --git a/documentation/codegenerator/client/codegenerator.html b/documentation/codegenerator/client/codegenerator.html new file mode 100644 index 0000000000..b92092807c --- /dev/null +++ b/documentation/codegenerator/client/codegenerator.html @@ -0,0 +1,34 @@ + \ No newline at end of file diff --git a/documentation/codegenerator/client/codegenerator.js b/documentation/codegenerator/client/codegenerator.js new file mode 100644 index 0000000000..82255ad7da --- /dev/null +++ b/documentation/codegenerator/client/codegenerator.js @@ -0,0 +1,108 @@ +import { Template } from 'meteor/templating'; +import { ReactiveVar } from 'meteor/reactive-var'; +import { HTTP } from 'meteor/http'; + +import _ from 'lodash'; + +import { DocumentationFiles } from '/documentation/collection/collection'; +import { specificLanguageNames } from './codgeneratorSpecificLanguages'; + +Template.sdkCodeGeneratorModal.onCreated(function () { + const instance = this; + + instance.callRequest = new ReactiveVar(false); + instance.dataReady = new ReactiveVar(false); + + // Get documentation file id + const documentationFileId = instance.data.apiBackend.documentationFileId; + + // Save documentation file URL + instance.documentationFileURL = Meteor.absoluteUrl().slice(0, -1) + DocumentationFiles.baseURL + '/id/' + documentationFileId; + + /* Get list of an available languages from Codegen server */ + + // Codegen server url + const url = 'https://generator.swagger.io/api/gen/clients'; + + // Call GET request + HTTP.get(url, {}, function (error, result) { + // Get information from Swagger API response + const response = JSON.parse(result.content); + + // Save response to use it like url parameter in POST request + instance.urlParameters = response; + + // Create list of friendly language names + instance.languageList = []; + + _.forEach(response, function (language) { + // Check on specific name + let newLanguageName = specificLanguageNames[language]; + + // Convert name by standard method if it isn't specific name + if (_.isUndefined(newLanguageName)) { + // Split the name into words, ex. 'akka-scala' -> 'akka','scala' + let newLanguageList = language.split('-'); + // Do the capital letter for each word + newLanguageList = _.map(newLanguageList, function (word) { return _.capitalize(word); }); + // Join this list to string using space + newLanguageName = newLanguageList.join(' '); + } + // Add new name to list of languages which show to user + instance.languageList.push(newLanguageName); + + // Finish spinner + instance.dataReady.set(true); + }); + }); +}); + +Template.sdkCodeGeneratorModal.helpers({ + // Schema for SDK Code Generator form + generateSDK () { + // Get reference to template instance + const instance = Template.instance(); + + // Create simple schema for sdk modal + return new SimpleSchema({ + selectLanguage: { + type: String, + allowedValues: instance.languageList, + autoform: { + afFieldInput: { + firstOption: '(Language)' + } + } + } + }); + }, + // Check on ready of data from call GET request + dataFetched () { + // Get reference to template instance + const instance = Template.instance(); + + return instance.dataReady.get(); + }, + // Give variable callRequest to template + statusRequest () { + // Get reference to template instance + const instance = Template.instance(); + + return instance.callRequest.get(); + }, + // From template AutoForm we don't have access to instance of this template + // getTemplateInstance return object that containts the necessary varaibles + getTemplateInstance () { + // Get reference to template instance + const instance = Template.instance(); + + // Create object with instance varaibles + return { + 'apiBackend': instance.data.apiBackend, + 'callRequest': instance.callRequest, + 'documentationFileURL': instance.documentationFileURL, + 'languageList': instance.languageList, + 'urlParameters': instance.urlParameters + }; + } +}); diff --git a/documentation/codegenerator/client/codgeneratorSpecificLanguages.js b/documentation/codegenerator/client/codgeneratorSpecificLanguages.js new file mode 100644 index 0000000000..7ac1511763 --- /dev/null +++ b/documentation/codegenerator/client/codgeneratorSpecificLanguages.js @@ -0,0 +1,17 @@ +// The most part of list items can convert to user friendly name by standard method +// The method is to replace dash on space and to do the capital letter of each word +// Some language names can't be convert by standard method. +// Variable 'specificLanguageNames' keeps specific names +const specificLanguageNames = { + 'dynamic-html': 'Dynamic HTML', + 'csharp': 'C#', + 'CsharpDotNet2': 'C# .NET 2.0', + 'html': 'HTML', + 'objc': 'Objective-C', + 'php': 'PHP', + 'qt5cpp': 'Qt 5 C++', + 'swagger': 'Swagger JSON', + 'swagger-yaml': 'Swagger YAML' +}; + +export { specificLanguageNames }; diff --git a/documentation/collection/collection.js b/documentation/collection/collection.js index 94b6a3ce9f..31420b66b8 100644 --- a/documentation/collection/collection.js +++ b/documentation/collection/collection.js @@ -5,7 +5,7 @@ const DocumentationFiles = new FileCollection('DocumentationFiles', { { method: 'get', path: '/id/:_id', - lookup: function(params, query) { + lookup: function (params, query) { return { _id: params._id }; @@ -15,3 +15,4 @@ const DocumentationFiles = new FileCollection('DocumentationFiles', { }); export { DocumentationFiles }; + diff --git a/documentation/view/client/documentation.css b/documentation/view/client/documentation.css index 386f9aa862..26e8d667f5 100644 --- a/documentation/view/client/documentation.css +++ b/documentation/view/client/documentation.css @@ -12,3 +12,7 @@ iframe { .s-alert-box { z-index: 10000 } + +button#sdk-code-generator { + margin-right: 1em +} diff --git a/documentation/view/client/documentation.html b/documentation/view/client/documentation.html index ab404a3898..795d17a77b 100644 --- a/documentation/view/client/documentation.html +++ b/documentation/view/client/documentation.html @@ -2,13 +2,24 @@
{{#if apiBackend.currentUserCanEdit }} - - {{/if}} + + {{/if}} + + {{#if documentationExists }} + + {{/if}} +

{{_ "documentation_Title" }}

diff --git a/documentation/view/client/documentation.js b/documentation/view/client/documentation.js index 183b8d2a46..8550ecd9e3 100644 --- a/documentation/view/client/documentation.js +++ b/documentation/view/client/documentation.js @@ -62,5 +62,11 @@ Template.documentation.events({ const apiBackend = instance.data.apiBackend // Show the manage API documentation form Modal.show('manageApiDocumentationModal', { apiBackend }) + }, + 'click #sdk-code-generator' (event, instance) { + // Get reference to API backend + const apiBackend = instance.data.apiBackend; + // Show the SDK Code generator form + Modal.show('sdkCodeGeneratorModal', { apiBackend }); } }); diff --git a/lib/i18n/en.i18n.json b/lib/i18n/en.i18n.json index cfac4a23e5..539cbf5346 100644 --- a/lib/i18n/en.i18n.json +++ b/lib/i18n/en.i18n.json @@ -115,12 +115,15 @@ "documentation_APICall_Warning_Message": "API calls (PUT, POST, or DELETE) from Swagger are real calls.", "documentation_APICall_Warning_Title": "Warning!", "documentation_Link_Title": "Link", + "documentation_manageDocumentation_buttonText": "Manage", "documentation_No_Link_Manager_Message": "You can add one using Manage API feature.", "documentation_No_Link_Message": "No documentation link is available.", "documentation_No_Swagger_Manager_Message": "You can add one using Manage API feature.", "documentation_No_Swagger_Message": "No swagger document is available.", "documentation_Title": "Documentation", "documentation_Viewer_Title": "Viewer", + "documentation_sdkGenerateButton": "SDK Generate", + "documentation_tooltipSDKGeneratorButton": "With a valid swagger file, you can download an SDK of your preferred language using this wizard", "editApiBackendForm-uploadLogo": "Upload logo", "editApiMetadata_editApiMetadataForm_button": "Edit API Metadata", "editApiMetadata_editApiMetadataForm_title": "Edit API Metadata", @@ -348,6 +351,8 @@ } } }, + "sdkCodeGeneratorModal_errorText": "Your file is not supported by the generator. Please upload the correct file", + "sdkCodeGeneratorModal_Title": "Generate SDK file", "searchField_button": "Search", "searchField_placeholder": "Search...", "searchPage_addedPrefix": "Added",