feat: init bulk edit

This commit is contained in:
liyasthomas
2021-08-29 23:26:27 +05:30
parent add358c752
commit d8881ba6a3
4 changed files with 286 additions and 206 deletions

View File

@@ -35,12 +35,14 @@
@apply text-accentContrast; @apply text-accentContrast;
} }
input::placeholder { input::placeholder,
textarea::placeholder {
@apply text-secondaryDark; @apply text-secondaryDark;
@apply opacity-25; @apply opacity-25;
} }
input { input,
textarea {
@apply text-secondaryDark; @apply text-secondaryDark;
@apply font-medium; @apply font-medium;
} }

View File

@@ -28,28 +28,56 @@
v-tippy="{ theme: 'tooltip' }" v-tippy="{ theme: 'tooltip' }"
:title="$t('action.clear_all')" :title="$t('action.clear_all')"
svg="trash-2" svg="trash-2"
:disabled="bulkMode"
@click.native="clearContent" @click.native="clearContent"
/> />
<ButtonSecondary
v-tippy="{ theme: 'tooltip' }"
:title="$t('state.bulk_mode')"
svg="edit"
:class="{ '!text-accent': bulkMode }"
@click.native="bulkMode = !bulkMode"
/>
<ButtonSecondary <ButtonSecondary
v-tippy="{ theme: 'tooltip' }" v-tippy="{ theme: 'tooltip' }"
:title="$t('add.new')" :title="$t('add.new')"
svg="plus" svg="plus"
:disabled="bulkMode"
@click.native="addHeader" @click.native="addHeader"
/> />
</div> </div>
</div> </div>
<div <div v-if="bulkMode" class="flex">
v-for="(header, index) in headers$" <textarea
:key="`header-${index}`" name="bulk-parameters"
class="divide-x divide-dividerLight border-b border-dividerLight flex" class="
> bg-transparent border-b
<SmartAutoComplete border-dividerLight flex
:placeholder="$t('count.header', { count: index + 1 })" flex-1
:source="commonHeaders" py-2
:spellcheck="false" px-4
:value="header.key" whitespace-pre
autofocus resize-y
styles=" overflow-auto
"
rows="10"
:placeholder="$t('state.bulk_mode_placeholder')"
v-focus
></textarea>
</div>
<div v-else>
<div
v-for="(header, index) in headers$"
:key="`header-${index}`"
class="divide-x divide-dividerLight border-b border-dividerLight flex"
>
<SmartAutoComplete
:placeholder="$t('count.header', { count: index + 1 })"
:source="commonHeaders"
:spellcheck="false"
:value="header.key"
autofocus
styles="
bg-transparent bg-transparent
flex flex
flex-1 flex-1
@@ -57,104 +85,113 @@
px-4 px-4
truncate truncate
" "
:class="{ '!flex flex-1': EXPERIMENTAL_URL_BAR_ENABLED }" :class="{ '!flex flex-1': EXPERIMENTAL_URL_BAR_ENABLED }"
@input=" @input="
updateHeader(index, { updateHeader(index, {
key: $event, key: $event,
value: header.value, value: header.value,
active: header.active, active: header.active,
}) })
" "
/> />
<SmartEnvInput <SmartEnvInput
v-if="EXPERIMENTAL_URL_BAR_ENABLED" v-if="EXPERIMENTAL_URL_BAR_ENABLED"
v-model="header.value" v-model="header.value"
:placeholder="$t('count.value', { count: index + 1 })" :placeholder="$t('count.value', { count: index + 1 })"
styles=" styles="
bg-transparent bg-transparent
flex flex
flex-1 flex-1
py-1 py-1
px-4 px-4
" "
@change=" @change="
updateHeader(index, {
key: header.key,
value: $event,
active: header.active,
})
"
/>
<input
v-else
class="bg-transparent flex flex-1 py-2 px-4"
:placeholder="$t('count.value', { count: index + 1 })"
:name="'value' + index"
:value="header.value"
@change="
updateHeader(index, {
key: header.key,
value: $event.target.value,
active: header.active,
})
"
/>
<span>
<ButtonSecondary
v-tippy="{ theme: 'tooltip' }"
:title="
header.hasOwnProperty('active')
? header.active
? $t('action.turn_off')
: $t('action.turn_on')
: $t('action.turn_off')
"
:svg="
header.hasOwnProperty('active')
? header.active
? 'check-circle'
: 'circle'
: 'check-circle'
"
color="green"
@click.native="
updateHeader(index, { updateHeader(index, {
key: header.key, key: header.key,
value: header.value, value: $event,
active: header.hasOwnProperty('active') ? !header.active : false, active: header.active,
}) })
" "
/> />
</span> <input
<span> v-else
<ButtonSecondary class="bg-transparent flex flex-1 py-2 px-4"
v-tippy="{ theme: 'tooltip' }" :placeholder="$t('count.value', { count: index + 1 })"
:title="$t('action.remove')" :name="'value' + index"
svg="trash" :value="header.value"
color="red" @change="
@click.native="deleteHeader(index)" updateHeader(index, {
key: header.key,
value: $event.target.value,
active: header.active,
})
"
/> />
</span> <span>
</div> <ButtonSecondary
<div v-tippy="{ theme: 'tooltip' }"
v-if="headers$.length === 0" :title="
class="flex flex-col text-secondaryLight p-4 items-center justify-center" header.hasOwnProperty('active')
> ? header.active
<span class="text-center pb-4"> ? $t('action.turn_off')
{{ $t("empty.headers") }} : $t('action.turn_on')
</span> : $t('action.turn_off')
<ButtonSecondary "
filled :svg="
:label="$t('add.new')" header.hasOwnProperty('active')
svg="plus" ? header.active
@click.native="addHeader" ? 'check-circle'
/> : 'circle'
: 'check-circle'
"
color="green"
@click.native="
updateHeader(index, {
key: header.key,
value: header.value,
active: header.hasOwnProperty('active')
? !header.active
: false,
})
"
/>
</span>
<span>
<ButtonSecondary
v-tippy="{ theme: 'tooltip' }"
:title="$t('action.remove')"
svg="trash"
color="red"
@click.native="deleteHeader(index)"
/>
</span>
</div>
<div
v-if="headers$.length === 0"
class="
flex flex-col
text-secondaryLight
p-4
items-center
justify-center
"
>
<span class="text-center pb-4">
{{ $t("empty.headers") }}
</span>
<ButtonSecondary
filled
:label="$t('add.new')"
svg="plus"
@click.native="addHeader"
/>
</div>
</div> </div>
</AppSection> </AppSection>
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent } from "@nuxtjs/composition-api" import { defineComponent, ref } from "@nuxtjs/composition-api"
import { import {
restHeaders$, restHeaders$,
addRESTHeader, addRESTHeader,
@@ -169,9 +206,11 @@ import { HoppRESTHeader } from "~/helpers/types/HoppRESTRequest"
export default defineComponent({ export default defineComponent({
setup() { setup() {
const bulkMode = ref(false)
return { return {
headers$: useReadonlyStream(restHeaders$, []), headers$: useReadonlyStream(restHeaders$, []),
EXPERIMENTAL_URL_BAR_ENABLED: useSetting("EXPERIMENTAL_URL_BAR_ENABLED"), EXPERIMENTAL_URL_BAR_ENABLED: useSetting("EXPERIMENTAL_URL_BAR_ENABLED"),
bulkMode,
} }
}, },
data() { data() {

View File

@@ -28,144 +28,179 @@
v-tippy="{ theme: 'tooltip' }" v-tippy="{ theme: 'tooltip' }"
:title="$t('action.clear_all')" :title="$t('action.clear_all')"
svg="trash-2" svg="trash-2"
:disabled="bulkMode"
@click.native="clearContent" @click.native="clearContent"
/> />
<ButtonSecondary
v-tippy="{ theme: 'tooltip' }"
:title="$t('state.bulk_mode')"
svg="edit"
:class="{ '!text-accent': bulkMode }"
@click.native="bulkMode = !bulkMode"
/>
<ButtonSecondary <ButtonSecondary
v-tippy="{ theme: 'tooltip' }" v-tippy="{ theme: 'tooltip' }"
:title="$t('add.new')" :title="$t('add.new')"
svg="plus" svg="plus"
:disabled="bulkMode"
@click.native="addParam" @click.native="addParam"
/> />
</div> </div>
</div> </div>
<div <div v-if="bulkMode" class="flex">
v-for="(param, index) in params$" <textarea
:key="`param-${index}`" name="bulk-parameters"
class="divide-x divide-dividerLight border-b border-dividerLight flex" class="
> bg-transparent
<SmartEnvInput border-b border-dividerLight
v-if="EXPERIMENTAL_URL_BAR_ENABLED" flex flex-1
v-model="param.key" py-2
:placeholder="$t('count.parameter', { count: index + 1 })" px-4
styles=" whitespace-pre
resize-y
overflow-auto
"
rows="10"
:placeholder="$t('state.bulk_mode_placeholder')"
v-focus
></textarea>
</div>
<div v-else>
<div
v-for="(param, index) in params$"
:key="`param-${index}`"
class="divide-x divide-dividerLight border-b border-dividerLight flex"
>
<SmartEnvInput
v-if="EXPERIMENTAL_URL_BAR_ENABLED"
v-model="param.key"
:placeholder="$t('count.parameter', { count: index + 1 })"
styles="
bg-transparent bg-transparent
flex flex
flex-1 flex-1
py-1 py-1
px-4 px-4
" "
@change=" @change="
updateParam(index, {
key: $event,
value: param.value,
active: param.active,
})
"
/>
<input
v-else
class="bg-transparent flex flex-1 py-2 px-4"
:placeholder="$t('count.parameter', { count: index + 1 })"
:name="'param' + index"
:value="param.key"
autofocus
@change="
updateParam(index, {
key: $event.target.value,
value: param.value,
active: param.active,
})
"
/>
<SmartEnvInput
v-if="EXPERIMENTAL_URL_BAR_ENABLED"
v-model="param.value"
:placeholder="$t('count.value', { count: index + 1 })"
styles="
bg-transparent
flex
flex-1
py-1
px-4
"
@change="
updateParam(index, {
key: param.key,
value: $event,
active: param.active,
})
"
/>
<input
v-else
class="bg-transparent flex flex-1 py-2 px-4"
:placeholder="$t('count.value', { count: index + 1 })"
:name="'value' + index"
:value="param.value"
@change="
updateParam(index, {
key: param.key,
value: $event.target.value,
active: param.active,
})
"
/>
<span>
<ButtonSecondary
v-tippy="{ theme: 'tooltip' }"
:title="
param.hasOwnProperty('active')
? param.active
? $t('action.turn_off')
: $t('action.turn_on')
: $t('action.turn_off')
"
:svg="
param.hasOwnProperty('active')
? param.active
? 'check-circle'
: 'circle'
: 'check-circle'
"
color="green"
@click.native="
updateParam(index, { updateParam(index, {
key: param.key, key: $event,
value: param.value, value: param.value,
active: param.hasOwnProperty('active') ? !param.active : false, active: param.active,
}) })
" "
/> />
</span> <input
<span> v-else
<ButtonSecondary class="bg-transparent flex flex-1 py-2 px-4"
v-tippy="{ theme: 'tooltip' }" :placeholder="$t('count.parameter', { count: index + 1 })"
:title="$t('action.remove')" :name="'param' + index"
svg="trash" :value="param.key"
color="red" autofocus
@click.native="deleteParam(index)" @change="
updateParam(index, {
key: $event.target.value,
value: param.value,
active: param.active,
})
"
/> />
</span> <SmartEnvInput
</div> v-if="EXPERIMENTAL_URL_BAR_ENABLED"
<div v-model="param.value"
v-if="params$.length === 0" :placeholder="$t('count.value', { count: index + 1 })"
class="flex flex-col text-secondaryLight p-4 items-center justify-center" styles="
> bg-transparent
<span class="text-center pb-4"> flex
{{ $t("empty.parameters") }} flex-1
</span> py-1
<ButtonSecondary px-4
:label="$t('add.new')" "
svg="plus" @change="
filled updateParam(index, {
@click.native="addParam" key: param.key,
/> value: $event,
active: param.active,
})
"
/>
<input
v-else
class="bg-transparent flex flex-1 py-2 px-4"
:placeholder="$t('count.value', { count: index + 1 })"
:name="'value' + index"
:value="param.value"
@change="
updateParam(index, {
key: param.key,
value: $event.target.value,
active: param.active,
})
"
/>
<span>
<ButtonSecondary
v-tippy="{ theme: 'tooltip' }"
:title="
param.hasOwnProperty('active')
? param.active
? $t('action.turn_off')
: $t('action.turn_on')
: $t('action.turn_off')
"
:svg="
param.hasOwnProperty('active')
? param.active
? 'check-circle'
: 'circle'
: 'check-circle'
"
color="green"
@click.native="
updateParam(index, {
key: param.key,
value: param.value,
active: param.hasOwnProperty('active') ? !param.active : false,
})
"
/>
</span>
<span>
<ButtonSecondary
v-tippy="{ theme: 'tooltip' }"
:title="$t('action.remove')"
svg="trash"
color="red"
@click.native="deleteParam(index)"
/>
</span>
</div>
<div
v-if="params$.length === 0"
class="
flex flex-col
text-secondaryLight
p-4
items-center
justify-center
"
>
<span class="text-center pb-4">
{{ $t("empty.parameters") }}
</span>
<ButtonSecondary
:label="$t('add.new')"
svg="plus"
filled
@click.native="addParam"
/>
</div>
</div> </div>
</AppSection> </AppSection>
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent } from "@nuxtjs/composition-api" import { defineComponent, ref } from "@nuxtjs/composition-api"
import { HoppRESTParam } from "~/helpers/types/HoppRESTRequest" import { HoppRESTParam } from "~/helpers/types/HoppRESTRequest"
import { useReadonlyStream } from "~/helpers/utils/composables" import { useReadonlyStream } from "~/helpers/utils/composables"
import { import {
@@ -179,9 +214,11 @@ import { useSetting } from "~/newstore/settings"
export default defineComponent({ export default defineComponent({
setup() { setup() {
const bulkMode = ref(false)
return { return {
params$: useReadonlyStream(restParams$, []), params$: useReadonlyStream(restParams$, []),
EXPERIMENTAL_URL_BAR_ENABLED: useSetting("EXPERIMENTAL_URL_BAR_ENABLED"), EXPERIMENTAL_URL_BAR_ENABLED: useSetting("EXPERIMENTAL_URL_BAR_ENABLED"),
bulkMode,
} }
}, },
watch: { watch: {

View File

@@ -403,6 +403,8 @@
"url": "URL" "url": "URL"
}, },
"state": { "state": {
"bulk_mode": "Bulk edit",
"bulk_mode_placeholder": "Entries are separated by newline\nKeys and values are separated by :",
"cleared": "Cleared", "cleared": "Cleared",
"connected": "Connected", "connected": "Connected",
"connected_to": "Connected to {name}", "connected_to": "Connected to {name}",