Skip to content

Commit

Permalink
Merge pull request #2 from OsamaHaikal/feat/make-devtools-page-consis…
Browse files Browse the repository at this point in the history
…tent

feat(devtools): use devtools uikit
  • Loading branch information
s00d authored Aug 20, 2024
2 parents acde627 + f244ef5 commit fb58e1d
Show file tree
Hide file tree
Showing 3 changed files with 653 additions and 117 deletions.
224 changes: 110 additions & 114 deletions client/app.vue
Original file line number Diff line number Diff line change
@@ -1,92 +1,8 @@
<template>
<div
class="relative"
style="height: 100vh"
>
<div class="flex h-full">
<!-- Sidebar for Locales -->
<div
class="h-full border-r border-r-gray-400 overflow-auto bg-gray-50 dark:bg-gray-800"
style="width: 22rem; min-width: 0; flex: 0 0 auto"
>
<div class="border-b border-b-gray-400 p-3">
<!-- Component Title -->
<h2 class="text-lg font-semibold text-gray-900 dark:text-gray-100 mb-3">
nuxt-i18n-micro
</h2>
<NTextInput
v-model="search"
placeholder="Search locales..."
icon="carbon-search"
class="w-full"
/>
</div>
<div
v-for="locale in filteredLocales"
:key="locale.locale"
class="relative group"
>
<button
class="text-secondary hover:bg-blue-100 dark:hover:bg-blue-900 flex select-none truncate px-2 py-2 font-mono text-sm w-full"
:class="{ 'bg-blue-200 dark:bg-blue-700': locale.locale === selectedLocale }"
@click="selectedLocale = locale.locale"
>
{{ locale.locale }}
</button>
</div>
</div>

<!-- Splitter -->
<div class="splitpanes__splitter bg-gray-300 dark:bg-gray-600" />

<!-- Main Content -->
<div
v-if="selectedLocale"
class="h-full relative w-full overflow-auto bg-white dark:bg-gray-900"
>
<div class="p-4">
<h3 class="text-lg mb-2 text-gray-900 dark:text-gray-100">
Translation Files for {{ selectedLocale }}
</h3>
<div
v-for="file in selectedLocaleFiles"
:key="file"
class="relative group"
>
<button
class="text-secondary hover:bg-blue-100 dark:hover:bg-blue-900 flex select-none truncate px-2 py-2 font-mono text-sm w-full"
:class="{ 'bg-blue-200 dark:bg-blue-700': file === selectedFile }"
@click="selectedFile = file"
>
{{ file }}
</button>
</div>

<div
v-if="selectedFileContent"
class="mt-4"
>
<h3 class="text-lg mb-2 text-gray-900 dark:text-gray-100">
Content of {{ selectedFile }}
</h3>
<pre
class="p-4 bg-gray-100 rounded dark:bg-gray-800 text-sm text-gray-900 dark:text-gray-100"
style="white-space: pre-wrap; word-break: break-word;"
>
<code class="language-json"><span v-html="formattedFileContent" /></code>
</pre>
</div>
</div>
</div>
</div>
</div>
</template>

<script setup lang="ts">
import { onDevtoolsClientConnected } from '@nuxt/devtools-kit/iframe-client'
import { ref, computed } from 'vue'
import { onDevtoolsClientConnected } from '@nuxt/devtools-kit/iframe-client'
import JsonEditorVue from 'json-editor-vue'
// TypeScript interfaces for locale data
interface TranslationContent {
[key: string]: unknown
}
Expand All @@ -99,12 +15,11 @@ interface LocaleData {
const RPC_NAMESPACE = 'nuxt-i18n-micro'
const search = ref('')
const selectedLocale = ref<string>('')
const selectedFile = ref<string>('')
const locales = ref<LocaleData[]>([])
const search = ref<string>('')
// Computed properties to filter and display locale and file data
const selectedLocaleFiles = computed<string[]>(() => {
const locale = locales.value.find(l => l.locale === selectedLocale.value)
return locale ? locale.files : []
Expand All @@ -116,22 +31,8 @@ const selectedFileContent = computed<TranslationContent | null>(() => {
})
const filteredLocales = computed<LocaleData[]>(() => {
if (!search.value) {
return locales.value
}
return locales.value.filter(locale =>
locale.locale.toLowerCase().includes(search.value.toLowerCase()),
)
})
const formattedFileContent = computed<string>(() => {
// Add syntax highlighting for JSON
return '<br>' + JSON.stringify(selectedFileContent.value, null, 2)
.replace(/"(.*?)":/g, '<span class="text-blue-500">"$1":</span>') // Keys
.replace(/:\s?"(.*?)"/g, ': "<span class="text-green-500">$1</span>"') // String values
.replace(/:\s?(\d+)/g, ': <span class="text-purple-500">$1</span>') // Number values
.replace(/:\s?(true|false)/g, ': <span class="text-red-500">$1</span>') // Boolean values
if (!search.value) return locales.value
return locales.value.filter(locale => locale.locale.toLowerCase().includes(search.value.toLowerCase()))
})
onDevtoolsClientConnected(async (client) => {
Expand All @@ -146,14 +47,109 @@ onDevtoolsClientConnected(async (client) => {
})
</script>

<style scoped>
.splitpanes__splitter {
width: 4px;
cursor: ew-resize;
}
<template>
<div
class="h-screen overflow-auto"
>
<NSplitPane
storage-key="tab-i18n-locales"
>
<template #left>
<div class="h-[48px] flex items-center justify-between gap1 px-3">
<NTextInput
v-model="search"
placeholder="Search locales..."
icon="carbon-search"
class="w-full"
/>
</div>
<template
v-for="locale in filteredLocales"
:key="locale.locale"
>
<button
block
w-full
truncate
px2
py1
text-start
text-sm
font-mono
:class="locale.locale === selectedLocale ? 'text-primary n-bg-active' : 'text-secondary hover:n-bg-hover'"
@click="selectedLocale = locale.locale"
>
{{ locale.locale }}
</button>
<div x-divider />
</template>
</template>

.language-json {
font-family: 'Courier New', Courier, monospace;
font-size: 0.875rem;
}
</style>
<template #right>
<div
v-if="selectedLocale"
h-full
of-hidden
flex="~ col"
>
<div
border="b base"
class="h-[49px] flex flex-none items-center justify-between px-4 text-sm"
>
<div class="flex items-center gap-4">
<code>{{ selectedLocale }}</code>
</div>
</div>
<div
v-for="file in selectedLocaleFiles"
:key="file"
>
<button
block
w-full
truncate
px2
py1
text-start
text-sm
font-mono
:class="file === selectedFile ? 'text-primary n-bg-active' : 'text-secondary hover:n-bg-hover'"
@click="selectedFile = file"
>
{{ file }}
</button>
<div x-divider />
</div>

<JsonEditorVue
v-if="selectedFileContent"
v-model="selectedFileContent"
v-bind="$attrs"
style="overflow: auto;"
:main-menu-bar="false"
:navigation-bar="false"
:status-bar="false"
:read-only="readonly"
:indentation="2"
:tab-size="2"
/>
</div>
<NPanelGrids v-else>
<NCard
px6
py4
>
Select a locale to view locale.<br>Learn more about
<NLink
href="https://github.com/s00d/nuxt-i18n-micro"
n="orange"
target="_blank"
>
i18n
</NLink>
</NCard>
</NPanelGrids>
</template>
</NSplitPane>
</div>
</template>
Loading

0 comments on commit fb58e1d

Please sign in to comment.