Skip to content

Commit

Permalink
feat(ui): Request Panel > Address Bar > Highlight valid and invalid e…
Browse files Browse the repository at this point in the history
…nvironment variables
  • Loading branch information
flawiddsouza committed Jan 17, 2024
1 parent 21df5b4 commit bbe93b9
Show file tree
Hide file tree
Showing 7 changed files with 130 additions and 36 deletions.
2 changes: 2 additions & 0 deletions packages/ui/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,8 @@ export default {
Object.assign(tab, this.activeTab)
}
}
this.$store.dispatch('updateActiveTabEnvironmentResolved')
},
deep: true
},
Expand Down
142 changes: 108 additions & 34 deletions packages/ui/src/components/CodeMirrorSingleLine.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,41 +3,87 @@
</template>

<script>
import { EditorView, keymap, placeholder } from '@codemirror/view'
import { EditorState } from '@codemirror/state'
import { EditorView, keymap, placeholder, ViewPlugin, Decoration } from '@codemirror/view'
import { EditorState, RangeSetBuilder, StateEffect } from '@codemirror/state'
import { history, historyKeymap } from '@codemirror/commands'
function createState(vueInstance) {
return EditorState.create({
doc: vueInstance.modelValue,
extensions: [
history(),
EditorView.updateListener.of(v => {
if(v.docChanged) {
vueInstance.emitted = true
vueInstance.$emit('update:modelValue', v.state.doc.toString())
const envVarDecoration = envVariables => {
return ViewPlugin.fromClass(class {
decorations
constructor(view) {
this.decorations = this.highlightEnvVariables(view, envVariables)
}
update(update) {
if (update.docChanged || update.viewportChanged) {
this.decorations = this.highlightEnvVariables(update.view, envVariables)
}
}
highlightEnvVariables(view, envVariables) {
const builder = new RangeSetBuilder()
const re = /{{\s*(\w+)\s*}}/g
for (let { from, to } of view.visibleRanges) {
const range = view.state.doc.sliceString(from, to)
let match
while ((match = re.exec(range))) {
const start = from + match.index
const end = start + match[0].length
const varName = match[1]
const isInEnv = varName in envVariables
const className = isInEnv ? 'valid-env-var' : 'invalid-env-var'
const titleText = isInEnv ? envVariables[varName] : 'Environment variable not found'
const decoration = Decoration.mark({
class: className,
attributes: {title: titleText}
})
builder.add(start, end, decoration)
}
}),
// From: https://discuss.codemirror.net/t/codemirror-6-single-line-and-or-avoid-carriage-return/2979/2
EditorState.transactionFilter.of(tr => tr.newDoc.lines > 1 ? [] : tr),
EditorView.domEventHandlers({
paste: (event, view) => {
const content = event.clipboardData.getData('text/plain')
}
return builder.finish()
}
}, {
decorations: v => v.decorations
})
}
if(content.includes('\n')) {
event.preventDefault()
const contentWithoutNewLines = content.replace(/[\n\r]/g, '')
const transaction = view.state.replaceSelection(contentWithoutNewLines)
const update = view.state.update(transaction)
view.update([update])
}
function getExtensions(vueInstance) {
return [
history(),
EditorView.updateListener.of(v => {
if(v.docChanged) {
vueInstance.emitted = true
vueInstance.$emit('update:modelValue', v.state.doc.toString())
}
}),
// From: https://discuss.codemirror.net/t/codemirror-6-single-line-and-or-avoid-carriage-return/2979/2
EditorState.transactionFilter.of(tr => tr.newDoc.lines > 1 ? [] : tr),
EditorView.domEventHandlers({
paste: (event, view) => {
const content = event.clipboardData.getData('text/plain')
if(content.includes('\n')) {
event.preventDefault()
const contentWithoutNewLines = content.replace(/[\n\r]/g, '')
const transaction = view.state.replaceSelection(contentWithoutNewLines)
const update = view.state.update(transaction)
view.update([update])
}
}),
keymap.of([
...historyKeymap
]),
placeholder(vueInstance.placeholder)
]
}
}),
keymap.of([
...historyKeymap
]),
placeholder(vueInstance.placeholder),
envVarDecoration(vueInstance.envVariables),
]
}
function createState(vueInstance) {
return EditorState.create({
doc: vueInstance.modelValue,
extensions: getExtensions(vueInstance)
})
}
Expand All @@ -50,22 +96,36 @@ export default {
placeholder: {
type: String,
default: ''
}
},
envVariables: {
type: Object,
default: () => ({})
},
},
data() {
return {
editor: null,
emitted: false
emitted: false,
}
},
editor: null,
watch: {
modelValue() {
if(!this.emitted) {
this.editor.setState(createState(this))
} else {
this.emitted = false
}
}
},
envVariables: {
deep: true,
handler() {
if (this.editor) {
this.editor.dispatch({
effects: StateEffect.reconfigure.of(getExtensions(this))
})
}
}
},
},
mounted() {
this.editor = new EditorView({
Expand All @@ -87,4 +147,18 @@ export default {
margin-right: 0.5rem;
overflow-x: hidden !important;
}
.code-mirror-single-line .valid-env-var {
background-color: var(--valid-env-highlight-background-color);
border-radius: 3px;
padding: 2px 0;
color: var(--valid-env-highlight-color);
}
.code-mirror-single-line .invalid-env-var {
background-color: var(--invalid-env-highlight-background-color);
border-radius: 3px;
padding: 2px 0;
color: var(--invalid-env-highlight-color);
}
</style>
5 changes: 4 additions & 1 deletion packages/ui/src/components/RequestPanel.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<option v-for="method in methods">{{ method }}</option>
</select>
<div class="code-mirror-input-container">
<CodeMirrorSingleLine v-model="activeTab.url" placeholder="Enter request URL" :key="'address-bar-' + activeTab._id" @keydown="handleAddressBarKeyDown" @paste="handleAdressBarPaste" />
<CodeMirrorSingleLine v-model="activeTab.url" placeholder="Enter request URL" :key="'address-bar-' + activeTab._id" @keydown="handleAddressBarKeyDown" @paste="handleAdressBarPaste" :env-variables="activeTabEnvironmentResolved" />
</div>
<button @click="sendRequest">Send</button>
</div>
Expand Down Expand Up @@ -334,6 +334,9 @@ export default {
activeWorkspace() {
return this.$store.state.activeWorkspace
},
activeTabEnvironmentResolved() {
return this.$store.state.activeTabEnvironmentResolved
},
},
watch: {
activeTab() {
Expand Down
2 changes: 2 additions & 0 deletions packages/ui/src/components/modals/EnvironmentModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,8 @@ export default {
if(this.workspace) {
this.$store.commit('updateWorkspaceEnvironments', { workspaceId: this.workspace._id, environments: this.environments })
}
this.$store.dispatch('updateActiveTabEnvironmentResolved')
},
saveCurrentEnvironment() {
if(this.collectionItem) {
Expand Down
2 changes: 1 addition & 1 deletion packages/ui/src/components/modals/GenerateCodeModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<label v-if="selectedLanguage" style="margin-top: 1rem;">
<div style="font-weight: 500; margin-bottom: 0.25rem;">Select Client</div>
<select v-model="selectedClient" @change="selectedClientChanged" class="full-width-input">
<option value="" disabled >Select client</option>
<option value="" disabled>Select client</option>
<option v-for="client in selectedLanguageClients" :value="client.key">{{ client.title }}</option>
</select>
</label>
Expand Down
5 changes: 5 additions & 0 deletions packages/ui/src/store.js
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ const store = createStore({
},
openContextMenuElement: null,
sockets: {},
activeTabEnvironmentResolved: {},
}
},
getters: {
Expand Down Expand Up @@ -798,6 +799,10 @@ const store = createStore({
const flattenedCollectionTree = JSON.parse(JSON.stringify(flattenTree(collectionTree)))
await createCollections(flattenedCollectionTree)
context.commit('setCollection', await getCollectionForWorkspace(context.state.activeWorkspace._id))
},
async updateActiveTabEnvironmentResolved(context) {
const { environment } = await context.dispatch('getEnvironmentForRequest', context.state.activeTab)
context.state.activeTabEnvironmentResolved = environment
}
}
})
Expand Down
8 changes: 8 additions & 0 deletions packages/ui/src/styles/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ html {
--socket-button-background-color: cadetblue;
--socket-input-disabled-background-color: #fafbfd;
--socket-green-row-background-color: #ddffb6;
--valid-env-highlight-color: #2e7d32;
--valid-env-highlight-background-color: #e8f5e9;
--invalid-env-highlight-color: #d32f2f;
--invalid-env-highlight-background-color: #ffebee;
}

html.theme-dark {
Expand Down Expand Up @@ -119,6 +123,10 @@ html.theme-dark {
--socket-button-background-color: #2c3f40;
--socket-input-disabled-background-color: #2d2d2d;
--socket-green-row-background-color: #88ff0017;
--valid-env-highlight-color: #a5d6a7;
--valid-env-highlight-background-color: #1b5e20;
--invalid-env-highlight-color: #ffcccb;
--invalid-env-highlight-background-color: #7c0404;
}

* {
Expand Down

0 comments on commit bbe93b9

Please sign in to comment.