Browse Source

fix: extension items (#9216)

* feat: sample extension & markdown support for description

Signed-off-by: mertmit <mertmit99@gmail.com>

* docs: extension developer guide

Signed-off-by: mertmit <mertmit99@gmail.com>

* docs: improved extension guid

Signed-off-by: mertmit <mertmit99@gmail.com>

* misc: remove docs from current PR

Signed-off-by: Raju Udava <86527202+dstala@users.noreply.github.com>

---------

Signed-off-by: mertmit <mertmit99@gmail.com>
Signed-off-by: Raju Udava <86527202+dstala@users.noreply.github.com>
Co-authored-by: Raju Udava <86527202+dstala@users.noreply.github.com>
pull/9221/head
Mert E. 4 months ago committed by GitHub
parent
commit
b5d1ff6002
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 6
      packages/nc-gui/components/extensions/Details.vue
  2. 2
      packages/nc-gui/composables/useExtensionHelper.ts
  3. 18
      packages/nc-gui/composables/useExtensions.ts
  4. BIN
      packages/nc-gui/extensions/json-exporter/icon.png
  5. 12
      packages/nc-gui/extensions/json-exporter/manifest.json
  6. 1
      packages/nc-gui/package.json
  7. 463
      pnpm-lock.yaml

6
packages/nc-gui/components/extensions/Details.vue

@ -1,4 +1,6 @@
<script lang="ts" setup> <script lang="ts" setup>
import { marked } from 'marked'
interface Prop { interface Prop {
modelValue: boolean modelValue: boolean
extensionId: string extensionId: string
@ -26,6 +28,8 @@ const onAddExtension = (ext: any) => {
const activeExtension = computed(() => { const activeExtension = computed(() => {
return availableExtensions.value.find((ext) => ext.id === props.extensionId) return availableExtensions.value.find((ext) => ext.id === props.extensionId)
}) })
const detailsBody = activeExtension.value?.description ? marked.parse(activeExtension.value.description) : '<p></p>'
</script> </script>
<template> <template>
@ -59,7 +63,7 @@ const activeExtension = computed(() => {
</div> </div>
</div> </div>
<div class="whitespace-pre-line text-base text-gray-600">{{ activeExtension.description }}</div> <div class="text-base text-gray-600" v-html="detailsBody"></div>
</div> </div>
<div class="extension-details-right"> <div class="extension-details-right">
<NcButton class="w-full" @click="onAddExtension(activeExtension)"> <NcButton class="w-full" @click="onAddExtension(activeExtension)">

2
packages/nc-gui/composables/useExtensionHelper.ts

@ -198,6 +198,7 @@ const [useProvideExtensionHelper, useExtensionHelper] = useInjectionState((exten
} }
return { return {
$api,
fullscreen, fullscreen,
collapsed, collapsed,
extension, extension,
@ -205,7 +206,6 @@ const [useProvideExtensionHelper, useExtensionHelper] = useInjectionState((exten
getViewsForTable, getViewsForTable,
getData, getData,
getTableMeta, getTableMeta,
$api,
insertData, insertData,
updateData, updateData,
upsertData, upsertData,

18
packages/nc-gui/composables/useExtensions.ts

@ -21,6 +21,7 @@ interface ExtensionManifest {
publisherName: string publisherName: string
publisherEmail: string publisherEmail: string
publisherUrl: string publisherUrl: string
disabled?: boolean
} }
abstract class ExtensionType { abstract class ExtensionType {
@ -334,11 +335,24 @@ export const useExtensions = createSharedComposable(() => {
onMounted(() => { onMounted(() => {
const modules = import.meta.glob('../extensions/*/*.json') const modules = import.meta.glob('../extensions/*/*.json')
const extensionCount = modules ? Object.keys(modules).length : 0
let disabledCount = 0
for (const path in modules) { for (const path in modules) {
modules[path]().then((mod: any) => { modules[path]().then((mod: any) => {
const manifest = mod.default as ExtensionManifest const manifest = mod.default as ExtensionManifest
availableExtensions.value.push(manifest)
if (Object.keys(modules).length === availableExtensions.value.length) { if (manifest?.disabled !== true) {
availableExtensions.value.push(manifest)
} else {
disabledCount++
}
if (availableExtensions.value.length + disabledCount === extensionCount) {
availableExtensions.value.sort((a, b) => a.title.localeCompare(b.title))
extensionsLoaded.value = true extensionsLoaded.value = true
} }
}) })

BIN
packages/nc-gui/extensions/json-exporter/icon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

12
packages/nc-gui/extensions/json-exporter/manifest.json

@ -0,0 +1,12 @@
{
"id": "nc-json-exporter",
"title": "JSON Exporter",
"description": "This is a sample NocoDB extension that exports data in JSON format. \nIt is used to demonstrate how to create a NocoDB extension.\n\nThis extension is disabled by default. To access it you need to first change the `disabled` property in the manifest file to `false`.",
"entry": "json-exporter",
"version": "0.1",
"iconUrl": "json-exporter/icon.png",
"publisherName": "NocoDB",
"publisherEmail": "contact@nocodb.com",
"publisherUrl": "https://www.nocodb.com",
"disabled": true
}

1
packages/nc-gui/package.json

@ -142,6 +142,7 @@
"@types/inflection": "^1.13.2", "@types/inflection": "^1.13.2",
"@types/leaflet": "^1.9.12", "@types/leaflet": "^1.9.12",
"@types/leaflet.markercluster": "^1.5.4", "@types/leaflet.markercluster": "^1.5.4",
"@types/marked": "^6.0.0",
"@types/papaparse": "^5.3.14", "@types/papaparse": "^5.3.14",
"@types/parse-github-url": "^1.0.3", "@types/parse-github-url": "^1.0.3",
"@types/qrcode": "^1.5.5", "@types/qrcode": "^1.5.5",

463
pnpm-lock.yaml

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save