Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <template>
- <v-container fluid class="my-1">
- <Navbar />
- <Breadcrumbs />
- <v-snackbar transition="true" timeout="3000" v-model="alert" absolute top :color="`${alertColor}`" text outlined right>
- <strong>
- {{ alertMessage }}
- </strong>
- </v-snackbar>
- <v-row>
- <v-col cols="12">
- <v-card elevation="2">
- <PanelHeader
- type="create"
- icon="qr_code"
- title="Campaigns"
- :subTitle="`Fill in details to create a ${type.toLowerCase()} campaign`"
- />
- <!-- removeRule -->
- <v-dialog v-model="showDeleteRuleModal" width="500px" class="d-flex justify-center">
- <v-card style="padding: 30px">
- <v-card-title class="red--text text--lighten-1 d-flex justify-center"> Delete </v-card-title>
- <v-card-text class="text-center"
- >Are you sure you want to delete <strong> {{ currentRuleName }} </strong> ?</v-card-text
- >
- <v-card-actions class="d-flex justify-center">
- <v-btn small outlined color="darken-3 white--text" @click="showDeleteRuleModal = false" class="mx-2">No</v-btn>
- <v-btn small outlined @click="removeRule(currentIndex)" class="mx-2 red--text">Yes</v-btn>
- </v-card-actions>
- </v-card>
- </v-dialog>
- <!-- removeRule -->
- <v-stepper v-model="e1" justify="center" elevation="0">
- <v-stepper-header>
- <v-stepper-step :complete="e1 > 1" step="1"> Campaign </v-stepper-step>
- <v-divider></v-divider>
- <v-stepper-step :complete="e1 > 2" step="2"> Setup </v-stepper-step>
- <v-divider></v-divider>
- <v-stepper-step step="3"> Finish </v-stepper-step>
- </v-stepper-header>
- <v-stepper-items>
- <v-stepper-content step="1">
- <v-card class="mb-12 py-5" elevation="0">
- <v-form ref="form" lazy-validation v-model="valid" id="form">
- <v-row class="mb-6">
- <v-col md="6">
- <v-card outlined tile class="selection product" @click="selectCampaign('Product')">
- <v-row>
- <v-col md="1">
- <v-btn class="ml-2 mt-3" fab icon x-large height="60px" right width="60px">
- <v-icon>qr_code_scanner</v-icon>
- </v-btn>
- </v-col>
- <v-col md="10">
- <v-card-title outlined tile>Product</v-card-title>
- <v-card-subtitle outlined tile>
- Create campaigns for products with existing QR Codes.
- </v-card-subtitle>
- </v-col>
- </v-row>
- </v-card>
- </v-col>
- <v-col md="6">
- <v-card outlined tile class="selection marketing" @click="selectCampaign('Marketing')">
- <v-row>
- <v-col md="1">
- <v-btn class="ml-2 mt-3" fab icon x-large height="60px" right width="60px">
- <v-icon>qr_code_2</v-icon>
- </v-btn>
- </v-col>
- <v-col md="10">
- <v-card-title outlined tile>Marketing</v-card-title>
- <v-card-subtitle outlined tile>
- Create campaigns and download QR Codes for marketing materials.
- </v-card-subtitle>
- </v-col>
- </v-row>
- </v-card>
- </v-col>
- </v-row>
- <v-btn color="primary" :disabled="!typeSelected" @click="validate()"> Continue </v-btn>
- <router-link :to="`/campaigns`">
- <v-btn text> Cancel </v-btn>
- </router-link>
- </v-form>
- </v-card>
- </v-stepper-content>
- <v-stepper-content step="2">
- <v-card class="mb-12 py-5" elevation="0">
- <v-form ref="form" lazy-validation v-model="valid" id="form2">
- <v-row>
- <!-- LEFT -->
- <v-col md="3">
- <!-- ROW 1 -->
- <v-row>
- <v-col md="12">
- <v-text-field
- class="type-input"
- dense
- outlined
- v-model="type"
- label="Type"
- disabled
- ></v-text-field>
- </v-col>
- </v-row>
- <!-- ROW 2 -->
- <v-row>
- <v-col md="12">
- <v-text-field
- dense
- outlined
- v-model="name"
- :rules="form.rules.name"
- label="Name"
- required
- ></v-text-field>
- </v-col>
- <v-col md="12">
- <v-textarea rows="1" dense outlined v-model="description" label="Description"></v-textarea>
- </v-col>
- </v-row>
- </v-col>
- <!-- col#2 -->
- <v-col md="3" v-if="type == 'Marketing'">
- <v-row>
- <v-col md="12">
- <v-select
- v-if="type == 'Marketing'"
- dense
- outlined
- item-text="name"
- item-value="id"
- :items="usages"
- v-model="useType"
- :rules="form.rules.useType"
- label="Use Type"
- deletable-chips
- ></v-select>
- </v-col>
- <v-col md="12">
- <v-select
- v-if="type == 'Marketing'"
- dense
- outlined
- item-text="name"
- item-value="id"
- :items="frequencies"
- v-model="frequency"
- :rules="form.rules.frequency"
- label="Frequency"
- hint="How often the QR code will be available"
- ></v-select>
- </v-col>
- <v-col md="12">
- <v-text-field
- dense
- outlined
- v-model="volume"
- :rules="form.rules.volume"
- label="Volume"
- hint="Total volume of consumers that could interact with QR Code"
- ></v-text-field>
- </v-col>
- </v-row>
- </v-col>
- <!-- col#3 -->
- <v-col md="3">
- <v-row>
- <v-col md="12">
- <v-select
- dense
- outlined
- :items="timezones"
- v-model="timezone"
- :rules="form.rules.timezone"
- label="Timezone"
- ></v-select>
- </v-col>
- <v-col md="6">
- <v-menu
- v-model="startDateMenu"
- :close-on-content-click="false"
- :nudge-right="40"
- transition="scale-transition"
- offset-y
- min-width="auto"
- >
- <template v-slot:activator="{ on, attrs }">
- <v-text-field
- dense
- outlined
- v-model="startDate"
- :rules="form.rules.startDate"
- label="Start Date"
- append-icon="mdi-calendar"
- readonly
- v-bind="attrs"
- v-on="on"
- ></v-text-field>
- </template>
- <v-date-picker v-model="startDate"></v-date-picker>
- </v-menu>
- </v-col>
- <v-col md="6">
- <v-menu
- ref="menu"
- v-model="startTimeMenu"
- :close-on-content-click="false"
- :nudge-right="40"
- transition="scale-transition"
- offset-y
- max-width="290px"
- min-width="290px"
- >
- <template v-slot:activator="{ on, attrs }">
- <v-text-field
- dense
- v-model="startTime"
- label="Start Time"
- append-icon="mdi-clock-time-four-outline"
- readonly
- v-bind="attrs"
- v-on="on"
- outlined
- ></v-text-field>
- </template>
- <v-time-picker
- use-seconds
- v-if="startTimeMenu"
- v-model="startTime"
- full-width
- @click:minute="$refs.menu.save(startTime)"
- ></v-time-picker>
- </v-menu>
- </v-col>
- <v-col md="6">
- <v-menu
- v-model="endDateMenu"
- :close-on-content-click="false"
- :nudge-right="40"
- transition="scale-transition"
- offset-y
- min-width="auto"
- >
- <template v-slot:activator="{ on, attrs }">
- <v-text-field
- dense
- outlined
- v-model="endDate"
- :rules="form.rules.endDate"
- :min="startDate"
- label="End Date"
- append-icon="mdi-calendar"
- readonly
- v-bind="attrs"
- v-on="on"
- ></v-text-field>
- </template>
- <v-date-picker v-model="endDate"></v-date-picker>
- </v-menu>
- </v-col>
- <v-col md="6">
- <v-menu
- ref="menu"
- v-model="endTimeMenu"
- :close-on-content-click="false"
- :nudge-right="40"
- transition="scale-transition"
- offset-y
- max-width="290px"
- min-width="290px"
- >
- <template v-slot:activator="{ on, attrs }">
- <v-text-field
- dense
- v-model="endTime"
- label="End Time"
- append-icon="mdi-clock-time-four-outline"
- readonly
- v-bind="attrs"
- v-on="on"
- outlined
- ></v-text-field>
- </template>
- <v-time-picker
- v-if="endTimeMenu"
- v-model="endTime"
- :min="startTime"
- use-seconds
- full-width
- ></v-time-picker>
- </v-menu>
- </v-col>
- </v-row>
- </v-col>
- <!-- RIGHT -->
- <v-col md="2">
- <img width="100%" :src="qrCode" />
- </v-col>
- </v-row>
- </v-form>
- </v-card>
- <v-card class="mb-12 py-5" elevation="0">
- <v-form ref="form2" lazy-validation v-model="valid2" id="form2">
- <!-- ----------------
- /// showAddRuleModal
- ---------------- -->
- <v-dialog v-model="showAddRule" width="1200px" class="d-flex justify-left">
- <v-card style="padding: 30px">
- <v-form ref="form3" lazy-validation v-model="valid3" id="form3">
- <h3>Create Rule</h3>
- <small class="text--disabled">Fill in details to create a rule</small>
- <v-row class="mt-15">
- <v-col md="12">
- <v-text-field
- dense
- outlined
- v-model="ruleName"
- :rules="form.rules.name"
- label="Rule Name"
- required
- ></v-text-field>
- </v-col>
- <v-card-text class="font-weight-bold">
- Destination
- <v-tooltip right>
- <template v-slot:activator="{ on, attrs }">
- <v-btn icon v-bind="attrs" v-on="on">
- <v-icon color="grey lighten-1">info</v-icon>
- </v-btn>
- </template>
- <span
- >The scan destination is the end point for a consumer experience. Can be single
- URL or use URL Groups.
- </span>
- </v-tooltip>
- </v-card-text>
- <v-col md="4">
- <v-select
- dense
- outlined
- :items="urlTypes"
- label="Single or Multi URL"
- v-model="urlType"
- :rules="form.rules.urlType"
- v-on:change="changeType(urlType)"
- ></v-select>
- </v-col>
- <v-col md="8" v-if="urlType == 'Single'">
- <v-text-field
- dense
- outlined
- v-model="url"
- :rules="form.rules.url"
- label="URL"
- required
- ></v-text-field>
- </v-col>
- <v-col md="8" v-if="urlType == 'Multi'">
- <v-combobox
- v-model="urlGroup.name"
- :items="urlGroups"
- item-text="name"
- item-value="id"
- label="URL Group"
- outlined
- dense
- v-on:change="changeURLGroup(urlGroup.name)"
- ></v-combobox>
- </v-col>
- </v-row>
- <v-row>
- <v-col md="4">
- <v-card-text class="font-weight-bold">
- Conditions
- <v-tooltip right>
- <template v-slot:activator="{ on, attrs }">
- <v-btn icon v-bind="attrs" v-on="on">
- <v-icon color="grey lighten-1">info</v-icon>
- </v-btn>
- </template>
- <span
- >The scan destination is the end point for a consumer experience. Can be
- single URL or use URL Groups.
- </span>
- </v-tooltip>
- <v-btn outlined class="blue--text" @click="addRuleDetail()">
- <v-icon dark> add </v-icon>
- Condition
- </v-btn>
- </v-card-text>
- </v-col>
- <v-col md="8">
- <v-combobox
- v-model="selectedCategories"
- :items="attributeCategories"
- item-text="name"
- item-value="id"
- label="Category"
- multiple
- chips
- clear-icon="mdi-close-circle"
- deletable-chips
- v-on:blur="changeCategory(selectedCategories)"
- ></v-combobox>
- </v-col>
- </v-row>
- <v-row v-for="(rule, index) in ruleDetails" :key="index">
- <v-col md="4">
- <v-select
- dense
- outlined
- item-text="name"
- item-value="id"
- label="Attribute"
- :items="attributes"
- v-model="rule.attribute_id"
- v-on:change="changeAttribute(index, rule.attribute_id)"
- ></v-select>
- </v-col>
- <v-col md="3">
- <v-select
- outlined
- dense
- item-text="name"
- item-value="id"
- label="Operator"
- v-model="rule.operator_id"
- :items="operators[index]"
- v-on:change="changeOperator(index, rule.attribute_id, rule.operator_id)"
- ></v-select>
- </v-col>
- <v-col md="4">
- <!-- ---------
- /// Add Value
- --------- -->
- <v-row v-if="locationAttributeIds.includes(rule.attribute_id)">
- <v-col md="3">
- <v-combobox
- v-model="radius"
- :items="radiuses"
- label="Radius"
- dense
- outlined
- ></v-combobox>
- </v-col>
- <v-col md="9">
- <v-combobox
- :items="cities"
- item-text="name"
- item-value="name"
- v-model="rule.value"
- :label="`City (${cities.length})`"
- dense
- outlined
- append-outer-icon="delete"
- @click:append-outer="removeRuleDetail(index)"
- v-on:change="getCities(rule.value)"
- ></v-combobox>
- </v-col>
- </v-row>
- <v-row>
- <v-col md="3" v-if="weatherAttributeIds.includes(rule.attribute_id)">
- <v-combobox v-model="day" :items="days" label="Day" dense outlined></v-combobox>
- </v-col>
- <v-col md="9">
- <v-menu
- v-if="
- inputTypes[index] == 'Date Range' &&
- !locationAttributeIds.includes(rule.attribute_id)
- "
- :close-on-content-click="false"
- :nudge-right="40"
- transition="scale-transition"
- offset-y
- min-width="auto"
- >
- <template v-slot:activator="{ on, attrs }">
- <v-text-field
- dense
- outlined
- v-model="rule.value"
- label="Values"
- append-icon="mdi-calendar"
- readonly
- v-bind="attrs"
- v-on="on"
- ></v-text-field>
- </template>
- <v-date-picker range v-model="rule.value"></v-date-picker>
- </v-menu>
- <v-menu
- v-if="
- inputTypes[index] == 'Date Picker' &&
- !locationAttributeIds.includes(rule.attribute_id)
- "
- :close-on-content-click="false"
- :nudge-right="40"
- transition="scale-transition"
- offset-y
- min-width="auto"
- >
- <template v-slot:activator="{ on, attrs }">
- <v-text-field
- dense
- outlined
- v-model="rule.value"
- label="Values"
- append-icon="mdi-calendar"
- readonly
- v-bind="attrs"
- v-on="on"
- ></v-text-field>
- </template>
- <v-date-picker v-model="rule.value"></v-date-picker>
- </v-menu>
- <v-select
- v-if="
- inputTypes[index] == 'Single Select' &&
- !locationAttributeIds.includes(rule.attribute_id)
- "
- outlined
- dense
- item-text="name"
- item-value="value"
- label="Values"
- v-model="rule.value"
- :items="values[index]"
- @click:append-outer="removeRuleDetail(index)"
- append-outer-icon="delete"
- ></v-select>
- <v-combobox
- v-if="
- inputTypes[index] == 'Multi Select' &&
- !locationAttributeIds.includes(rule.attribute_id)
- "
- multiple
- outlined
- dense
- item-text="name"
- item-value="value"
- label="Values"
- v-model="rule.value"
- :items="values[index]"
- @click:append-outer="removeRuleDetail(index)"
- append-outer-icon="delete"
- ></v-combobox>
- <v-text-field
- v-if="
- inputTypes[index] == 'Text' &&
- !locationAttributeIds.includes(rule.attribute_id)
- "
- dense
- outlined
- required
- clearable
- v-model="rule.value"
- :rules="form.rules.value"
- label="Values"
- clear-icon="mdi-close-circle"
- append-outer-icon="delete"
- @click:append-outer="removeRuleDetail(index)"
- ></v-text-field>
- <v-text-field
- v-if="
- inputTypes[index] == 'Init' &&
- !locationAttributeIds.includes(rule.attribute_id)
- "
- disabled
- dense
- outlined
- required
- clearable
- v-model="rule.value"
- :rules="form.rules.value"
- label="Values"
- clear-icon="mdi-close-circle"
- append-outer-icon="delete"
- @click:append-outer="removeRuleDetail(index)"
- ></v-text-field>
- </v-col>
- </v-row>
- </v-col>
- </v-row>
- <v-card-actions style="padding: 0px" class="mt-10">
- <v-btn @click="storeRule()" class="success white--text">Save</v-btn>
- <v-btn text color="darken-3 white--text" @click="showAddRule = false">Cancel</v-btn>
- </v-card-actions>
- </v-form>
- </v-card>
- </v-dialog>
- <!-- /showAddRuleModal -->
- <!-- showEditRuleModal -->
- <v-dialog v-model="showEditRule" width="1200px" class="d-flex justify-left">
- <v-card style="padding: 30px">
- <v-form ref="form3" lazy-validation v-model="valid3" id="form3">
- <h3>Edit Rule</h3>
- <small class="text--disabled">Fill in details to edit this rule</small>
- <v-row class="mt-15">
- <v-col md="12">
- <v-text-field
- dense
- outlined
- v-model="selectedRuleName"
- :rules="form.rules.name"
- label="Rule Name"
- required
- ></v-text-field>
- </v-col>
- <v-card-text class="font-weight-bold">
- Destination
- <v-tooltip right>
- <template v-slot:activator="{ on, attrs }">
- <v-btn icon v-bind="attrs" v-on="on">
- <v-icon color="grey lighten-1">info</v-icon>
- </v-btn>
- </template>
- <span
- >The scan destination is the end point for a consumer experience. Can be single
- URL or use URL Groups.
- </span>
- </v-tooltip>
- </v-card-text>
- <v-col md="4">
- <v-select
- dense
- outlined
- :items="urlTypes"
- label="Single or Multi URL"
- v-model="selectedRuleUrlType"
- :rules="form.rules.urlType"
- v-on:change="changeType(selectedRuleUrlType)"
- ></v-select>
- </v-col>
- <v-col md="8" v-if="selectedRuleUrlType == 'Single'">
- <v-text-field
- dense
- outlined
- v-model="selectedRuleUrl"
- :rules="form.rules.url"
- label="URL"
- required
- ></v-text-field>
- </v-col>
- <v-col md="8" v-if="selectedRuleUrlType == 'Multi'">
- <v-combobox
- v-model="selectedRuleUrlGroupName"
- :items="urlGroups"
- item-text="name"
- item-value="id"
- label="URL Group"
- outlined
- dense
- v-on:change="changeURLGroup(selectedRuleUrlGroupName)"
- ></v-combobox>
- </v-col>
- </v-row>
- <v-row>
- <v-col md="4">
- <v-card-text class="font-weight-bold">
- Conditions
- <v-tooltip right>
- <template v-slot:activator="{ on, attrs }">
- <v-btn icon v-bind="attrs" v-on="on">
- <v-icon color="grey lighten-1">info</v-icon>
- </v-btn>
- </template>
- <span
- >The scan destination is the end point for a consumer experience. Can be
- single URL or use URL Groups.
- </span>
- </v-tooltip>
- <v-btn outlined class="blue--text" @click="addRuleDetail()">
- <v-icon dark> add </v-icon>
- Condition
- </v-btn>
- </v-card-text>
- </v-col>
- <v-col md="8">
- <v-combobox
- v-model="selectedCategories"
- :items="attributeCategories"
- item-text="name"
- item-value="id"
- label="Category"
- multiple
- chips
- v-on:blur="changeCategory(selectedCategories)"
- ></v-combobox>
- </v-col>
- </v-row>
- <v-row v-for="(rule, index) in selectedRuleConditions" :key="`selectedRuleConditions-${index}`">
- <v-col md="4">
- <v-select
- dense
- outlined
- item-text="name"
- item-value="id"
- label="Attribute"
- :items="attributes"
- v-model="rule.attribute_id"
- v-on:change="changeAttribute(index, rule.attribute_id)"
- ></v-select>
- </v-col>
- <v-col md="3">
- <v-select
- outlined
- dense
- item-text="name"
- item-value="id"
- label="Operator"
- v-model="rule.operator_id"
- :items="operators[index]"
- v-on:change="changeOperator(index, rule.attribute_id, rule.operator_id)"
- ></v-select>
- </v-col>
- <v-col md="4">
- <v-menu
- v-if="inputTypes[index] == 'Date Range'"
- :close-on-content-click="false"
- :nudge-right="40"
- transition="scale-transition"
- offset-y
- min-width="auto"
- >
- <template v-slot:activator="{ on, attrs }">
- <v-text-field
- dense
- outlined
- v-model="rule.value"
- label="Values"
- append-icon="mdi-calendar"
- readonly
- v-bind="attrs"
- v-on="on"
- ></v-text-field>
- </template>
- <v-date-picker range v-model="rule.value"></v-date-picker>
- </v-menu>
- <v-menu
- v-if="inputTypes[index] == 'Date Picker'"
- :close-on-content-click="false"
- :nudge-right="40"
- transition="scale-transition"
- offset-y
- min-width="auto"
- >
- <template v-slot:activator="{ on, attrs }">
- <v-text-field
- dense
- outlined
- v-model="rule.value"
- label="Values"
- append-icon="mdi-calendar"
- readonly
- v-bind="attrs"
- v-on="on"
- ></v-text-field>
- </template>
- <v-date-picker v-model="rule.value"></v-date-picker>
- </v-menu>
- <v-select
- v-if="inputTypes[index] == 'Single Select'"
- outlined
- dense
- item-text="name"
- item-value="value"
- label="Values"
- v-model="rule.value"
- :items="values[index]"
- @click:append-outer="removeRuleDetail(index)"
- append-outer-icon="delete"
- ></v-select>
- <v-combobox
- v-if="inputTypes[index] == 'Multi Select'"
- hint="Maximum of 5 tags"
- multiple
- persistent-hint
- outlined
- dense
- item-text="name"
- item-value="value"
- label="Values"
- v-model="rule.value"
- :items="values[index]"
- @click:append-outer="removeRuleDetail(index)"
- append-outer-icon="delete"
- ></v-combobox>
- <v-text-field
- v-if="inputTypes[index] == 'Text'"
- dense
- outlined
- required
- clearable
- v-model="rule.value"
- :rules="form.rules.value"
- label="Values"
- clear-icon="mdi-close-circle"
- append-outer-icon="delete"
- @click:append-outer="removeRuleDetail(index)"
- ></v-text-field>
- <v-text-field
- v-if="inputTypes[index] == 'Init'"
- disabled
- dense
- outlined
- required
- clearable
- v-model="rule.value"
- :rules="form.rules.value"
- label="Values"
- clear-icon="mdi-close-circle"
- append-outer-icon="delete"
- @click:append-outer="removeRuleDetail(index)"
- ></v-text-field>
- </v-col>
- </v-row>
- <v-row v-for="(rule, index) in newConditions" :key="`newConditions-${index}`">
- <v-col md="4">
- <v-select
- dense
- outlined
- item-text="name"
- item-value="id"
- label="Attribute"
- :items="attributes"
- v-model="rule.attribute_id"
- v-on:change="changeAttribute(index, rule.attribute_id)"
- ></v-select>
- </v-col>
- <v-col md="3">
- <v-select
- outlined
- dense
- item-text="name"
- item-value="id"
- label="Operator"
- v-model="rule.operator_id"
- :items="operators[index]"
- v-on:change="changeOperator(index, rule.attribute_id, rule.operator_id)"
- ></v-select>
- </v-col>
- <v-col md="4">
- <v-menu
- v-if="inputTypes[index] == 'Date Range'"
- :close-on-content-click="false"
- :nudge-right="40"
- transition="scale-transition"
- offset-y
- min-width="auto"
- >
- <template v-slot:activator="{ on, attrs }">
- <v-text-field
- dense
- outlined
- v-model="rule.value"
- label="Values"
- append-icon="mdi-calendar"
- readonly
- v-bind="attrs"
- v-on="on"
- ></v-text-field>
- </template>
- <v-date-picker range v-model="rule.value"></v-date-picker>
- </v-menu>
- <v-menu
- v-if="inputTypes[index] == 'Date Picker'"
- :close-on-content-click="false"
- :nudge-right="40"
- transition="scale-transition"
- offset-y
- min-width="auto"
- >
- <template v-slot:activator="{ on, attrs }">
- <v-text-field
- dense
- outlined
- v-model="rule.value"
- label="Values"
- append-icon="mdi-calendar"
- readonly
- v-bind="attrs"
- v-on="on"
- ></v-text-field>
- </template>
- <v-date-picker v-model="rule.value"></v-date-picker>
- </v-menu>
- <v-select
- v-if="inputTypes[index] == 'Single Select'"
- outlined
- dense
- item-text="name"
- item-value="value"
- label="Values"
- v-model="rule.value"
- :items="values[index]"
- @click:append-outer="removeRuleDetail(index)"
- append-outer-icon="delete"
- ></v-select>
- <v-combobox
- v-if="inputTypes[index] == 'Multi Select'"
- hint="Maximum of 5 tags"
- multiple
- persistent-hint
- outlined
- dense
- item-text="name"
- item-value="value"
- label="Values"
- v-model="rule.value"
- :items="values[index]"
- @click:append-outer="removeRuleDetail(index)"
- append-outer-icon="delete"
- ></v-combobox>
- <v-text-field
- v-if="inputTypes[index] == 'Text'"
- dense
- outlined
- required
- clearable
- v-model="rule.value"
- :rules="form.rules.value"
- label="Values"
- clear-icon="mdi-close-circle"
- append-outer-icon="delete"
- @click:append-outer="removeRuleDetail(index)"
- ></v-text-field>
- <v-text-field
- v-if="inputTypes[index] == 'Init'"
- disabled
- dense
- outlined
- required
- clearable
- v-model="rule.value"
- :rules="form.rules.value"
- label="Values"
- clear-icon="mdi-close-circle"
- append-outer-icon="delete"
- @click:append-outer="removeRuleDetail(index)"
- ></v-text-field>
- </v-col>
- </v-row>
- <v-card-actions style="padding: 0px" class="mt-10">
- <v-btn @click="updateRule(selectedRule)" class="success white--text">Done</v-btn>
- <v-btn text color="darken-3 white--text" @click="showEditRule = false">Cancel</v-btn>
- </v-card-actions>
- </v-form>
- </v-card>
- </v-dialog>
- <!-- /showEditRuleModal -->
- <pre id="debug" v-if="debug == true">{{ rules }}</pre>
- <v-row>
- <v-col cols="12">
- <v-card-text class="font-weight-bold">Rules </v-card-text>
- <!-- RULE TABLE -->
- <v-data-table
- :headers="headers"
- :items="rules"
- :single-expand="singleExpand"
- :expanded.sync="expanded"
- item-key="name"
- show-expand
- class="elevation-0"
- >
- <template v-slot:top>
- <v-toolbar flat>
- <v-spacer></v-spacer>
- <v-btn outlined class="green--text" @click="showAddRuleModal()">
- <v-icon dark> add </v-icon>
- Rule
- </v-btn>
- </v-toolbar>
- </template>
- <template v-slot:expanded-item="{ headers, item }">
- <td :colspan="headers.length">
- <v-row class="py-5">
- <v-col cols="12">
- <v-simple-table class="condition-table">
- <template v-slot:default>
- <thead>
- <tr>
- <th class="text-left">Name</th>
- <th class="text-left">Operator</th>
- <th class="text-left">Value</th>
- </tr>
- </thead>
- <tbody>
- <tr v-for="item in item.details" :key="item.id">
- <td>
- <v-chip class="ma-2" color="blue" label outlined>
- {{ displayAttributeNameBasedOnId(item.attribute_id) }}
- </v-chip>
- </td>
- <td>
- <v-chip class="ma-2" color="blue" label outlined>
- {{ displayOperatorNameBasedOnId(item.operator_id) }}
- </v-chip>
- </td>
- <td>
- <v-chip class="ma-2" color="blue" label outlined>
- {{ item.value }}
- </v-chip>
- </td>
- </tr>
- </tbody>
- </template>
- </v-simple-table>
- </v-col>
- </v-row>
- </td>
- </template>
- <template v-slot:item.rules="{ item }">
- <v-chip class="ma-2" color="amber darken-1" text-color="white">
- {{ item.details.length }}
- </v-chip>
- </template>
- <template v-slot:item.url="{ index, item }">
- {{ displayUrlInfo(index) }}
- </template>
- <template v-slot:item.id="{ index, item }">
- <v-btn small outlined class="orange--text mr-2" @click="showEditRuleModal(index)">
- Edit
- </v-btn>
- <v-btn small outlined class="red--text" @click="displayDeleteRuleModal(index)">
- Delete
- </v-btn>
- </template>
- </v-data-table>
- </v-col>
- </v-row>
- </v-form>
- </v-card>
- <v-btn color="primary" @click="submitRule()" :disabled="!submit"> Save </v-btn>
- <v-btn
- text
- @click="
- e1 = 1
- backBtnClicked()
- "
- >
- Back
- </v-btn>
- </v-stepper-content>
- <v-stepper-content step="3"> </v-stepper-content>
- </v-stepper-items>
- </v-stepper>
- </v-card>
- </v-col>
- </v-row>
- </v-container>
- </template>
- <script>
- import Navbar from '../../../components/Navbar'
- import Breadcrumbs from '../../../components/Breadcrumbs'
- import PanelHeader from '../../../components/PanelHeader'
- import moment, { now } from 'moment-timezone'
- import axios from 'axios'
- export default {
- components: {
- Navbar,
- Breadcrumbs,
- PanelHeader
- },
- beforeMount() {},
- computed: {
- timeZone: function () {
- console.log('timeZone')
- },
- startDateAndStartTime() {
- return this.startDate + 'T' + this.startTime
- },
- endDateAndEndTime() {
- return this.endDate + 'T' + this.endTime
- }
- },
- mounted() {
- this.checkLocalStorage()
- this.initializeValues()
- this.getFrequencies()
- this.getUseTypes()
- },
- data() {
- return {
- debug: false,
- alert: localStorage.getItem('alert'),
- alertColor: localStorage.getItem('alertColor'),
- alertMessage: localStorage.getItem('alertMessage'),
- form: {
- errors: {},
- rules: {
- type: [(v) => !!v || 'Type is required'],
- name: [(v) => !!v || 'Name is required'],
- startDate: [(v) => !!v || 'Start Date is required'],
- endDate: [(v) => !!v || 'End Date is required'],
- timezone: [(v) => !!v || 'Timezone is required'],
- startTime: [(v) => !!v || 'Start Time is required'],
- endTime: [(v) => !!v || 'End Time is required'],
- urlType: [(v) => !!v || 'URL Type is required'],
- url: [(v) => !!v || 'URL is required', (v) => this.isURL(v) || 'URL is not valid'],
- rules: {
- value: [(v) => !!v || 'Value is required']
- }
- }
- },
- headers: [
- { text: 'Priority', value: 'priority', width: '10%' },
- {
- text: 'Name',
- align: 'start',
- sortable: false,
- value: 'name',
- width: '15%'
- },
- { text: 'URL', value: 'url', width: '40%' },
- { text: 'Condition', value: 'rules', width: '10%' },
- { text: 'Actions', value: 'id', width: '20%' },
- { text: '', value: 'data-table-expand', width: '5%' }
- ],
- rules: [],
- name: '',
- description: '',
- type: '',
- template: '',
- timezone: 'America/New_York',
- startDate: new Date(Date.now() - new Date().getTimezoneOffset() * 60000).toISOString().substr(0, 10),
- endDate: new Date(Date.now() - new Date().getTimezoneOffset() * 60000).toISOString().substr(0, 10),
- startTime: '09:00:00',
- endTime: '17:00:00',
- e1: 1,
- valid: false,
- valid2: false,
- valid3: false,
- submit: false,
- typeSelected: false,
- hover: false,
- volume: 0,
- frequencies: [],
- attributeCategories: [],
- frequency: '',
- usages: [],
- useType: '',
- qrCode: '',
- timezones: moment.tz.names(),
- startDateMenu: false,
- endDateMenu: false,
- startTimeMenu: false,
- endTimeMenu: false,
- singleExpand: true,
- expanded: [],
- search: '',
- status: '',
- currentRuleName: '',
- currentIndex: 0,
- statuses: ['Active', 'Disabled'],
- showAddRule: false,
- showEditRule: false,
- showDeleteRuleModal: false,
- urlType: 'Single',
- url: 'https://',
- urlTypes: ['Single', 'Multi'],
- urlGroups: [],
- urlGroup: {},
- ruleDetails: [],
- ruleName: '',
- attributes: [],
- operators: [],
- inputTypes: [],
- values: [],
- selectedRule: 0,
- selectedRuleName: '',
- selectedRuleUrlType: '',
- selectedRuleUrl: '',
- selectedRuleUrlGroup: {},
- selectedRuleUrlGroupName: '',
- selectedRuleUrlGroupId: '',
- selectedRuleConditions: [],
- mode: 'create',
- newConditions: [],
- selectedCategories: [],
- radius: 5,
- radiuses: [5, 10, 15, 25, 50, 100],
- city: '',
- cities: [],
- weatherAttributeIds: [14, 15, 16, 17, 18, 20, 31, 33],
- locationAttributeIds: [34, 35],
- day: '',
- days: ['NOW', 1, 3, 5]
- }
- },
- methods: {
- initializeValues() {
- if (window.location.host == 'localhost:8080') {
- this.name = 'Demo -' + Date.now()
- this.description = 'Demo description' + Date.now()
- this.ruleName = 'One'
- this.url = 'https://www.one.com'
- this.useType = 2
- this.frequency = 5
- this.volume = 999
- }
- },
- backBtnClicked() {
- console.log('backBtnClicked')
- this.type = ''
- this.name = ''
- this.description = ''
- this.typeSelected = false
- this.rules = []
- this.selectedRuleConditions = []
- },
- checkLocalStorage() {
- localStorage.removeItem('alert')
- localStorage.removeItem('alertColor')
- localStorage.removeItem('alertMessage')
- },
- validate() {
- this.e1 = 2
- },
- displayAttributeNameBasedOnId(id) {
- // console.log('displayAttributeNameBasedOnId', id)
- let attribute = this.attributes.filter((item) => {
- return item.id == id
- })
- return attribute[0].name
- },
- displayOperatorNameBasedOnId(id) {
- // console.log('displayOperatorNameBasedOnId', id)
- let operator = this.operators[0].filter((item) => {
- return item.id == id
- })
- return operator[0].name
- },
- showAddRuleModal() {
- this.showAddRule = true
- this.mode = 'create'
- this.getAttributeCategories()
- //reset form values
- this.ruleName = ' '
- this.url = 'https://www.'
- this.urlType = 'Single'
- if (window.location.host == 'localhost:8080') {
- this.ruleName = 'Rule ' + String(Date.now()).substr(-5)
- this.url = 'https://www.' + 'Demo-url-' + Date.now() + '.com'
- }
- },
- addRuleDetail() {
- let condition = {
- attribute_id: '',
- operator_id: '',
- value: ''
- }
- if (this.mode == 'create') {
- this.ruleDetails.push(condition)
- }
- if (this.mode == 'edit') {
- this.newConditions.push(condition)
- }
- this.inputTypes.push('Init')
- },
- removeRuleDetail(index) {
- if (this.ruleDetails.length > 0) {
- this.ruleDetails.splice(index, 1)
- }
- if (this.selectedRuleConditions.length > 0) {
- this.selectedRuleConditions.splice(index, 1)
- }
- if (this.newConditions.length > 0) {
- this.newConditions.splice(index, 1)
- }
- },
- showEditRuleModal(index) {
- this.mode = 'edit'
- this.showEditRule = true
- this.selectedRule = index
- this.selectedRuleName = this.rules[index].name
- this.getAttributeCategories()
- if (this.rules[index].url != null) {
- this.selectedRuleUrlType = 'Single'
- this.selectedRuleUrl = this.rules[index].url
- }
- if (this.rules[index].group_id != null) {
- this.selectedRuleUrlType = 'Multi'
- this.selectedRuleUrlGroupName = this.rules[index].group_name
- this.selectedRuleUrlGroupId = this.rules[index].group_id
- }
- this.selectedRuleConditions = this.rules[index].details
- },
- removeRule(index) {
- console.log('removeRule clicked', index)
- this.alert = true
- this.alertColor = 'success'
- this.alertMessage = this.rules[index].name + ' - deleted !'
- this.rules.splice(index, 1)
- if (this.rules.length == 0) {
- this.submit = false
- }
- this.showDeleteRuleModal = false
- //reset the priority
- this.resetPriority()
- },
- storeRule() {
- this.$refs.form.validate()
- if (this.$refs.form.validate()) {
- let conditions = []
- for (var i = 0; i < this.ruleDetails.length; i++) {
- if (this.ruleDetails[i].attribute_id != '' && this.ruleDetails[i].attribute_id != null) {
- let condition = {
- attribute_id: this.ruleDetails[i].attribute_id,
- operator_id: this.ruleDetails[i].operator_id,
- value: this.ruleDetails[i].value
- }
- if (this.ruleDetails[i].attribute_id == 34) {
- condition.value = this.ruleDetails[i].value.data.latitude + ' ' + this.ruleDetails[i].value.data.longitude
- condition.value_param = this.radius
- condition.value_alias = this.ruleDetails[i].value.data.name
- }
- conditions.push(condition)
- }
- }
- // console.log('conditions', conditions)
- let currentPriority = this.rules.length + 1
- var rule = {}
- rule.name = this.ruleName
- rule.priority = currentPriority
- // console.log('this.userGroup', this.userGroup)
- if (this.urlType == 'Multi') {
- rule.group_id = this.userGroup.id
- rule.group_name = this.userGroup.name
- } else {
- rule.url = this.url
- }
- rule.details = conditions
- this.rules.push(rule)
- if (this.rules.length > 0) {
- this.submit = true
- }
- console.log('rules', this.rules)
- this.showAddRule = false
- this.alert = true
- this.alertColor = 'green'
- this.alertMessage = this.ruleName + ' - created !'
- this.$refs.form3.reset()
- }
- },
- updateRule(index) {
- this.$refs.form.validate()
- if (this.$refs.form.validate()) {
- this.showEditRule = false
- let conditions = []
- for (var i = 0; i < this.selectedRuleConditions.length; i++) {
- let selectedCondition = this.selectedRuleConditions[i]
- if (selectedCondition.attribute_id != '' && selectedCondition.attribute_id != null) {
- let condition = {
- attribute_id: selectedCondition.attribute_id,
- operator_id: selectedCondition.operator_id,
- value: selectedCondition.value
- }
- conditions.push(condition)
- }
- }
- for (var i = 0; i < this.newConditions.length; i++) {
- let selectedCondition = this.newConditions[i]
- if (selectedCondition.attribute_id != '' && selectedCondition.attribute_id != null) {
- let condition = {
- attribute_id: selectedCondition.attribute_id,
- operator_id: selectedCondition.operator_id,
- value: selectedCondition.value
- }
- conditions.push(condition)
- }
- }
- var rule = {}
- rule.name = this.selectedRuleName
- rule.priority = this.rules[index].priority
- if (this.selectedRuleUrlType == 'Multi') {
- rule.group_id = this.selectedRuleUrlGroup.id
- rule.group_name = this.selectedRuleUrlGroup.name
- } else {
- rule.url = this.selectedRuleUrl
- }
- rule.details = conditions
- //remove
- this.rules.splice(index, 1)
- //add new one
- this.rules.push(rule)
- if (this.rules.length > 0) {
- this.submit = true
- }
- this.resetPriority()
- this.showAddRule = false
- this.alert = true
- this.alertColor = 'green'
- this.alertMessage = this.selectedRuleName + ' - created !'
- this.$refs.form3.reset()
- }
- },
- submitRule() {
- if (this.rules.length == 0) {
- this.alert = true
- this.alertColor = 'red'
- this.alertMessage = 'No rule detected'
- return
- }
- let data = {
- name: this.name,
- description: this.description,
- start_date: this.startDateAndStartTime,
- end_date: this.endDateAndEndTime,
- time_zone: this.timezone,
- priority: '1',
- type_id: this.type == 'Product' ? 2 : 1,
- rules: this.rules
- }
- if (this.type == 'Marketing') {
- data.frequency_id = this.frequency
- data.usage_id = this.useType
- data.volume = this.volume
- }
- console.log('data', data)
- let body = {
- $root: 'vc_campaign',
- op: 'create',
- brand: localStorage.getItem('brandCode'),
- campaign: data,
- _SESSION: localStorage.getItem('session')
- }
- axios.defaults.headers['Content-Type'] = 'application/json'
- axios.post(window.MTS_URL, body).then((response) => {
- if (response.data.status == 0) {
- this.campaign = response.data.campaign
- // console.log(this.campaign)
- localStorage.setItem('alert', true)
- localStorage.setItem('alertColor', 'green')
- localStorage.setItem('alertMessage', this.name + ' - created !')
- this.$router.push({
- path: `/campaigns/` + this.campaign.id
- })
- } else {
- console.log('%c ______________________________', 'background: linear-gradient(45deg, red, yellow, blue, green, purple)')
- console.error(response.error)
- // console.error(response.data.failures[0].detail)
- this.alert = true
- this.alertColor = 'red'
- this.alertMessage = response.error.detail
- }
- })
- },
- displayDeleteRuleModal(index) {
- console.log('showDeleteRuleModal', index)
- this.showDeleteRuleModal = true
- this.currentIndex = index
- this.currentRuleName = this.rules[index].name
- },
- changeCategory(category) {
- if (category.length > 0) {
- this.attributes = []
- for (var i = 0; i < category.length; i++) {
- console.log(category[i])
- let vc_attribute_class = {
- $root: 'vc_rule_attribute',
- op: 'read',
- brand: localStorage.getItem('brandCode'),
- selection: {
- filters: [`class_id:${category[i].id}`, `campaign_type_id:${this.campaignTypeId}`]
- },
- _SESSION: localStorage.getItem('session')
- }
- axios.defaults.headers['Content-Type'] = 'application/json'
- axios.post(window.MTS_URL, vc_attribute_class).then((response) => {
- for (var i = 0; i < response.data.rule_attributes.length; i++) {
- this.attributes.push(response.data.rule_attributes[i])
- }
- })
- }
- }
- },
- changeAttribute(index, attributeId) {
- // console.log('changeAttribute run:', index, attributeId)
- let attribute = {
- $root: 'vc_rule_attribute',
- op: 'read',
- brand: localStorage.getItem('brandCode'),
- selection: {
- filters: [`id:${attributeId}`]
- },
- _SESSION: localStorage.getItem('session')
- }
- axios.defaults.headers['Content-Type'] = 'application/json'
- axios.post(window.MTS_URL, attribute).then((response) => {
- this.attribute = response.data.rule_attributes[0]
- axios.defaults.headers['Content-Type'] = 'application/json'
- let data = {
- $root: 'vc_operator',
- op: 'read',
- brand: localStorage.getItem('brandCode'),
- selection: {
- filters: [`data_type_id:${this.attribute.data_type_id}`]
- },
- _SESSION: localStorage.getItem('session')
- }
- axios.post(window.MTS_URL, data).then((response) => {
- // console.log('index', index)
- // console.log('response.data', response.data)
- this.operators.splice(index, 0, response.data.operators)
- })
- })
- // vc_attribute_value
- axios.defaults.headers['Content-Type'] = 'application/json'
- let data = {
- $root: 'vc_attribute_value',
- op: 'read',
- attribute_id: attributeId,
- brand: localStorage.getItem('brandCode'),
- _SESSION: localStorage.getItem('session')
- }
- axios.post(window.MTS_URL, data).then((response) => {
- this.values.splice(index, 0, response.data.values)
- })
- },
- changeOperator(index, attributeId, operatorId) {
- // console.log('changeOperator run:', index, attributeId, operatorId)
- // vc_attribute_value
- axios.defaults.headers['Content-Type'] = 'application/json'
- let data = {
- $root: 'vc_input_type',
- op: 'read',
- attribute_id: attributeId,
- operator_id: operatorId,
- brand: localStorage.getItem('brandCode'),
- _SESSION: localStorage.getItem('session')
- }
- axios.post(window.MTS_URL, data).then((response) => {
- this.inputTypes.splice(index, 0, response.data.types[0].name)
- console.log('%c ------------------ ', 'background: linear-gradient(45deg, red, yellow, blue, green, purple)')
- console.log('inputType = ', response.data.types[0].name)
- })
- },
- getAttributeCategories() {
- let getAttributeCategories = {
- $root: 'vc_attribute_class',
- op: 'read',
- selection: {
- filters: [`campaign_type_id:${this.campaignTypeId}`]
- },
- brand: localStorage.getItem('brandCode'),
- _SESSION: localStorage.getItem('session')
- }
- axios.defaults.headers['Content-Type'] = 'application/json'
- axios.post(window.MTS_URL, getAttributeCategories).then((response) => {
- this.attributeCategories = response.data.classes
- this.selectedCategories = response.data.classes
- var category = response.data.classes
- if (category.length > 0) {
- this.attributes = []
- for (var i = 0; i < category.length; i++) {
- // console.log(category[i])
- let vc_attribute_class = {
- $root: 'vc_rule_attribute',
- op: 'read',
- brand: localStorage.getItem('brandCode'),
- selection: {
- filters: [`class_id:${category[i].id}`, `campaign_type_id:${this.campaignTypeId}`]
- },
- _SESSION: localStorage.getItem('session')
- }
- // vc_attribute_class.selection.filters = [class_id: + category[i].id,campaign_type_id:${this.campaignTypeId}"]
- axios.defaults.headers['Content-Type'] = 'application/json'
- axios.post(window.MTS_URL, vc_attribute_class).then((response) => {
- for (var i = 0; i < response.data.rule_attributes.length; i++) {
- this.attributes.push(response.data.rule_attributes[i])
- }
- })
- }
- }
- })
- },
- getUseTypes() {
- let attributes = {
- $root: 'vc_campaign_usage',
- op: 'read',
- brand: localStorage.getItem('brandCode'),
- _SESSION: localStorage.getItem('session')
- }
- axios.defaults.headers['Content-Type'] = 'application/json'
- axios.post(window.MTS_URL, attributes).then((response) => {
- this.usages = response.data.usages
- })
- },
- getFrequencies() {
- let attributes = {
- $root: 'vc_campaign_frequency',
- op: 'read',
- brand: localStorage.getItem('brandCode'),
- _SESSION: localStorage.getItem('session')
- }
- axios.defaults.headers['Content-Type'] = 'application/json'
- axios.post(window.MTS_URL, attributes).then((response) => {
- this.frequencies = response.data.frequencies
- })
- },
- getCities(city) {
- console.log('%c >>>>>>', 'background: linear-gradient(45deg, red, yellow, blue, green, purple)')
- console.log('city', city)
- console.log('%c >>>>>>', 'background: linear-gradient(45deg, red, yellow, blue, green, purple)')
- let cities = {
- $root: 'vc_attribute_value',
- op: 'read',
- brand: localStorage.getItem('brandCode'),
- _SESSION: localStorage.getItem('session'),
- attribute_id: 34,
- selection: {
- filters: [`name:${city}`]
- }
- }
- axios.defaults.headers['Content-Type'] = 'application/json'
- axios.post(window.MTS_URL, cities).then((response) => {
- this.cities = response.data.values
- console.log('%c 🔥🧨 ', 'background: red; color: white;')
- })
- },
- displayUrlInfo(index) {
- console.log('displayUrlInfo')
- if (this.rules[index].group_name != null) {
- return this.rules[index].group_name
- }
- if (this.rules[index].url != null) {
- return this.rules[index].url
- }
- },
- resetPriority() {
- for (var i = 0; i < this.rules.length; i++) {
- this.rules[i].priority = i + 1
- }
- },
- isURL(str) {
- let url
- try {
- url = new URL(str)
- } catch (_) {
- return false
- }
- return url.protocol === 'http:' || url.protocol === 'https:'
- },
- selectCampaign(type) {
- // console.log('Campaign Type changed')
- // console.log('Campaign Type changed to ' + type)
- this.typeSelected = true
- this.type = type
- if (type == 'Marketing') {
- this.campaignTypeId = 1
- } else {
- this.campaignTypeId = 2
- }
- this.e1 = 2
- },
- changeType(urlType) {
- console.log('urlType changed')
- console.log('urlType changed to ' + urlType)
- this.selectedRuleUrlType = urlType
- if (urlType == 'Multi') {
- let vc_url_group = {
- $root: 'vc_url_group',
- op: 'read',
- brand: localStorage.getItem('brandCode'),
- selection: {
- page: 1,
- per_page: 500,
- sort: 'id'
- },
- _SESSION: localStorage.getItem('session')
- }
- axios.defaults.headers['Content-Type'] = 'application/json'
- axios
- .post(window.MTS_URL, vc_url_group)
- .then((response) => {
- if (response.data.status == 0) {
- this.urlGroups = response.data.groups
- console.log('this.urlGroups', this.urlGroups)
- console.log('urlGroup ' + this.urlGroup)
- } else {
- alert(response.data.statustext)
- reject(response.data.statustext)
- }
- })
- .catch((err) => {
- console.log('Something went wrong: ', err)
- })
- }
- },
- changeURLGroup(selectedUrlRuleGroup) {
- //create
- this.userGroup = selectedUrlRuleGroup
- //update
- this.selectedRuleUrlGroup = selectedUrlRuleGroup
- }
- }
- }
- </script>
- <style scoped>
- #debug {
- top: -200px;
- right: 5px;
- background-color: silver;
- padding: 30px;
- border: black solid 2px;
- }
- .selection:not(.on-hover) {
- opacity: 0.9;
- }
- .selection:hover {
- opacity: 1;
- border: 3px solid #f6c042;
- background-color: #f6c04220;
- }
- .selection.marketing:hover {
- opacity: 1;
- border: 3px solid #26a69a;
- background-color: #26a69a20;
- }
- .selection.product:hover {
- opacity: 1;
- border: 3px solid #e91e63;
- background-color: #e91e6320;
- }
- .v-application--is-ltr .v-expansion-panel-header {
- text-align: left;
- overflow-wrap: anywhere;
- }
- >>> .v-data-table > .v-data-table__wrapper tbody tr.v-data-table__expanded__content {
- box-shadow: none !important;
- }
- >>> v-snack {
- z-index: 1000;
- }
- .condition-table {
- background-color: #e1f5fe70;
- }
- </style>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement