HEX
Server: Microsoft-IIS/8.5
System: Windows NT YDAWBH120 6.3 build 9600 (Windows Server 2012 R2 Standard Edition) AMD64
User: tentjecom_web (0)
PHP: 7.4.14
Disabled: NONE
Upload Files
File: D:/HostingSpaces/SBogers10/shop.komma.nl/resources/js/components/vue/properties/FreeProperties.vue
<template>
    <div>
        <transition name="a-modal">
            <div class="o-modal" v-if="modalOpened">
                <div class="o-modal__content">
                    <h3 class="o-modal__header">{{ trans('KMS::properties').free_properties }}</h3>
                    <div class="o-modal__body">
                        <label class="radio" >
                            <input type="radio" :name="propertyTypeRadioName" value="existing" v-model="propertyType">
                            <span>{{ trans('KMS::properties').choose_existing_properties }}</span>
                        </label>
                        <multiselect
                            :disabled="propertyType !== 'existing'"
                            :values="this.propertiesKeysByIdWithDisplayName()"
                            @change="selectedExistingPropertyKeys = $event"
                            name="existing"
                        />

                        <div class="new-properties">
                            <label class="radio">
                                <input type="radio" :name="propertyTypeRadioName" value="new" v-model="propertyType">
                                <span>{{ newPropertyLabel }}</span>
                            </label>
                            <div class="" v-if="propertyType !== 'existing'">
                                <label v-for="(languageHavingSite, index) in this.languagesHavingSites()">
                                    <span>{{ trans('KMS::properties').name + ' ' + languageHavingSite.iso_2  }}</span>
                                    <input type="text" v-model="newPropertyNames[index]" :list="valuesId">
                                </label>
                            </div>
                        </div>

                        <div class="button-row" :data-create-type="propertyType">
                            <button class="button" v-if="propertyType === 'existing'" type="button" @click="createBasedOnExisting()">{{ trans('KMS::properties').save }}</button>
                            <button class="button" v-if="propertyType !== 'existing'" type="button" @click="createProperty()" :disabled="addPropertyButtonDisabled">{{ trans('KMS::properties').add }}</button>
                            <button class="button  button--subtle" type="button" @click="openModal(false)">{{ trans('KMS::properties').close }}</button>
                        </div>

                    </div>
                </div>
            </div>
        </transition>

        <div class="wrapper">
            <label>{{ trans('KMS::properties').free_properties }}</label>
            <table>
                <tbody>
                    <tr v-for="displayProperty in this.displayPropertiesForPropertizable(this.iso_2, false)" :class="{ 'u-hidden': (displayProperty.state === 4) }" :data-id="displayProperty.id">
                        <td><span :list="keysId">{{ displayProperty.key }}</span></td>
                        <td><input aria-label="property" type="text" :value="displayProperty.value" @input="updatePropertyValue($event, displayProperty)" :list="valuesId" /></td>
                        <td><button class="trash" @click.prevent="remove(displayProperty.id)" title="Delete"></button></td>
                    </tr>
                </tbody>
            </table>
            <button class="button" type="button" @click.prevent="openModal(true)">{{ trans('KMS::properties').add }}</button>
        </div>

        <datalist :id="valuesId">
            <option v-for="valueTranslation in this.valueTranslations()" :value="valueTranslation.name"/>
        </datalist>
        <input type="hidden" :name="attributeKey" ref="real_input" :value="propertiesForPropertizableAsStringyfiedJson(false)">
    </div>
</template>

<style lang="scss" scoped>
    .wrapper {
        margin-top: 16px;
        padding-left: 45px;
    }

    label {
        display: block;
        font-size: .7rem;
        color: #9ba0ae;
        text-transform: uppercase;
        font-weight: 500;
        white-space: nowrap;
        margin: 0;
    }

    table {
        margin-bottom: 8px;
    }

    td {
        &:first-child {
            display: block;
            margin-top: 9px;
            margin-right: 60px;
            font-size: .7rem;
            color: #70778c;
            font-weight: 700;
            text-transform: uppercase;
            white-space: nowrap;
        }
    }

    input[type="text"] {
        min-height: 40px;
        background-color: #fff;
        text-indent: 10px;
        font-size: .7rem;
        z-index: 99999;
        display: block;
        color: #32343a;
        box-sizing: border-box;
        width: 100%;
        max-width: 500px;
        border: 1px solid #d8dae2;
        border-radius: 5px;
        transition: border-color .25s ease-in-out,box-shadow .25s ease-in-out;

        &:focus {
            border-color: #3c8bf5;
            outline: 0;
            box-shadow: inset 0 1px 1px rgba(0,0,0,.075), inset 0 0 12px rgba(120,169,236,.3);
        }

    }

    .button {
        display: inline-block;
        height: 40px;
        padding: 0 40px;
        background-color: #3289ff;
        color: #fff;
        font-size: .7rem;
        font-family: Rubik, sans-serif;
        vertical-align: top;
        border-radius: 4px;
        appearance: none;
        border: none;
        cursor: pointer;
        transition: background-color .3s;

        &:hover {
            background-color: #006cfe;
        }

        &[disabled="disabled"] {
            background-color: #aaaaaa;
            cursor: not-allowed;
        }
    }

    .button--subtle {
        color: #1d2433;
        background-color: #eceef3;

        &:hover {
            background-color: #d5d9e4;
        }
    }

    .button-row {
        display: flex;
        justify-content: space-between;
        margin-top: 16px;
    }

    .new-properties {

    }

    .radio {
        margin-top: 8px;
        margin-bottom: 8px;
    }

</style>

<script>
    import { mapGetters } from "vuex";
    import PropertyService from "../../../services/propertyService";
    import { States } from "./resources/baseResource";
    import Multiselect from "../forms/multiselect";
    import Property from "./resources/property";
    import KeyValueTranslation from "./resources/translation";

    let propertyService = new PropertyService();

    export default {
        components: {
            Multiselect
        },
        props: {
            attributeKey: {
                required: true,
                type: String
            },
            iso_2: {
                required: true,
                type: String
            },
        },
        data: function() {
            return {
                newPropertyNames: [],
                selectedExistingPropertyKeys: [],
                //Add property modal data
                propertyType: 'existing',
                modalOpened: false,
                propertizable_id: null,
                propertizable_type: null,
            }
        },
        methods: {
            updatePropertyValue(event, property) {
                property.value = event.target.value;
                if(property.state !== States.NEW) property.state = States.DIRTY
                this.$store.commit('properties/updateDisplayProperty', property)
            },
            openModal(open) {
                this.newPropertyNames = []; //Clear state
                this.modalOpened = open;
            },
            createBasedOnExisting() {
                const store = this.$store
                this.selectedExistingPropertyKeys.map(existingId => parseInt(existingId)).forEach(existingId => {
                    //Build data to send to the backend, that will create a new property
                    let key = store.state.properties.propertyKeys.find((key) => key.id === existingId)

                    const property = new Property();
                    property.key = key;

                    this.$store.commit('properties/addPropertyToCurrentPropertizableProperties', property);

                    this.newPropertyNames = [];
                    this.openModal(false);
                });
            },
            remove(propertyId) {
                this.$store.commit('properties/remove', [propertyId])
            },
            createProperty() {
                console.log('create new property')

                //Build data to send to the backend, that will create a new property
                const property = new Property();

                const languages = this.languagesHavingSites();
                let languagesHavingSitesCount = languages.length;

                for(let index = 0; index < languagesHavingSitesCount; index++) {
                    if(typeof this.newPropertyNames[index] === 'undefined') break;

                    let translation = new KeyValueTranslation();
                    translation.language.id = languages[index].id
                    translation.language.iso_2 = languages[index].iso_2
                    translation.name = this.newPropertyNames[index];
                    property.key.translations.push(translation);
                }

                this.$store.commit('properties/addPropertyToCurrentPropertizableProperties', property);
                console.log('stored')

                this.newPropertyNames = [];
                this.openModal(false);
            }
        },
        computed: {
            ...mapGetters({
                trans: "g11n/translation/translation",
                languagesHavingSites: "sites/languagesHavingSites",
                propertiesByKeyId: "properties/propertiesByKeyIdWithDisplayName",
                propertiesForPropertizableAsStringyfiedJson: "properties/propertiesForPropertizableAsStringyfiedJson",
                displayPropertiesForPropertizable: "properties/displayPropertiesForPropertizable",
                displayPropertyKeys: "properties/displayPropertyKeys",
                propertyIdsForPropertizable: "properties/propertyIdsForPropertizable",
                propertiesKeysByIdWithDisplayName: "properties/propertiesKeysByIdWithDisplayName",
                valueTranslations: "properties/valueTranslations",
                keyTranslations: "properties/keyTranslations",
            }),
            valuesId: function() {
                return this.attributeKey + '|values'
            },
            keysId: function() {
                return this.attributeKey + '|keys'
            },
            propertyTypeRadioName: function() {
                return this.attributeKey + '|property_type';
            },
            addPropertyButtonDisabled: function() {
                if(!Array.isArray(this.newPropertyNames)) return true;

                const disabledByLengthConditions = (
                    this.newPropertyNames.length === 0 ||
                    this.newPropertyNames.length !== this.languagesHavingSites().length
                )

                const emptyPropertiesCount = this.newPropertyNames.filter((name) => {
                    return name.trim() === '';
                }).length

                return disabledByLengthConditions || emptyPropertiesCount > 0;
            },
            //"Add property modal data
            newPropertyLabel: function() {
                return (this.propertyType === 'existing') ? this.trans('KMS::properties').section.new : this.trans('KMS::properties').name_new;
            },
        },
    };
</script>