| // Licensed to the Apache Software Foundation (ASF) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The ASF licenses this file |
| // to you under the Apache License, Version 2.0 (the |
| // "License"); you may not use this file except in compliance |
| // with the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, |
| // software distributed under the License is distributed on an |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| // KIND, either express or implied. See the License for the |
| // specific language governing permissions and limitations |
| // under the License. |
| |
| <template> |
| <div> |
| <resource-layout> |
| <template #left> |
| <a-card :bordered="false"> |
| <a-auto-complete |
| v-model:value="query" |
| :options="options.filter(value => value.value.toLowerCase().includes(query.toLowerCase()))" |
| style="width: 100%" |
| > |
| <a-input-search |
| size="default" |
| :placeholder="$t('label.search')" |
| v-model:value="query" |
| allow-clear |
| enter-button |
| > |
| <template #prefix><search-outlined /></template> |
| </a-input-search> |
| </a-auto-complete> |
| <a-list style="margin-top: 12px; height:580px; overflow-y: scroll;" size="small" :data-source="Object.keys($store.getters.apis).sort()"> |
| <template #renderItem="{ item }"> |
| <a> |
| <a-list-item |
| v-if="item.toLowerCase().includes(query.toLowerCase())" |
| @click="showApi(item)" |
| style="padding-left: 12px" |
| :class="selectedApi === item ? 'selected-item' : ''"> |
| {{ item }} <a-tag v-if="$store.getters.apis[item].isasync" color="blue">async</a-tag> |
| </a-list-item> |
| </a> |
| </template> |
| </a-list> |
| <a-divider style="margin-bottom: 12px" /> |
| <span>{{ Object.keys($store.getters.apis).length }} {{ $t('label.api.docs.count') }}</span> |
| </a-card> |
| </template> |
| <template #right> |
| <a-card |
| class="spin-content" |
| :bordered="true" |
| style="width: 100%; overflow-x: auto"> |
| <span v-if="selectedApi && selectedApi in $store.getters.apis"> |
| <h2>{{ selectedApi }} |
| <a-tag v-if="$store.getters.apis[selectedApi].isasync" color="blue">Asynchronous API</a-tag> |
| <a-tag v-if="$store.getters.apis[selectedApi].since">Since {{ $store.getters.apis[selectedApi].since }}</a-tag> |
| <tooltip-button |
| tooltipPlacement="right" |
| :tooltip="$t('label.copy') + ' ' + selectedApi" |
| icon="CopyOutlined" |
| type="outlined" |
| size="small" |
| @onClick="$message.success($t('label.copied.clipboard'))" |
| :copyResource="selectedApi" /> |
| </h2> |
| <p>{{ $store.getters.apis[selectedApi].description }}</p> |
| <h3>{{ $t('label.request') }} {{ $t('label.params') }}:</h3> |
| <a-table |
| :columns="[{title: $t('label.name'), dataIndex: 'name'}, {title: $t('label.required'), dataIndex: 'required'}, {title: $t('label.type'), dataIndex: 'type'}, {title: $t('label.description'), dataIndex: 'description'}]" |
| :data-source="selectedParams" |
| :pagination="false" |
| size="small"> |
| <template #bodyCell="{text, column, record}"> |
| <a-tag v-if="record.since && column.dataIndex === 'description'">Since {{ record.since }}</a-tag> |
| <span v-if="record.required === true"><strong>{{ text }}</strong></span> |
| <span v-else>{{ text }}</span> |
| </template> |
| </a-table> |
| <br/> |
| <h3>{{ $t('label.response') }} {{ $t('label.params') }}:</h3> |
| <a-table |
| :columns="[{title: $t('label.name'), dataIndex: 'name'}, {title: $t('label.type'), dataIndex: 'type'}, {title: $t('label.description'), dataIndex: 'description'}]" |
| :data-source="selectedResponse" |
| :pagination="false" |
| size="small" /> |
| </span> |
| <span v-else> |
| <a-alert |
| :message="$t('label.api.docs')" |
| type="info" |
| show-icon |
| banner> |
| <template #description> |
| <a href="https://docs.cloudstack.apache.org/en/latest/developersguide/dev.html" target="_blank">{{ $t('label.api.docs.description') }}</a> |
| </template> |
| </a-alert> |
| <a-result |
| status="success" |
| :title="$t('label.download') + ' CloudStack CloudMonkey CLI'" |
| sub-title="For API automation and orchestration" |
| > |
| <template #extra> |
| <a-button type="primary"><a href="https://github.com/apache/cloudstack-cloudmonkey/releases" target="_blank">{{ $t('label.download') }} CLI</a></a-button> |
| <a-button><a href="https://github.com/apache/cloudstack-cloudmonkey/wiki/Usage" target="_blank">{{ $t('label.open.documentation') }} (CLI)</a></a-button> |
| <br/> |
| <br/> |
| <div v-if="showKeys"> |
| <key-outlined /> |
| <strong> |
| {{ $t('label.apikey') }} |
| <tooltip-button |
| tooltipPlacement="right" |
| :tooltip="$t('label.copy') + ' ' + $t('label.apikey')" |
| icon="CopyOutlined" |
| type="dashed" |
| size="small" |
| @onClick="$message.success($t('label.copied.clipboard'))" |
| :copyResource="userkeys.apikey" /> |
| </strong> |
| <div> |
| {{ userkeys.apikey.substring(0, 20) }}... |
| </div> |
| <br/> |
| <lock-outlined /> |
| <strong> |
| {{ $t('label.secretkey') }} |
| <tooltip-button |
| tooltipPlacement="right" |
| :tooltip="$t('label.copy') + ' ' + $t('label.secretkey')" |
| icon="CopyOutlined" |
| type="dashed" |
| size="small" |
| @onClick="$message.success($t('label.copied.clipboard'))" |
| :copyResource="userkeys.secretkey" /> |
| </strong> |
| <div> |
| {{ userkeys.secretkey.substring(0, 20) }}... |
| </div> |
| </div> |
| </template> |
| </a-result> |
| </span> |
| </a-card> |
| </template> |
| </resource-layout> |
| </div> |
| </template> |
| |
| <script> |
| import { getAPI } from '@/api' |
| |
| import ResourceLayout from '@/layouts/ResourceLayout' |
| import TooltipButton from '@/components/widgets/TooltipButton' |
| |
| export default { |
| name: 'ApiDocsPlugin', |
| components: { |
| ResourceLayout, |
| TooltipButton |
| }, |
| data () { |
| return { |
| query: '', |
| selectedApi: '', |
| selectedParams: [], |
| selectedResponse: [], |
| showKeys: false, |
| userkeys: {}, |
| options: [ |
| { value: 'VirtualMachine', label: 'Instance' }, |
| { value: 'Kubernetes', label: 'Kubernetes' }, |
| { value: 'Volume', label: 'Volume' }, |
| { value: 'Snapshot', label: 'Snapshot' }, |
| { value: 'Backup', label: 'Backup' }, |
| { value: 'Network', label: 'Network' }, |
| { value: 'IpAddress', label: 'IP Address' }, |
| { value: 'VPN', label: 'VPN' }, |
| { value: 'VPC', label: 'VPC' }, |
| { value: 'NetworkACL', label: 'Network ACL' }, |
| { value: 'SecurityGroup', label: 'Security Group' }, |
| { value: 'Template', label: 'Template' }, |
| { value: 'ISO', label: 'ISO' }, |
| { value: 'SSH', label: 'SSH' }, |
| { value: 'Project', label: 'Project' }, |
| { value: 'Account', label: 'Account' }, |
| { value: 'User', label: 'User' }, |
| { value: 'Event', label: 'Event' }, |
| { value: 'Offering', label: 'Offering' }, |
| { value: 'Zone', label: 'Zone' } |
| ] |
| } |
| }, |
| created () { |
| if (!('getUserKeys' in this.$store.getters.apis)) { |
| return |
| } |
| getAPI('getUserKeys', { id: this.$store.getters.userInfo.id }).then(json => { |
| this.userkeys = json.getuserkeysresponse.userkeys |
| if (this.userkeys && this.userkeys.secretkey) { |
| this.showKeys = true |
| } |
| }) |
| }, |
| methods: { |
| showApi (api) { |
| this.selectedApi = api |
| this.selectedParams = this.$store.getters.apis[api].params |
| .sort((a, b) => (a.name > b.name) ? 1 : ((b.name > a.name) ? -1 : 0)) |
| .sort((a, b) => (a.required > b.required) ? -1 : ((b.required > a.required) ? 1 : 0)) |
| .filter(value => Object.keys(value).length > 0) |
| this.selectedResponse = this.$store.getters.apis[api].response.filter(value => Object.keys(value).length > 0) |
| } |
| } |
| } |
| </script> |