Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add multi select #2

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ This [custom element](https://docs.kontent.ai/tutorials/develop-apps/integrate/i
- Editors can...
- Search for products in all languages in the commercetools project
- Select a single product (or one of it's variants)
- Select multiple products (or their variants)
- Optional debug panel for diagnostics

## Demo
Expand Down Expand Up @@ -34,6 +35,7 @@ The JSON parameters required as as follows:
| Name | Type | Description |
| -------- | ------ | ----------- |
| debug | boolean | (Optional) If present and set to true the debug panel will activate when editing a content item. |
| multiSelect | boolean | If set to true, it will be possible to select multiple products. If set to false, it will be possible to only select a single product |
| commercetools | object | This contains all the details required to connect to the [commercetools API](https://docs.commercetools.com/http-api). The values for this object will be derived from an API client that you configure in commercetools with the exception of the `defaultCulture`. When generating the API client, be sure to select the `view_products` and `view_project_settings` scopes. |
| commercetools.defaultCulture | string | Set this to the IETF language tag of the language in commercetools to use by default for search. |
| commercetools.project | string | This is the commercetools project key. |
Expand All @@ -48,6 +50,7 @@ Sample parameters JSON:
```json
{
"debug": true,
"multiSelect": true,
"commercetools": {
"defaultCulture": "en",
"project": "your-project",
Expand All @@ -62,7 +65,7 @@ Sample parameters JSON:

## Values saved

The custom element will store the selected product's information in the following format:
The custom element will store the selected product's information in the following format (In an array):

```json
{
Expand Down
41 changes: 30 additions & 11 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

57 changes: 43 additions & 14 deletions src/components/CommercetoolsSelector.vue
Original file line number Diff line number Diff line change
@@ -1,30 +1,33 @@
<template>
<div class="wrapper">
<ProductSearch
v-if="!value && !element.disabled"
v-if="(!value || value.length == 0 || multiSelect) && !element.disabled"
:commercetoolsClient="commercetoolsClient"
@onProductSelected="save"
:defaultCulture="defaultCulture"
/>
<PreviewValue
v-if="value"
:value="value"
:disabled="element.disabled"
:commercetoolsClient="commercetoolsClient"
@onProductCleared="reset"
/>
<div class="preview" v-if="value">
<PreviewValueList
v-if="value"
:value="value"
:disabled="element.disabled"
:multiSelect="multiSelect"
:commercetoolsClient="commercetoolsClient"
@onProductCleared="reset"
/>
</div>
</div>
</template>

<script>
import commercetoolsClient from "../helpers/commercetoolsClient";
import PreviewValue from "./PreviewValue";
import PreviewValueList from "./PreviewValueList";
import ProductSearch from "./ProductSearch";

export default {
components: {
PreviewValue,
ProductSearch
ProductSearch,
PreviewValueList
},
props: {
element: {
Expand All @@ -50,15 +53,33 @@ export default {
return configAvailable
? this.element.config.commercetools.defaultCulture
: null;
},
multiSelect: function() {
const configAvailable =
this.element && this.element.config && this.element.config.multiSelect;
return configAvailable ? this.element.config.multiSelect : false;
}
},
methods: {
reset: function() {
this.save(null);
reset: function(value) {
let newValue = this.value ? this.value.filter(x => x.id !== value) : [];

this.$emit("update:value", newValue);
},
save: function(value) {
if (this.element && !this.element.disabled) {
this.$emit("update:value", value);
// Allow the same product to be only selected once
if (this.value && this.value.some(x => x.id === value.id)) {
return;
}

const newValue = this.multiSelect
? this.value
? [...this.value, value]
: [value]
: [value];

this.$emit("update:value", newValue);
}
}
},
Expand All @@ -73,4 +94,12 @@ export default {
.wrapper {
margin: 10px;
}

.preview {
width: 100%;
display: flex;
display: -webkit-flex;
justify-content: center;
-webkit-justify-content: center;
}
</style>
61 changes: 31 additions & 30 deletions src/components/PreviewValue.vue
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
<template>
<div class="preview">
<ProductCard
v-if="product"
:product="product"
:variantId="variantId"
:culture="culture"
@onProductCleared="clearProduct"
/>
<div v-else-if="disabled">
No product selected.
</div>
</div>
<ProductCard
v-if="product"
:product="product"
:variantId="variantId"
:culture="culture"
:disabled="disabled"
@onProductCleared="clearProduct"
/>
</template>

<script>
Expand Down Expand Up @@ -56,31 +52,36 @@ export default {
methods: {
getCurrentProduct: async function() {
if (this.value && this.value.id) {
logEvent(`Getting product projection for "${this.value.id}"`);
try {
logEvent(`Getting product projection for "${this.value.id}"`);

const product = await this.commercetoolsClient.getProductByID({
id: this.value.id
});
const product = await this.commercetoolsClient.getProductByID({
id: this.value.id
});

logEvent(`Got product projection for "${this.value.id}"`, product);
logEvent(`Got product projection for "${this.value.id}"`, product);

this.product = product;
this.product = product;
} catch (e) {
logEvent(
`Error while getting product projection for "${this.value.id}"`,
e
);

this.product = {
name: { "en-US": "NOT FOUND" },
variants: [],
masterVariant: {
id: 1,
images: []
}
};
}
}
},
clearProduct() {
this.product = null;
this.$emit("onProductCleared");
this.$emit("onProductCleared", this.value.id);
}
}
};
</script>

<style scoped>
.preview {
width: 100%;
display: flex;
display: -webkit-flex;
justify-content: center;
-webkit-justify-content: center;
}
</style>
Loading