nuxt-google-sheets-import 0.1.10 → 0.1.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -46,6 +46,12 @@ NUXT_GOOGLE_API_KEY=your_google_sheets_api_key
|
|
|
46
46
|
|
|
47
47
|
Then open `/google-sheets-import` in your app.
|
|
48
48
|
|
|
49
|
+
## Todo
|
|
50
|
+
- [ ] Find out why 'addTemplate' adds the example file to the module root/utils (unintended) as well as the consuming app utils folder (intended).
|
|
51
|
+
- [ ] Check page overrides are working as expected.
|
|
52
|
+
- [ ] Should @nuxt/ui be a dependency or should it just install? Pretty heavy for one page
|
|
53
|
+
- [ ] Check that development mode is the only mode the module runs in. If not, add safeguards to prevent unintended file writes in production.
|
|
54
|
+
|
|
49
55
|
## Repository Development
|
|
50
56
|
|
|
51
57
|
Development commands:
|
package/dist/module.mjs
CHANGED
|
@@ -18,7 +18,7 @@ const module$1 = defineNuxtModule({
|
|
|
18
18
|
const resolver = createResolver(import.meta.url);
|
|
19
19
|
addTemplate({
|
|
20
20
|
filename: "googleSheetsImportSchemas.ts",
|
|
21
|
-
src: resolver.resolve("./runtime/app/examples/googleSheetsImportSchemas
|
|
21
|
+
src: resolver.resolve("./runtime/app/examples/googleSheetsImportSchemas"),
|
|
22
22
|
dst: "utils/.googleSheetsImportSchemas.ts",
|
|
23
23
|
write: true
|
|
24
24
|
});
|
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
-
import {
|
|
3
|
-
import { useToast } from "#imports";
|
|
2
|
+
import { onMounted, ref, watch } from "vue";
|
|
4
3
|
import { useGoogleSheetsImport } from "../composables/useGoogleSheetsImport";
|
|
5
|
-
import { copyTextWithSuccessToast } from "../utils/clipboard";
|
|
6
4
|
import { toTsvRow } from "../utils/delimited";
|
|
7
5
|
const props = defineProps({
|
|
8
6
|
initialSchema: { type: String, required: false, default: "" }
|
|
9
7
|
});
|
|
10
8
|
const { getSchemaColumns } = useGoogleSheetsImport();
|
|
11
|
-
const toast = useToast();
|
|
12
9
|
const selectedSchema = ref("");
|
|
13
10
|
const availableSchemas = ref([]);
|
|
14
11
|
const columns = ref([]);
|
|
@@ -16,10 +13,7 @@ const collectionType = ref("unknown");
|
|
|
16
13
|
const pageOverrideColumns = ref([]);
|
|
17
14
|
const status = ref("idle");
|
|
18
15
|
const error = ref("");
|
|
19
|
-
const
|
|
20
|
-
label: schema,
|
|
21
|
-
value: schema
|
|
22
|
-
})));
|
|
16
|
+
const copyFeedback = ref("");
|
|
23
17
|
async function loadSchemas() {
|
|
24
18
|
status.value = "pending";
|
|
25
19
|
error.value = "";
|
|
@@ -63,131 +57,161 @@ onMounted(async () => {
|
|
|
63
57
|
await loadColumns(selectedSchema.value);
|
|
64
58
|
}
|
|
65
59
|
});
|
|
60
|
+
async function copyText(text, successMessage) {
|
|
61
|
+
if (!text) {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
try {
|
|
65
|
+
await navigator.clipboard.writeText(text);
|
|
66
|
+
copyFeedback.value = successMessage;
|
|
67
|
+
} catch {
|
|
68
|
+
copyFeedback.value = "Could not copy to clipboard.";
|
|
69
|
+
}
|
|
70
|
+
}
|
|
66
71
|
async function copyColumns() {
|
|
67
|
-
await
|
|
68
|
-
text: columns.value.join("\n"),
|
|
69
|
-
toast,
|
|
70
|
-
description: "Column names copied to clipboard.",
|
|
71
|
-
title: "Copied"
|
|
72
|
-
});
|
|
72
|
+
await copyText(columns.value.join("\n"), "Column names copied to clipboard.");
|
|
73
73
|
}
|
|
74
74
|
async function copyColumnsTsv() {
|
|
75
|
-
await
|
|
76
|
-
text: toTsvRow(columns.value),
|
|
77
|
-
toast,
|
|
78
|
-
description: "Column names copied as a tab-separated row for Google Sheets.",
|
|
79
|
-
title: "Copied"
|
|
80
|
-
});
|
|
75
|
+
await copyText(toTsvRow(columns.value), "Column names copied as a tab-separated row for Google Sheets.");
|
|
81
76
|
}
|
|
82
77
|
async function copyPageOverrideColumns() {
|
|
83
|
-
await
|
|
84
|
-
text: pageOverrideColumns.value.join("\n"),
|
|
85
|
-
toast,
|
|
86
|
-
description: "Page override column names copied to clipboard.",
|
|
87
|
-
title: "Copied"
|
|
88
|
-
});
|
|
78
|
+
await copyText(pageOverrideColumns.value.join("\n"), "Page override column names copied to clipboard.");
|
|
89
79
|
}
|
|
90
80
|
async function copyPageOverrideColumnsTsv() {
|
|
91
|
-
await
|
|
92
|
-
text: toTsvRow(pageOverrideColumns.value),
|
|
93
|
-
toast,
|
|
94
|
-
description: "Page override column names copied as a tab-separated row for Google Sheets.",
|
|
95
|
-
title: "Copied"
|
|
96
|
-
});
|
|
81
|
+
await copyText(toTsvRow(pageOverrideColumns.value), "Page override column names copied as a tab-separated row for Google Sheets.");
|
|
97
82
|
}
|
|
98
83
|
</script>
|
|
99
84
|
|
|
100
85
|
<template>
|
|
101
|
-
<div class="space-y-4">
|
|
102
|
-
<
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
86
|
+
<div class="space-y-4 rounded-lg border border-gray-200 p-4 bg-white">
|
|
87
|
+
<div class="rounded-md border border-gray-200 bg-gray-50 p-3">
|
|
88
|
+
<p class="text-sm font-semibold text-gray-900">
|
|
89
|
+
Schema column helper
|
|
90
|
+
</p>
|
|
91
|
+
<p class="text-sm text-gray-600">
|
|
92
|
+
Choose a schema to see the expected Google Sheet column names.
|
|
93
|
+
</p>
|
|
94
|
+
</div>
|
|
108
95
|
|
|
109
|
-
<
|
|
96
|
+
<div
|
|
110
97
|
v-if="error"
|
|
111
|
-
|
|
112
|
-
:description="error"
|
|
113
|
-
color="error"
|
|
114
|
-
variant="subtle"
|
|
115
|
-
/>
|
|
116
|
-
|
|
117
|
-
<UFormField
|
|
118
|
-
label="Collection schema"
|
|
119
|
-
name="schema"
|
|
120
|
-
description="Pick the schema you want to import."
|
|
98
|
+
class="rounded-md border border-red-200 bg-red-50 p-3"
|
|
121
99
|
>
|
|
122
|
-
<
|
|
100
|
+
<p class="text-sm font-semibold text-red-900">
|
|
101
|
+
Could not load schema information
|
|
102
|
+
</p>
|
|
103
|
+
<p class="text-sm text-red-700">
|
|
104
|
+
{{ error }}
|
|
105
|
+
</p>
|
|
106
|
+
</div>
|
|
107
|
+
|
|
108
|
+
<div class="space-y-1">
|
|
109
|
+
<label
|
|
110
|
+
for="schema-select"
|
|
111
|
+
class="block text-sm font-medium text-gray-800"
|
|
112
|
+
>
|
|
113
|
+
Collection schema
|
|
114
|
+
</label>
|
|
115
|
+
<p class="text-xs text-gray-500">
|
|
116
|
+
Pick the schema you want to import.
|
|
117
|
+
</p>
|
|
118
|
+
<select
|
|
119
|
+
id="schema-select"
|
|
123
120
|
v-model="selectedSchema"
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
121
|
+
class="w-full max-w-sm rounded-md border border-gray-300 bg-white px-3 py-2 text-sm text-gray-900"
|
|
122
|
+
:disabled="status === 'pending' || !availableSchemas.length"
|
|
123
|
+
>
|
|
124
|
+
<option
|
|
125
|
+
v-if="!availableSchemas.length"
|
|
126
|
+
value=""
|
|
127
|
+
>
|
|
128
|
+
{{ status === "pending" ? "Loading schemas..." : "No schemas found" }}
|
|
129
|
+
</option>
|
|
130
|
+
<option
|
|
131
|
+
v-for="schema in availableSchemas"
|
|
132
|
+
:key="schema"
|
|
133
|
+
:value="schema"
|
|
134
|
+
>
|
|
135
|
+
{{ schema }}
|
|
136
|
+
</option>
|
|
137
|
+
</select>
|
|
138
|
+
</div>
|
|
131
139
|
|
|
132
|
-
<
|
|
140
|
+
<div
|
|
133
141
|
v-if="status === 'success' && selectedSchema"
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
142
|
+
class="rounded-md border border-gray-200 bg-gray-50 p-3"
|
|
143
|
+
>
|
|
144
|
+
<p class="text-sm font-semibold text-gray-900">
|
|
145
|
+
Expected column names
|
|
146
|
+
</p>
|
|
147
|
+
<p class="text-sm text-gray-600">
|
|
148
|
+
Use these exact headers in your Google Sheet for schema: {{ selectedSchema }}.
|
|
149
|
+
</p>
|
|
150
|
+
</div>
|
|
151
|
+
|
|
152
|
+
<p
|
|
153
|
+
v-if="copyFeedback"
|
|
154
|
+
class="text-sm text-green-700"
|
|
155
|
+
role="status"
|
|
156
|
+
>
|
|
157
|
+
{{ copyFeedback }}
|
|
158
|
+
</p>
|
|
139
159
|
|
|
140
160
|
<div
|
|
141
161
|
v-if="columns.length"
|
|
142
162
|
class="space-y-3"
|
|
143
163
|
>
|
|
144
164
|
<div class="flex flex-wrap gap-2">
|
|
145
|
-
<
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
color="neutral"
|
|
149
|
-
variant="subtle"
|
|
165
|
+
<button
|
|
166
|
+
type="button"
|
|
167
|
+
class="rounded-md border border-gray-300 bg-white px-3 py-2 text-sm text-gray-800 hover:bg-gray-50"
|
|
150
168
|
@click="copyColumns"
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
169
|
+
>
|
|
170
|
+
Copy column names
|
|
171
|
+
</button>
|
|
172
|
+
<button
|
|
173
|
+
type="button"
|
|
174
|
+
class="rounded-md border border-gray-300 bg-white px-3 py-2 text-sm text-gray-800 hover:bg-gray-50"
|
|
157
175
|
@click="copyColumnsTsv"
|
|
158
|
-
|
|
176
|
+
>
|
|
177
|
+
Copy as tab-separated row
|
|
178
|
+
</button>
|
|
159
179
|
</div>
|
|
160
|
-
<pre class="text-xs whitespace-pre-wrap">{{ columns.join("\n") }}</pre>
|
|
180
|
+
<pre class="rounded-md border border-gray-200 bg-gray-50 p-3 text-xs whitespace-pre-wrap text-gray-800">{{ columns.join("\n") }}</pre>
|
|
161
181
|
|
|
162
|
-
<
|
|
182
|
+
<div
|
|
163
183
|
v-if="collectionType === 'page' && pageOverrideColumns.length"
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
184
|
+
class="rounded-md border border-gray-200 bg-gray-50 p-3"
|
|
185
|
+
>
|
|
186
|
+
<p class="text-sm font-semibold text-gray-900">
|
|
187
|
+
Nuxt Content page overrides
|
|
188
|
+
</p>
|
|
189
|
+
<p class="text-sm text-gray-600">
|
|
190
|
+
Optional built-in page fields Nuxt Content adds automatically for page collections.
|
|
191
|
+
</p>
|
|
192
|
+
</div>
|
|
169
193
|
|
|
170
194
|
<div
|
|
171
195
|
v-if="collectionType === 'page' && pageOverrideColumns.length"
|
|
172
196
|
class="space-y-3"
|
|
173
197
|
>
|
|
174
198
|
<div class="flex flex-wrap gap-2">
|
|
175
|
-
<
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
color="neutral"
|
|
179
|
-
variant="subtle"
|
|
199
|
+
<button
|
|
200
|
+
type="button"
|
|
201
|
+
class="rounded-md border border-gray-300 bg-white px-3 py-2 text-sm text-gray-800 hover:bg-gray-50"
|
|
180
202
|
@click="copyPageOverrideColumns"
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
203
|
+
>
|
|
204
|
+
Copy page override columns
|
|
205
|
+
</button>
|
|
206
|
+
<button
|
|
207
|
+
type="button"
|
|
208
|
+
class="rounded-md border border-gray-300 bg-white px-3 py-2 text-sm text-gray-800 hover:bg-gray-50"
|
|
187
209
|
@click="copyPageOverrideColumnsTsv"
|
|
188
|
-
|
|
210
|
+
>
|
|
211
|
+
Copy overrides as tab-separated row
|
|
212
|
+
</button>
|
|
189
213
|
</div>
|
|
190
|
-
<pre class="text-xs whitespace-pre-wrap">{{ pageOverrideColumns.join("\n") }}</pre>
|
|
214
|
+
<pre class="rounded-md border border-gray-200 bg-gray-50 p-3 text-xs whitespace-pre-wrap text-gray-800">{{ pageOverrideColumns.join("\n") }}</pre>
|
|
191
215
|
</div>
|
|
192
216
|
</div>
|
|
193
217
|
</div>
|
package/package.json
CHANGED