\r\n Refreshes all cached subscription information so that subscriptions will be reloaded from the database and re-cached.\r\n \r\n Used after an update to add/remove/change subscription properties to ensure that cached subscriptions are up to date with changes\r\n
\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n\r\n\r\n\r\n\r\n","\r\nimport { computed, defineComponent, Ref, ref, watch } from 'vue';\r\nimport { useStore as useSubscriptionsStore } from '@/store/subscriptions/subscriptions';\r\n\r\nexport default defineComponent({\r\n props: {\r\n modelValue: {\r\n type: Boolean,\r\n required: true\r\n }\r\n },\r\n setup (props, { emit }) {\r\n const subscriptionsStore = useSubscriptionsStore();\r\n\r\n const isOpen = computed({\r\n get: () => props.modelValue,\r\n set: (v) => emit('update:modelValue', v)\r\n });\r\n\r\n watch(() => props.modelValue, reset);\r\n\r\n const isRefreshingSubscriptions = ref(false);\r\n const refreshSubscriptionsSuccess: Ref = ref(null);\r\n const refreshSubscriptionsSuccessIcon = computed(() => {\r\n if (refreshSubscriptionsSuccess.value === null) {\r\n return [null, null];\r\n }\r\n\r\n return refreshSubscriptionsSuccess.value ? ['mdi-check-circle', 'green'] : ['mdi-alpha-x-circle green', 'red'];\r\n });\r\n\r\n async function refreshCachedSubscriptions () {\r\n isRefreshingSubscriptions.value = true;\r\n\r\n refreshSubscriptionsSuccess.value = await subscriptionsStore.refreshCachedSubscriptions();\r\n\r\n isRefreshingSubscriptions.value = false;\r\n }\r\n\r\n function reset () {\r\n isRefreshingSubscriptions.value = false;\r\n refreshSubscriptionsSuccess.value = null;\r\n }\r\n\r\n function close () {\r\n isOpen.value = false;\r\n }\r\n\r\n return {\r\n isOpen,\r\n refreshCachedSubscriptions,\r\n refreshSubscriptionsSuccess,\r\n refreshSubscriptionsSuccessIcon,\r\n isRefreshingSubscriptions,\r\n close\r\n };\r\n }\r\n});\r\n","import { render } from \"./DiagnosticsDialog.vue?vue&type=template&id=2bc9c79d\"\nimport script from \"./DiagnosticsDialog.vue?vue&type=script&lang=ts\"\nexport * from \"./DiagnosticsDialog.vue?vue&type=script&lang=ts\"\n\nimport \"./DiagnosticsDialog.vue?vue&type=style&index=0&id=2bc9c79d&lang=scss\"\nscript.render = render\n\nexport default script\nimport QDialog from 'quasar/src/components/dialog/QDialog.js';\nimport QCard from 'quasar/src/components/card/QCard.js';\nimport QCardSection from 'quasar/src/components/card/QCardSection.js';\nimport QBtn from 'quasar/src/components/btn/QBtn.js';\nimport QTooltip from 'quasar/src/components/tooltip/QTooltip.js';\nimport QIcon from 'quasar/src/components/icon/QIcon.js';\nimport qInstall from \"../../../node_modules/vue-cli-plugin-quasar/lib/runtime.auto-import.js\";\nqInstall(script, 'components', {QDialog,QCard,QCardSection,QBtn,QTooltip,QIcon});\n","\r\nimport { computed, defineComponent, onMounted, onUnmounted, ref } from 'vue';\r\nimport { QTableColumn } from '@/components/utils/qTable';\r\nimport { useRouter } from 'vue-router';\r\nimport { ISubscriptionListingModel, ISubscriptionService } from '@/store/contracts/subscriptions/subscriptions';\r\nimport { SubscriptionRoutes } from '@/router/routes/subscriptions';\r\nimport { getServiceName } from '@/store/contracts/subscriptions/subscriptionServiceType';\r\nimport useQuasar from 'quasar/src/composables/use-quasar.js';;\r\nimport { useStore as useSubscriptionsStore } from '@/store/subscriptions/subscriptions';\r\nimport { shortDateFormat } from '@/utils/dateUtil';\r\nimport DiagnosticsDialog from '@/components/subscriptions/DiagnosticsDialog.vue';\r\n\r\nexport default defineComponent({\r\n components: {\r\n DiagnosticsDialog\r\n },\r\n async setup () {\r\n const subscriptionsStore = useSubscriptionsStore();\r\n const router = useRouter();\r\n const $q = useQuasar();\r\n\r\n const keysPressed = { m: false };\r\n function onKeyDown (e: KeyboardEvent) {\r\n keysPressed[e.key] = true;\r\n if (keysPressed.m && e.ctrlKey && e.altKey && Object.keys(keysPressed).length === 3) {\r\n toggleDiagnostics();\r\n }\r\n }\r\n onMounted(() => {\r\n window.addEventListener('keydown', (e) => onKeyDown(e));\r\n window.addEventListener('keyup', (e) => delete keysPressed[e.key]);\r\n });\r\n onUnmounted(() => {\r\n window.removeEventListener('keydown', (e) => onKeyDown(e));\r\n window.removeEventListener('keyup', (e) => delete keysPressed[e.key]);\r\n });\r\n\r\n function displayServices (services: ISubscriptionService[]) {\r\n if (services.length === 0) {\r\n return 'None';\r\n }\r\n return services.map(s => getServiceName(s.serviceType)).join(', ');\r\n }\r\n const subscriptions = computed(() => subscriptionsStore.state.subscriptions?.filter(sub => showDisabledSubscriptions.value || subscriptionsStore.isEnabled(sub)));\r\n\r\n const showDisabledSubscriptions = computed({\r\n get: () => subscriptionsStore.state.showDisabled,\r\n set: (value) => subscriptionsStore.setShowDisabled(value)\r\n });\r\n\r\n enum ColumnNames {\r\n label = 'label',\r\n machineId = 'machineId',\r\n services = 'services',\r\n activeDate = 'activeDate',\r\n expiresDate = 'expiresDate',\r\n enabled = 'enabled',\r\n actions = 'actions'\r\n }\r\n\r\n const visibleColumns = computed(() => Object.keys(ColumnNames).filter((c) => showDisabledSubscriptions.value || c !== ColumnNames.enabled));\r\n\r\n const columns: QTableColumn[] = [\r\n {\r\n name: ColumnNames.enabled,\r\n label: 'Enabled',\r\n align: 'left',\r\n field: (row: ISubscriptionListingModel) => subscriptionsStore.isEnabled(row)\r\n },\r\n {\r\n name: ColumnNames.label,\r\n label: 'Label',\r\n align: 'left',\r\n field: (row: ISubscriptionListingModel) => row.label,\r\n sortable: true\r\n },\r\n {\r\n name: ColumnNames.machineId,\r\n label: 'Machine ID',\r\n align: 'left',\r\n field: (row: ISubscriptionListingModel) => row.machineId\r\n },\r\n {\r\n name: ColumnNames.services,\r\n label: 'Services',\r\n align: 'left',\r\n field: (row: ISubscriptionListingModel) => displayServices(row.services)\r\n },\r\n {\r\n name: ColumnNames.activeDate,\r\n label: 'Activation Date',\r\n align: 'left',\r\n field: (row: ISubscriptionListingModel) => shortDateFormat(row.activeDate),\r\n sortable: true,\r\n sort: (a, b) => new Date(a).getTime() - new Date(b).getTime()\r\n },\r\n {\r\n name: ColumnNames.expiresDate,\r\n label: 'Expiration Date',\r\n align: 'left',\r\n field: (row: ISubscriptionListingModel) => shortDateFormat(row.expiresDate),\r\n sortable: true,\r\n sort: (a, b) => new Date(a).getTime() - new Date(b).getTime()\r\n },\r\n {\r\n name: ColumnNames.actions,\r\n label: '',\r\n align: 'left',\r\n field: (row: ISubscriptionListingModel) => row\r\n }\r\n ];\r\n\r\n await subscriptionsStore.loadSubscriptions();\r\n\r\n function viewSubscription (subscription: ISubscriptionListingModel) {\r\n router.push({ name: SubscriptionRoutes.view, params: { subscriptionId: subscription.subscriptionId } });\r\n }\r\n\r\n function generateSubscription () {\r\n router.push({ name: SubscriptionRoutes.generate });\r\n }\r\n\r\n function confirmDisableSubscription (subscription: ISubscriptionListingModel) {\r\n $q.dialog({\r\n title: 'Disable Subscription Confirmation',\r\n message: 'Are you sure you want to disable this subscription?',\r\n cancel: true,\r\n persistent: true\r\n }).onOk(() => {\r\n subscriptionsStore.disableSubscription(subscription.subscriptionId);\r\n });\r\n }\r\n\r\n async function enableSubscription (subscription: ISubscriptionListingModel) {\r\n await subscriptionsStore.enableSubscription(subscription.subscriptionId);\r\n }\r\n\r\n const isDiagnosticsOpen = ref(false);\r\n function toggleDiagnostics () {\r\n isDiagnosticsOpen.value = !isDiagnosticsOpen.value;\r\n }\r\n\r\n return {\r\n columns,\r\n visibleColumns,\r\n subscriptions,\r\n screen: $q.screen,\r\n viewSubscription,\r\n generateSubscription,\r\n isEnabled: subscriptionsStore.isEnabled,\r\n confirmDisableSubscription,\r\n enableSubscription,\r\n showDisabledSubscriptions,\r\n isDiagnosticsOpen\r\n };\r\n }\r\n});\r\n","import { render } from \"./SubscriptionListPage.vue?vue&type=template&id=700b620d\"\nimport script from \"./SubscriptionListPage.vue?vue&type=script&lang=ts\"\nexport * from \"./SubscriptionListPage.vue?vue&type=script&lang=ts\"\n\nimport \"./SubscriptionListPage.vue?vue&type=style&index=0&id=700b620d&lang=scss\"\nscript.render = render\n\nexport default script\nimport QToggle from 'quasar/src/components/toggle/QToggle.js';\nimport QBtn from 'quasar/src/components/btn/QBtn.js';\nimport QTable from 'quasar/src/components/table/QTable.js';\nimport QCheckbox from 'quasar/src/components/checkbox/QCheckbox.js';\nimport qInstall from \"../../../node_modules/vue-cli-plugin-quasar/lib/runtime.auto-import.js\";\nqInstall(script, 'components', {QToggle,QBtn,QTable,QCheckbox});\n","import { ISubscriptionState, ISubscriptionStore, TEnableSubscription, TDisableSubscription, TGenerateNewKey, TLoadSubscription, TSetSubscription, TUpdateActiveExpiresDate, TUpdateLabel, TUpdateNote, TUpdateServices } from '@/store/contracts/subscriptions/subscription';\r\nimport { impl } from '@/utils/impl';\r\nimport { reactive, readonly, provide, inject } from 'vue';\r\nimport { chainHandlers, DefaultIStatusHandler, handleErrorStatus, handleErrorStatusResult, ResponseStatus } from '@/store/utils/apiResponseHandling';\r\nimport { sendRequest } from '@/store/utils/axiosUtils';\r\nimport { Settings } from '@/settings';\r\nimport { store as subscriptionsStore } from '@/store/subscriptions/subscriptions';\r\nimport { IServerSubscriptionResponse, subscriptiontoApp, toServerDate } from '@/store/subscriptions/mapping/subscriptionListingModel';\r\nimport updateLabelValidationModel from '@/validation/updateSubscriptionLabelValidationModel';\r\nimport { store as validationStore } from '@/store/validation';\r\nimport updateActiveExpiresDateValidationModel from '@/validation/updateActiveExpiresDateValidationModel';\r\nimport { SubscriptionUpdateType } from '../contracts/subscriptions/subscriptionUpdateType';\r\n\r\nconst SubscriptionStoreKey = Symbol('SubscriptionStore');\r\n\r\nconst createState = () => reactive(impl({\r\n subscription: null\r\n}));\r\n\r\nfunction setSubscription (state: ISubscriptionState): TSetSubscription {\r\n return (subscription) => {\r\n state.subscription = subscription;\r\n };\r\n}\r\n\r\nfunction loadSubscription (state: ISubscriptionState): TLoadSubscription {\r\n return async (subscriptionId, handler) => {\r\n await handleErrorStatusResult(await sendRequest(\r\n `${Settings.adminApiBaseUrl}/admin/v1/subscription/load`,\r\n 'post',\r\n {\r\n SubscriptionId: subscriptionId\r\n }\r\n ), chainHandlers({\r\n onSuccess: async (s) => setSubscription(state)(subscriptiontoApp(s))\r\n }, handler));\r\n };\r\n}\r\n\r\nfunction generateNewKey (state: ISubscriptionState): TGenerateNewKey {\r\n return async (handler) => {\r\n if (state.subscription !== null) {\r\n await handleErrorStatusResult(await sendRequest(\r\n `${Settings.adminApiBaseUrl}/admin/v1/subscription/newKey`,\r\n 'post',\r\n {\r\n SubscriptionId: state.subscription.subscriptionId\r\n }\r\n ), chainHandlers({\r\n onSuccess: async () => loadSubscription(state)(state.subscription!.subscriptionId)\r\n }, handler));\r\n }\r\n };\r\n}\r\n\r\nfunction updateNote (state: ISubscriptionState): TUpdateNote {\r\n return async (model, handler) => {\r\n if (state.subscription !== null) {\r\n await handleErrorStatus(await sendRequest(\r\n `${Settings.adminApiBaseUrl}/admin/v1/subscription/update`,\r\n 'post',\r\n {\r\n $type: SubscriptionUpdateType.UpdateSubscriptionNotes,\r\n SubscriptionId: state.subscription.subscriptionId,\r\n Note: model.note\r\n }\r\n ), chainHandlers({\r\n onSuccess: async () => loadSubscription(state)(state.subscription!.subscriptionId),\r\n onError: async (r) => {\r\n await DefaultIStatusHandler.onError(r);\r\n }\r\n }, handler));\r\n }\r\n };\r\n}\r\n\r\nfunction updateLabel (state: ISubscriptionState): TUpdateLabel {\r\n return async (model, handler) => {\r\n if (state.subscription !== null) {\r\n const isValid = await validationStore.doValidation({\r\n model: updateLabelValidationModel,\r\n value: model\r\n });\r\n if (isValid) {\r\n await handleErrorStatus(await sendRequest(\r\n `${Settings.adminApiBaseUrl}/admin/v1/subscription/update`,\r\n 'post',\r\n {\r\n $type: SubscriptionUpdateType.UpdateSubscriptionLabel,\r\n SubscriptionId: state.subscription.subscriptionId,\r\n Label: model.label\r\n }\r\n ), chainHandlers({\r\n onSuccess: async () => await loadSubscription(state)(state.subscription!.subscriptionId),\r\n onError: async (r) => {\r\n await DefaultIStatusHandler.onError(r);\r\n }\r\n }, handler));\r\n }\r\n }\r\n };\r\n}\r\n\r\nfunction updateActiveExpiresDate (state: ISubscriptionState): TUpdateActiveExpiresDate {\r\n return async (model, handler) => {\r\n if (state.subscription !== null) {\r\n const isValid = await validationStore.doValidation({\r\n model: updateActiveExpiresDateValidationModel,\r\n value: model\r\n });\r\n if (isValid) {\r\n await handleErrorStatus(await sendRequest(\r\n `${Settings.adminApiBaseUrl}/admin/v1/subscription/update`,\r\n 'post',\r\n {\r\n $type: SubscriptionUpdateType.UpdateSubscriptionStatus,\r\n SubscriptionId: state.subscription.subscriptionId,\r\n ...toServerDate(model)\r\n }\r\n ), chainHandlers({\r\n onSuccess: async () => await loadSubscription(state)(state.subscription!.subscriptionId),\r\n onError: async (r) => {\r\n await DefaultIStatusHandler.onError(r);\r\n }\r\n }, handler));\r\n }\r\n }\r\n };\r\n}\r\n\r\nfunction updateServices (state: ISubscriptionState): TUpdateServices {\r\n return async (model, handler) => {\r\n if (state.subscription !== null) {\r\n await handleErrorStatusResult(await sendRequest(\r\n `${Settings.adminApiBaseUrl}/admin/v1/subscription/update`,\r\n 'post',\r\n {\r\n $type: SubscriptionUpdateType.UpdateSubscriptionServices,\r\n SubscriptionId: state.subscription.subscriptionId,\r\n Services: model.Services\r\n }\r\n ), chainHandlers({\r\n onSuccess: async () => loadSubscription(state)(state.subscription!.subscriptionId),\r\n onError: async (r) => {\r\n await DefaultIStatusHandler.onError(r);\r\n }\r\n }, handler));\r\n }\r\n };\r\n}\r\n\r\nfunction enableSubscription (state: ISubscriptionState): TEnableSubscription {\r\n return async (handler) => {\r\n if (state.subscription !== null) {\r\n return await subscriptionsStore.enableSubscription(state.subscription.subscriptionId,\r\n chainHandlers(\r\n {\r\n onSuccess: async () => loadSubscription(state)(state.subscription!.subscriptionId)\r\n }, handler));\r\n }\r\n console.warn(\"Can't enable a subscription when the subscription is null.\");\r\n };\r\n}\r\n\r\nfunction disableSubscription (state: ISubscriptionState): TDisableSubscription {\r\n return async (handler) => {\r\n if (state.subscription !== null) {\r\n return await subscriptionsStore.disableSubscription(state.subscription.subscriptionId,\r\n chainHandlers(\r\n {\r\n onSuccess: async () => loadSubscription(state)(state.subscription!.subscriptionId)\r\n }, handler));\r\n }\r\n console.warn(\"Can't disable a subscription when the subscription is null.\");\r\n };\r\n}\r\n\r\nfunction isEnabled (state: ISubscriptionState): () => boolean {\r\n return () => {\r\n if (state.subscription === null) {\r\n return false;\r\n }\r\n\r\n return subscriptionsStore.isEnabled(state.subscription);\r\n };\r\n}\r\n\r\nconst createForState = (state: ISubscriptionState) => impl({\r\n state: readonly(state),\r\n setSubscription: setSubscription(state),\r\n loadSubscription: loadSubscription(state),\r\n enableSubscription: enableSubscription(state),\r\n disableSubscription: disableSubscription(state),\r\n generateNewKey: generateNewKey(state),\r\n updateNote: updateNote(state),\r\n updateServices: updateServices(state),\r\n updateLabel: updateLabel(state),\r\n updateActiveExpiresDate: updateActiveExpiresDate(state),\r\n get isEnabled (): boolean {\r\n return isEnabled(state)();\r\n }\r\n});\r\n\r\nexport function provideStore (): ISubscriptionStore {\r\n const state = createState();\r\n provide(SubscriptionStoreKey, state);\r\n return createForState(state);\r\n}\r\n\r\nexport function useStore (): ISubscriptionStore {\r\n const state = inject(SubscriptionStoreKey);\r\n if (state === undefined) {\r\n throw new Error('Using SubscriptionStore before providing it!');\r\n }\r\n return createForState(state);\r\n}\r\n","// extracted by mini-css-extract-plugin\nmodule.exports = {\"Gray50\":\"#fafafa\",\"Gray100\":\"#f2f4f5\",\"Gray200\":\"#ebeff2\",\"Gray300\":\"#dae0e6\",\"Gray400\":\"#bec5cc\",\"Gray500\":\"#a1aab3\",\"Gray600\":\"#8a9299\",\"Gray700\":\"#737980\",\"Gray800\":\"#5c6166\",\"Gray900\":\"#45494d\",\"Navy50\":\"#bde3fc\",\"Navy100\":\"#7ec9fc\",\"Navy200\":\"#3faffc\",\"Navy300\":\"#0095fc\",\"Navy400\":\"#0086e3\",\"Navy500\":\"#0077c9\",\"Navy600\":\"#0068b0\",\"Navy700\":\"#005996\",\"Navy800\":\"#004a7d\",\"Navy900\":\"#002b49\",\"Blue50\":\"#bbeafa\",\"Blue100\":\"#7ddafa\",\"Blue200\":\"#3ecafa\",\"Blue300\":\"#00bbfa\",\"Blue400\":\"#00a8e1\",\"Blue500\":\"#0095c7\",\"Blue600\":\"#0081ad\",\"Blue700\":\"#006e94\",\"Blue800\":\"#005b7a\",\"Blue900\":\"#004861\",\"Red50\":\"#f2b5c1\",\"Red100\":\"#f2798f\",\"Red200\":\"#f23d5e\",\"Red300\":\"#f2002c\",\"Red400\":\"#d90027\",\"Red500\":\"#bf0023\",\"Red600\":\"#a6001e\",\"Red700\":\"#8c001a\",\"Red800\":\"#730015\",\"Red900\":\"#590010\",\"Yellow50\":\"#fcf8bd\",\"Yellow100\":\"#fcf37e\",\"Yellow200\":\"#fcef3f\",\"Yellow300\":\"#fceb00\",\"Yellow400\":\"#e3d400\",\"Yellow500\":\"#c9bc00\",\"White\":\"#fff\",\"Black\":\"#17181a\",\"Orange\":\"#ff8900\",\"Transparent\":\"rgba(255,255,255,0)\"};","export * from \"-!../../../node_modules/mini-css-extract-plugin/dist/loader.js??ref--8-oneOf-1-0!../../../node_modules/css-loader/dist/cjs.js??ref--8-oneOf-1-1!../../../node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/stylePostLoader.js!../../../node_modules/postcss-loader/src/index.js??ref--8-oneOf-1-2!../../../node_modules/sass-loader/dist/cjs.js??ref--8-oneOf-1-3!../../../node_modules/vue-cli-plugin-quasar/lib/loader.vue.auto-import-quasar.js?kebab!../../../node_modules/cache-loader/dist/cjs.js??ref--0-1!../../../node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/index.js??ref--0-2!./EditActiveExpiresDatesDialog.vue?vue&type=style&index=0&id=3429c4f9&lang=scss\"","\r\nexport function hasFlag (flag: T): (flags: T | number) => boolean {\r\n return (flags) => (flags & flag) === flag;\r\n}\r\n\r\n/**\r\n * Get an array of enum values based on the given populated flag value.\r\n * @param possibleValues the enum values\r\n * @param flag the populated flag value\r\n * @returns an array containing the values of the enum that are populated in the flag\r\n */\r\nexport function getFlagValues (possibleValues: E[], flag: number | null): E[] {\r\n if (flag === null) {\r\n return [];\r\n }\r\n return possibleValues.filter(v => hasFlag(v)(flag));\r\n}\r\n\r\nexport function toFlag (values: E[]): number {\r\n return values.reduce((prev, next) => prev | next, 0);\r\n}\r\n","// extracted by mini-css-extract-plugin\nmodule.exports = {\"Gray50\":\"#fafafa\",\"Gray100\":\"#f2f4f5\",\"Gray200\":\"#ebeff2\",\"Gray300\":\"#dae0e6\",\"Gray400\":\"#bec5cc\",\"Gray500\":\"#a1aab3\",\"Gray600\":\"#8a9299\",\"Gray700\":\"#737980\",\"Gray800\":\"#5c6166\",\"Gray900\":\"#45494d\",\"Navy50\":\"#bde3fc\",\"Navy100\":\"#7ec9fc\",\"Navy200\":\"#3faffc\",\"Navy300\":\"#0095fc\",\"Navy400\":\"#0086e3\",\"Navy500\":\"#0077c9\",\"Navy600\":\"#0068b0\",\"Navy700\":\"#005996\",\"Navy800\":\"#004a7d\",\"Navy900\":\"#002b49\",\"Blue50\":\"#bbeafa\",\"Blue100\":\"#7ddafa\",\"Blue200\":\"#3ecafa\",\"Blue300\":\"#00bbfa\",\"Blue400\":\"#00a8e1\",\"Blue500\":\"#0095c7\",\"Blue600\":\"#0081ad\",\"Blue700\":\"#006e94\",\"Blue800\":\"#005b7a\",\"Blue900\":\"#004861\",\"Red50\":\"#f2b5c1\",\"Red100\":\"#f2798f\",\"Red200\":\"#f23d5e\",\"Red300\":\"#f2002c\",\"Red400\":\"#d90027\",\"Red500\":\"#bf0023\",\"Red600\":\"#a6001e\",\"Red700\":\"#8c001a\",\"Red800\":\"#730015\",\"Red900\":\"#590010\",\"Yellow50\":\"#fcf8bd\",\"Yellow100\":\"#fcf37e\",\"Yellow200\":\"#fcef3f\",\"Yellow300\":\"#fceb00\",\"Yellow400\":\"#e3d400\",\"Yellow500\":\"#c9bc00\",\"White\":\"#fff\",\"Black\":\"#17181a\",\"Orange\":\"#ff8900\",\"Transparent\":\"rgba(255,255,255,0)\"};","import { SubscriptionServiceType } from '@/store/contracts/subscriptions/subscriptionServiceType';\r\n\r\nexport function subscriptionServiceTypeGridDisplay (serviceType: SubscriptionServiceType) : string | null {\r\n switch (serviceType) {\r\n case SubscriptionServiceType.None:\r\n return null;\r\n case SubscriptionServiceType.Vision:\r\n return 'Lookups';\r\n case SubscriptionServiceType.Translation:\r\n return 'Characters';\r\n case SubscriptionServiceType.Transcription:\r\n return 'Duration of Audio';\r\n case SubscriptionServiceType.Profile:\r\n return 'Searches';\r\n default:\r\n return '';\r\n }\r\n}\r\n\r\nexport function subscriptionServiceTypeChartDisplay (serviceType: SubscriptionServiceType) : string | null {\r\n switch (serviceType) {\r\n case SubscriptionServiceType.None:\r\n return null;\r\n case SubscriptionServiceType.Vision:\r\n return 'Lookups';\r\n case SubscriptionServiceType.Translation:\r\n return 'Characters';\r\n case SubscriptionServiceType.Transcription:\r\n return 'Hours';\r\n case SubscriptionServiceType.Profile:\r\n return 'Searches';\r\n default:\r\n return '';\r\n }\r\n}\r\n","\r\n \r\n \r\n \r\n
{{ dialogTitle }}
\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n\r\n\r\n\r\n\r\n","import { ISubscriptionServiceModel } from '@/store/contracts/subscriptions/addService';\r\nimport { SubscriptionServiceType } from '@/store/contracts/subscriptions/subscriptionServiceType';\r\nimport { VisionFeaturesFlag } from '@/store/contracts/subscriptions/visionFeaturesFlag';\r\nimport { ValidationModel } from '@/validation';\r\nimport { conditionalRules, getValueRequiredRule, numberRequiredRule } from '@/validation/common/rules';\r\nimport { isAfter, isBefore } from '@/validation/common/dateRules';\r\n\r\nexport enum SubscriptionServiceFieldName {\r\n DailyQuota = 'dailyQuota',\r\n MonthlyQuota = 'monthlyQuota',\r\n ContractStartDate = 'contractStartDate',\r\n ContractEndDate = 'contractEndDate',\r\n ContractQuota = 'contractQuota',\r\n ServiceType = 'serviceType',\r\n FeaturesFlag = 'featuresFlag'\r\n}\r\n\r\nclass SubscriptionServiceValidationModel extends ValidationModel {\r\n constructor () {\r\n super();\r\n\r\n this.setField(SubscriptionServiceFieldName.ContractQuota, {\r\n getter: (model) => model?.contractQuota ?? null,\r\n rules: [\r\n numberRequiredRule('Contract Quota is required.')\r\n ]\r\n });\r\n\r\n this.setField(SubscriptionServiceFieldName.ContractStartDate, {\r\n getter: (model) => model?.contractStartDate ?? null,\r\n rules: [\r\n getValueRequiredRule((value: Date | null) => value !== null)('Contract Start Date is required.'),\r\n isBefore((model) => model?.contractEndDate ?? null, 'Should be before Contract End Date.')\r\n ]\r\n });\r\n\r\n this.setField(SubscriptionServiceFieldName.ContractEndDate, {\r\n getter: (model) => model?.contractEndDate ?? null,\r\n rules: [\r\n getValueRequiredRule((value: Date | null) => value !== null)('Contract End Date is required.'),\r\n isAfter((model) => model?.contractStartDate ?? null, 'Should be after Contract Start Date.')\r\n ]\r\n });\r\n\r\n this.setField(SubscriptionServiceFieldName.ServiceType, {\r\n getter: (model) => model?.serviceType ?? null,\r\n rules: [\r\n getValueRequiredRule((v) => v !== null && v !== SubscriptionServiceType.None)('Service Type is required.'),\r\n async (context) => {\r\n const existingServiceTypes = context.model?.createModel?.services.filter(s => s.index === null || s.index !== context.model?.index).map((s) => s.serviceType) ?? [];\r\n const newServiceType = context.model?.serviceType ?? SubscriptionServiceType.None;\r\n return existingServiceTypes.none((s) => s === newServiceType) || 'Can not have multiple services of the same type';\r\n }\r\n ]\r\n });\r\n\r\n this.setField(SubscriptionServiceFieldName.FeaturesFlag, {\r\n getter: (model) => model?.featuresFlag ?? null,\r\n rules: [\r\n ...conditionalRules(\r\n (ctx) => ctx.model?.serviceType === SubscriptionServiceType.Vision,\r\n [\r\n getValueRequiredRule((f) => f !== null && f !== VisionFeaturesFlag.None)('Features are required.')\r\n ])\r\n ]\r\n });\r\n }\r\n\r\n public get modelName (): string {\r\n return 'SubscriptionService';\r\n }\r\n}\r\n\r\nexport default new SubscriptionServiceValidationModel();\r\n","import { impl } from '@/utils/impl';\r\nimport { inject, provide, reactive, readonly } from 'vue';\r\nimport {\r\n IAddServiceState,\r\n IAddServiceStore,\r\n TSetContractStartDate,\r\n TSetContractEndDate,\r\n TSetContractQuota,\r\n TSetMonthlyQuota,\r\n TSetDailyQuota,\r\n TSetCreateModel,\r\n TSetFeaturesFlag,\r\n TSetTanglesApiKey,\r\n TSetIndex,\r\n TSetModel,\r\n TSetServiceType,\r\n TValidate\r\n} from '@/store/contracts/subscriptions/addService';\r\nimport { store as validationStore } from '@/store/validation';\r\nimport validationModel from '@/validation/subscriptionServiceValidationModel';\r\nimport { SubscriptionServiceType } from '@/store/contracts/subscriptions/subscriptionServiceType';\r\nimport { Settings } from '@/settings';\r\n\r\nconst AddServiceStoreKey = Symbol('AddServiceStore');\r\n\r\nfunction setModel (state: IAddServiceState): TSetModel {\r\n return (model) => {\r\n state.model = model;\r\n };\r\n}\r\n\r\nfunction setContractStartDate (state: IAddServiceState): TSetContractStartDate {\r\n return (contractStartDate) => {\r\n state.model.contractStartDate = contractStartDate;\r\n };\r\n}\r\n\r\nfunction setContractEndDate (state: IAddServiceState): TSetContractEndDate {\r\n return (contractEndDate) => {\r\n state.model.contractEndDate = contractEndDate;\r\n };\r\n}\r\n\r\nfunction setContractQuota (state: IAddServiceState): TSetContractQuota {\r\n return (contractQuota) => {\r\n let val = contractQuota;\r\n if ((typeof contractQuota) === 'string') {\r\n const parsed = Number.parseInt(contractQuota as any);\r\n val = isNaN(parsed) ? null : parsed;\r\n }\r\n state.model.contractQuota = val;\r\n };\r\n}\r\n\r\nfunction setMonthlyQuota (state: IAddServiceState): TSetMonthlyQuota {\r\n return (monthlyQuota) => {\r\n let val = monthlyQuota;\r\n if ((typeof monthlyQuota) === 'string') {\r\n const parsed = Number.parseInt(monthlyQuota as any);\r\n val = isNaN(parsed) ? null : parsed;\r\n }\r\n state.model.monthlyQuota = val;\r\n };\r\n}\r\n\r\nfunction setDailyQuota (state: IAddServiceState): TSetDailyQuota {\r\n return (dailyQuota) => {\r\n let val = dailyQuota;\r\n if ((typeof dailyQuota) === 'string') {\r\n const parsed = Number.parseInt(dailyQuota as any);\r\n val = isNaN(parsed) ? null : parsed;\r\n }\r\n state.model.dailyQuota = val;\r\n };\r\n}\r\n\r\nfunction setServiceType (state: IAddServiceState): TSetServiceType {\r\n return (serviceType) => {\r\n state.model.serviceType = serviceType;\r\n };\r\n}\r\n\r\nfunction setFeaturesFlag (state: IAddServiceState): TSetFeaturesFlag {\r\n return (featuresFlag) => {\r\n state.model.featuresFlag = featuresFlag;\r\n };\r\n}\r\n\r\nfunction setTanglesApiKey (state: IAddServiceState): TSetTanglesApiKey {\r\n return (tanglesApiKey) => {\r\n state.model.tanglesApiKey = tanglesApiKey;\r\n };\r\n}\r\n\r\nfunction setCreateModel (state: IAddServiceState): TSetCreateModel {\r\n return (createModel) => {\r\n state.model.createModel = createModel;\r\n };\r\n}\r\n\r\nfunction setIndex (state: IAddServiceState): TSetIndex {\r\n return (index) => {\r\n state.model.index = index;\r\n };\r\n}\r\n\r\nfunction validate (state: IAddServiceState): TValidate {\r\n return async () => {\r\n return await validationStore.doValidation({\r\n model: validationModel,\r\n value: state.model\r\n });\r\n };\r\n}\r\n\r\nexport function createState (): IAddServiceState {\r\n validationStore.clear(validationModel);\r\n\r\n return reactive(impl({\r\n model: {\r\n contractStartDate: null,\r\n contractEndDate: null,\r\n contractQuota: Settings.defaultContractQuota,\r\n monthlyQuota: Settings.defaultMonthlyQuota,\r\n dailyQuota: Settings.defaultDailyQuota,\r\n serviceType: SubscriptionServiceType.None,\r\n featuresFlag: 1, // coincidentally want to default to Tag's for Vision and Tangles for Profile\r\n tanglesApiKey: null,\r\n createModel: null,\r\n index: null\r\n }\r\n }));\r\n}\r\n\r\nexport function createForState (state: IAddServiceState): IAddServiceStore {\r\n return impl({\r\n state: readonly(state),\r\n setModel: setModel(state),\r\n setContractStartDate: setContractStartDate(state),\r\n setContractEndDate: setContractEndDate(state),\r\n setContractQuota: setContractQuota(state),\r\n setMonthlyQuota: setMonthlyQuota(state),\r\n setDailyQuota: setDailyQuota(state),\r\n setFeaturesFlag: setFeaturesFlag(state),\r\n setTanglesApiKey: setTanglesApiKey(state),\r\n setServiceType: setServiceType(state),\r\n setCreateModel: setCreateModel(state),\r\n setIndex: setIndex(state),\r\n validate: validate(state)\r\n });\r\n}\r\n\r\nexport function provideStore (): IAddServiceStore {\r\n const state = createState();\r\n\r\n provide(AddServiceStoreKey, state);\r\n\r\n return createForState(state);\r\n}\r\n\r\nexport function useStore (): IAddServiceStore {\r\n const state = inject(AddServiceStoreKey);\r\n if (state === undefined) {\r\n throw new Error('Using AddServiceStore before providing it!');\r\n }\r\n return createForState(state);\r\n}\r\n","\r\nimport { computed, defineComponent, PropType, ref, watch } from 'vue';\r\nimport { VisionFeaturesFlag, VisionFeaturesFlags, getVisionFeatureName } from '@/store/contracts/subscriptions/visionFeaturesFlag';\r\nimport { ProfileFeaturesFlag, ProfileFeaturesFlags, getProfileFeatureName } from '@/store/contracts/subscriptions/profileFeaturesFlag';\r\nimport { SubscriptionServiceType, SubscriptionServiceTypes, getServiceName } from '@/store/contracts/subscriptions/subscriptionServiceType';\r\nimport validationModel, { SubscriptionServiceFieldName as FieldName } from '@/validation/subscriptionServiceValidationModel';\r\nimport { provideStore as provideServiceStore } from '@/store/subscriptions/addService';\r\nimport { fromAdd } from '@/store/subscriptions/mapping/subscriptionService';\r\nimport { getFlagValues, toFlag } from '@/utils/hasFlag';\r\nimport { ISubscriptionCreateModel } from '@/store/contracts/subscriptions/create';\r\nimport { useFieldsValidation } from '@/components/utils/fieldValidation';\r\nimport { ISubscriptionServiceModel } from '@/store/contracts/subscriptions/addService';\r\nimport { Settings } from '@/settings';\r\nimport DatePicker from '@/components/date/DatePicker.vue';\r\n\r\nexport default defineComponent({\r\n props: {\r\n modelValue: {\r\n type: Boolean,\r\n required: true\r\n },\r\n subscriptionCreateModel: {\r\n type: Object as PropType,\r\n required: true\r\n },\r\n subscriptionService: {\r\n type: Object as PropType,\r\n required: false\r\n }\r\n },\r\n components: {\r\n DatePicker\r\n },\r\n setup (props, { emit }) {\r\n const isOpen = computed({\r\n get: () => props.modelValue,\r\n set: (v) => emit('update:modelValue', v)\r\n });\r\n\r\n const contractQuotaLabel = computed(() => {\r\n switch (serviceType.value) {\r\n case SubscriptionServiceType.None:\r\n return 'Contract Quota';\r\n case SubscriptionServiceType.Vision:\r\n return 'Contract Quota (Lookups)';\r\n case SubscriptionServiceType.Translation:\r\n return 'Contract Quota (Characters)';\r\n case SubscriptionServiceType.Transcription:\r\n return 'Contract Quota (Hours)';\r\n case SubscriptionServiceType.Profile:\r\n return 'Contract Quota (Searches)';\r\n default:\r\n throw new Error(`Service Type ${serviceType.value} not found.`);\r\n }\r\n });\r\n\r\n const monthlyQuotaLabel = computed(() => {\r\n switch (serviceType.value) {\r\n case SubscriptionServiceType.None:\r\n return 'Monthly Quota';\r\n case SubscriptionServiceType.Vision:\r\n return 'Monthly Quota (Lookups)';\r\n case SubscriptionServiceType.Translation:\r\n return 'Monthly Quota (Characters)';\r\n case SubscriptionServiceType.Transcription:\r\n return 'Monthly Quota (Hours)';\r\n case SubscriptionServiceType.Profile:\r\n return 'Monthly Quota (Searches)';\r\n default:\r\n throw new Error(`Service Type ${serviceType.value} not found.`);\r\n }\r\n });\r\n\r\n const dailyQuotaLabel = computed(() => {\r\n switch (serviceType.value) {\r\n case SubscriptionServiceType.None:\r\n return 'Daily Quota';\r\n case SubscriptionServiceType.Vision:\r\n return 'Daily Quota (Lookups)';\r\n case SubscriptionServiceType.Translation:\r\n return 'Daily Quota (Characters)';\r\n case SubscriptionServiceType.Transcription:\r\n return 'Daily Quota (Hours)';\r\n case SubscriptionServiceType.Profile:\r\n return 'Daily Quota (Searches)';\r\n default:\r\n throw new Error(`Service Type ${serviceType.value} not found.`);\r\n }\r\n });\r\n\r\n const addServiceStore = provideServiceStore();\r\n\r\n const noServiceTypeSelected = computed(() => serviceType.value === SubscriptionServiceType.None);\r\n\r\n addServiceStore.setCreateModel(props.subscriptionCreateModel);\r\n\r\n const availableServices = SubscriptionServiceTypes.map(v => ({\r\n label: getServiceName(v),\r\n value: v\r\n }));\r\n\r\n const { validationStore, validationRefs } = useFieldsValidation(\r\n validationModel,\r\n ref(true),\r\n [FieldName.ServiceType, FieldName.DailyQuota, FieldName.MonthlyQuota, FieldName.ContractStartDate, FieldName.ContractEndDate, FieldName.ContractQuota, FieldName.FeaturesFlag]);\r\n\r\n const serviceType = computed({\r\n get: () => addServiceStore.state.model.serviceType,\r\n set: (s) => {\r\n resetQuotas(s); // Quotas use different units based on service type so we want to rest them when the service type changes.\r\n addServiceStore.setServiceType(s);\r\n }\r\n });\r\n\r\n const contractStartDate = computed({\r\n get: () => addServiceStore.state.model.contractStartDate,\r\n set: addServiceStore.setContractStartDate\r\n });\r\n\r\n const contractEndDate = computed({\r\n get: () => addServiceStore.state.model.contractEndDate,\r\n set: addServiceStore.setContractEndDate\r\n });\r\n\r\n const contractQuota = computed({\r\n get: () => getQuota('Contract', serviceType.value),\r\n set: (s) => setQuota(s, 'Contract', serviceType.value)\r\n });\r\n\r\n const monthlyQuota = computed({\r\n get: () => getQuota('Monthly', serviceType.value),\r\n set: (s) => setQuota(s, 'Monthly', serviceType.value)\r\n });\r\n\r\n const dailyQuota = computed({\r\n get: () => getQuota('Daily', serviceType.value),\r\n set: (s) => setQuota(s, 'Daily', serviceType.value)\r\n });\r\n\r\n const visionFeaturesFlag = computed({\r\n get: () => getFlagValues(VisionFeaturesFlags.filter(f => f !== VisionFeaturesFlag.None), addServiceStore.state.model.featuresFlag),\r\n set: (value) => addServiceStore.setFeaturesFlag(toFlag(value))\r\n });\r\n\r\n const profileFeaturesFlag = computed({\r\n get: () => getFlagValues(ProfileFeaturesFlags.filter(f => f !== ProfileFeaturesFlag.None), addServiceStore.state.model.featuresFlag),\r\n set: (value) => addServiceStore.setFeaturesFlag(toFlag(value))\r\n });\r\n\r\n const tanglesApiKey = computed({\r\n get: () => addServiceStore.state.model.tanglesApiKey,\r\n set: (s) => {\r\n if (s) {\r\n addServiceStore.setContractQuota(2147483647);\r\n } else if (addServiceStore.state.model.contractQuota === 2147483647) {\r\n addServiceStore.setContractQuota(null);\r\n }\r\n addServiceStore.setTanglesApiKey(s);\r\n }\r\n });\r\n\r\n const availableFeatures = computed(() => {\r\n switch (serviceType.value) {\r\n case SubscriptionServiceType.Vision:\r\n return VisionFeaturesFlags.filter(f => f !== VisionFeaturesFlags[0]).map(f => ({\r\n label: getVisionFeatureName(f),\r\n value: f\r\n }));\r\n case SubscriptionServiceType.Profile:\r\n return ProfileFeaturesFlags.filter(f => f !== ProfileFeaturesFlags[0]).map(f => ({\r\n label: getProfileFeatureName(f),\r\n value: f\r\n }));\r\n default:\r\n return [];\r\n }\r\n });\r\n\r\n function resetQuotas (serviceType: SubscriptionServiceType | null) {\r\n if (serviceType === SubscriptionServiceType.Profile && tanglesApiKey.value) {\r\n addServiceStore.setContractQuota(2147483647);\r\n } else {\r\n addServiceStore.setContractQuota(null);\r\n }\r\n addServiceStore.setMonthlyQuota(null);\r\n addServiceStore.setDailyQuota(null);\r\n }\r\n\r\n function getQuota (contractType: 'Contract' | 'Monthly' | 'Daily', serviceType: SubscriptionServiceType | null) {\r\n if (!serviceType) {\r\n serviceType = SubscriptionServiceType.None;\r\n }\r\n switch (contractType) {\r\n case 'Contract':\r\n return normalizeQuotaFromServer(addServiceStore.state.model.contractQuota, serviceType);\r\n case 'Monthly':\r\n return normalizeQuotaFromServer(addServiceStore.state.model.monthlyQuota, serviceType);\r\n case 'Daily':\r\n return normalizeQuotaFromServer(addServiceStore.state.model.dailyQuota, serviceType);\r\n default:\r\n break;\r\n }\r\n }\r\n\r\n function setQuota (quota: number | null | undefined, contractType: 'Contract' | 'Monthly' | 'Daily', serviceType: SubscriptionServiceType | null) {\r\n if (!serviceType) {\r\n serviceType = SubscriptionServiceType.None;\r\n }\r\n switch (contractType) {\r\n case 'Contract':\r\n addServiceStore.setContractQuota(normalizeQuotaToServer(quota, serviceType));\r\n break;\r\n case 'Monthly':\r\n addServiceStore.setMonthlyQuota(normalizeQuotaToServer(quota, serviceType));\r\n break;\r\n case 'Daily':\r\n addServiceStore.setDailyQuota(normalizeQuotaToServer(quota, serviceType));\r\n break;\r\n default:\r\n break;\r\n }\r\n }\r\n\r\n function normalizeQuotaToServer (value: number | null | undefined, serviceType: SubscriptionServiceType) {\r\n if (!value) {\r\n return null;\r\n }\r\n switch (serviceType) {\r\n case SubscriptionServiceType.Transcription:\r\n return value * 3600; // Converting hours to seconds for storage on the backend.\r\n default:\r\n return parseFloat(value.toFixed(0)); // Backend quotas are long and cannot have decimals.\r\n }\r\n }\r\n\r\n function normalizeQuotaFromServer (value: number | null, serviceType: SubscriptionServiceType) {\r\n if (!value) {\r\n return null;\r\n }\r\n switch (serviceType) {\r\n case SubscriptionServiceType.Transcription:\r\n return parseFloat((value / 3600).toFixed(2)); // Converting seconds to hours for view on frontend\r\n default:\r\n return parseFloat(value.toFixed(0)); // Backend quotas are long and cannot have decimals.\r\n }\r\n }\r\n\r\n const hasVisionFeatures = computed(() => {\r\n return (serviceType.value === SubscriptionServiceType.Vision);\r\n });\r\n const hasProfileFeatures = computed(() => {\r\n return (serviceType.value === SubscriptionServiceType.Profile);\r\n });\r\n const hasTanglesFeatures = computed(() => {\r\n return (serviceType.value === SubscriptionServiceType.Profile && (profileFeaturesFlag.value.includes(ProfileFeaturesFlag.TanglesSearch) || profileFeaturesFlag.value.includes(ProfileFeaturesFlag.AdvancedTanglesSearch)));\r\n });\r\n\r\n function resetState () {\r\n addServiceStore.setContractStartDate(props.subscriptionService ? props.subscriptionService?.contractStartDate : props.subscriptionCreateModel.activeDate);\r\n addServiceStore.setContractEndDate(props.subscriptionService ? props.subscriptionService?.contractEndDate : props.subscriptionCreateModel.expiresDate);\r\n addServiceStore.setContractQuota(props.subscriptionService?.contractQuota ?? Settings.defaultContractQuota);\r\n addServiceStore.setMonthlyQuota(props.subscriptionService?.monthlyQuota ?? Settings.defaultMonthlyQuota);\r\n addServiceStore.setDailyQuota(props.subscriptionService?.dailyQuota ?? Settings.defaultDailyQuota);\r\n addServiceStore.setServiceType(props.subscriptionService?.serviceType ?? SubscriptionServiceType.None);\r\n addServiceStore.setFeaturesFlag(props.subscriptionService?.featuresFlag ?? VisionFeaturesFlag.Tags);\r\n addServiceStore.setTanglesApiKey(props.subscriptionService?.tanglesApiKey ?? null);\r\n addServiceStore.setIndex(props.subscriptionService?.index ?? props.subscriptionCreateModel.services.length);\r\n }\r\n\r\n watch(() => props.modelValue, resetState);\r\n\r\n watch(() => props.subscriptionCreateModel, () => addServiceStore.setCreateModel(props.subscriptionCreateModel));\r\n\r\n async function add () {\r\n const valid = await addServiceStore.validate();\r\n if (valid) {\r\n emit('service-added', fromAdd(addServiceStore.state.model));\r\n isOpen.value = false;\r\n }\r\n }\r\n\r\n async function cancel () {\r\n validationStore.clear(validationModel);\r\n isOpen.value = false;\r\n }\r\n\r\n const dialogTitle = computed(() => props.subscriptionService ? 'Edit Service' : 'Add Service');\r\n const confirmWord = computed(() => props.subscriptionService ? 'Save' : 'Add');\r\n\r\n function contractStartDateChanged (startDate: Date | null) {\r\n contractStartDate.value = startDate;\r\n }\r\n\r\n function contractEndDateChanged (endDate: Date | null) {\r\n contractEndDate.value = endDate;\r\n }\r\n\r\n return {\r\n isOpen,\r\n contractStartDate,\r\n contractStartDateChanged,\r\n contractEndDate,\r\n contractEndDateChanged,\r\n contractQuota,\r\n monthlyQuota,\r\n dailyQuota,\r\n availableServices,\r\n serviceType,\r\n availableFeatures,\r\n add,\r\n cancel,\r\n hasVisionFeatures,\r\n hasProfileFeatures,\r\n hasTanglesFeatures,\r\n validationRefs,\r\n FieldName,\r\n visionFeaturesFlag,\r\n profileFeaturesFlag,\r\n tanglesApiKey,\r\n dialogTitle,\r\n confirmWord,\r\n contractQuotaLabel,\r\n monthlyQuotaLabel,\r\n dailyQuotaLabel,\r\n noServiceTypeSelected,\r\n resetQuotas\r\n };\r\n }\r\n});\r\n","import { render } from \"./AddServiceDialog.vue?vue&type=template&id=71ad42ae\"\nimport script from \"./AddServiceDialog.vue?vue&type=script&lang=ts\"\nexport * from \"./AddServiceDialog.vue?vue&type=script&lang=ts\"\n\nimport \"./AddServiceDialog.vue?vue&type=style&index=0&id=71ad42ae&lang=scss\"\nscript.render = render\n\nexport default script\nimport QDialog from 'quasar/src/components/dialog/QDialog.js';\nimport QCard from 'quasar/src/components/card/QCard.js';\nimport QCardSection from 'quasar/src/components/card/QCardSection.js';\nimport QSelect from 'quasar/src/components/select/QSelect.js';\nimport QInput from 'quasar/src/components/input/QInput.js';\nimport QBtn from 'quasar/src/components/btn/QBtn.js';\nimport qInstall from \"../../../node_modules/vue-cli-plugin-quasar/lib/runtime.auto-import.js\";\nqInstall(script, 'components', {QDialog,QCard,QCardSection,QSelect,QInput,QBtn});\n","export * from \"-!../../../node_modules/mini-css-extract-plugin/dist/loader.js??ref--8-oneOf-1-0!../../../node_modules/css-loader/dist/cjs.js??ref--8-oneOf-1-1!../../../node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/stylePostLoader.js!../../../node_modules/postcss-loader/src/index.js??ref--8-oneOf-1-2!../../../node_modules/sass-loader/dist/cjs.js??ref--8-oneOf-1-3!../../../node_modules/vue-cli-plugin-quasar/lib/loader.vue.auto-import-quasar.js?kebab!../../../node_modules/cache-loader/dist/cjs.js??ref--0-1!../../../node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/index.js??ref--0-2!./SubscriptionTransactionsPage.vue?vue&type=style&index=0&id=2c0a2708&lang=scss\"","export enum VisionFeaturesFlag\r\n {\r\n /// \r\n /// No additional features enabled for Vision\r\n /// \r\n None = 0,\r\n /// \r\n /// Tags feature for Vision\r\n /// \r\n Tags = 1,\r\n /// \r\n /// Adult content feature for Vision\r\n /// \r\n Adult = 1 << 1,\r\n}\r\n\r\nexport const VisionFeaturesFlags = [VisionFeaturesFlag.None, VisionFeaturesFlag.Adult, VisionFeaturesFlag.Tags];\r\n\r\nexport const getVisionFeatureName = (feature: VisionFeaturesFlag, defaultException = true): string => {\r\n switch (feature) {\r\n case VisionFeaturesFlag.Tags:\r\n return 'Tags';\r\n case VisionFeaturesFlag.Adult:\r\n return 'Adult';\r\n default:\r\n if (defaultException) {\r\n throw new Error(`Feature ${feature} does not exist.`);\r\n }\r\n return 'None';\r\n }\r\n};\r\n","export enum ProfileFeaturesFlag\r\n {\r\n /// \r\n /// No profile search features enabled.\r\n /// \r\n None = 0,\r\n /// \r\n /// Ability to search tangles.\r\n /// \r\n TanglesSearch = 1,\r\n /// \r\n /// Ability to search tangles with the advanced search flag.\r\n /// \r\n AdvancedTanglesSearch = 1 << 1,\r\n}\r\n\r\nexport const ProfileFeaturesFlags = [ProfileFeaturesFlag.None, ProfileFeaturesFlag.TanglesSearch];\r\n\r\nexport const getProfileFeatureName = (feature: ProfileFeaturesFlag, defaultException = true): string => {\r\n switch (feature) {\r\n case ProfileFeaturesFlag.TanglesSearch:\r\n return 'Tangles';\r\n case ProfileFeaturesFlag.AdvancedTanglesSearch:\r\n return 'Advanced Tangles';\r\n default:\r\n if (defaultException) {\r\n throw new Error(`Feature ${feature} does not exist.`);\r\n }\r\n return 'None';\r\n }\r\n};\r\n","// extracted by mini-css-extract-plugin\nmodule.exports = {\"Gray50\":\"#fafafa\",\"Gray100\":\"#f2f4f5\",\"Gray200\":\"#ebeff2\",\"Gray300\":\"#dae0e6\",\"Gray400\":\"#bec5cc\",\"Gray500\":\"#a1aab3\",\"Gray600\":\"#8a9299\",\"Gray700\":\"#737980\",\"Gray800\":\"#5c6166\",\"Gray900\":\"#45494d\",\"Navy50\":\"#bde3fc\",\"Navy100\":\"#7ec9fc\",\"Navy200\":\"#3faffc\",\"Navy300\":\"#0095fc\",\"Navy400\":\"#0086e3\",\"Navy500\":\"#0077c9\",\"Navy600\":\"#0068b0\",\"Navy700\":\"#005996\",\"Navy800\":\"#004a7d\",\"Navy900\":\"#002b49\",\"Blue50\":\"#bbeafa\",\"Blue100\":\"#7ddafa\",\"Blue200\":\"#3ecafa\",\"Blue300\":\"#00bbfa\",\"Blue400\":\"#00a8e1\",\"Blue500\":\"#0095c7\",\"Blue600\":\"#0081ad\",\"Blue700\":\"#006e94\",\"Blue800\":\"#005b7a\",\"Blue900\":\"#004861\",\"Red50\":\"#f2b5c1\",\"Red100\":\"#f2798f\",\"Red200\":\"#f23d5e\",\"Red300\":\"#f2002c\",\"Red400\":\"#d90027\",\"Red500\":\"#bf0023\",\"Red600\":\"#a6001e\",\"Red700\":\"#8c001a\",\"Red800\":\"#730015\",\"Red900\":\"#590010\",\"Yellow50\":\"#fcf8bd\",\"Yellow100\":\"#fcf37e\",\"Yellow200\":\"#fcef3f\",\"Yellow300\":\"#fceb00\",\"Yellow400\":\"#e3d400\",\"Yellow500\":\"#c9bc00\",\"White\":\"#fff\",\"Black\":\"#17181a\",\"Orange\":\"#ff8900\",\"Transparent\":\"rgba(255,255,255,0)\"};","// extracted by mini-css-extract-plugin\nmodule.exports = {\"Gray50\":\"#fafafa\",\"Gray100\":\"#f2f4f5\",\"Gray200\":\"#ebeff2\",\"Gray300\":\"#dae0e6\",\"Gray400\":\"#bec5cc\",\"Gray500\":\"#a1aab3\",\"Gray600\":\"#8a9299\",\"Gray700\":\"#737980\",\"Gray800\":\"#5c6166\",\"Gray900\":\"#45494d\",\"Navy50\":\"#bde3fc\",\"Navy100\":\"#7ec9fc\",\"Navy200\":\"#3faffc\",\"Navy300\":\"#0095fc\",\"Navy400\":\"#0086e3\",\"Navy500\":\"#0077c9\",\"Navy600\":\"#0068b0\",\"Navy700\":\"#005996\",\"Navy800\":\"#004a7d\",\"Navy900\":\"#002b49\",\"Blue50\":\"#bbeafa\",\"Blue100\":\"#7ddafa\",\"Blue200\":\"#3ecafa\",\"Blue300\":\"#00bbfa\",\"Blue400\":\"#00a8e1\",\"Blue500\":\"#0095c7\",\"Blue600\":\"#0081ad\",\"Blue700\":\"#006e94\",\"Blue800\":\"#005b7a\",\"Blue900\":\"#004861\",\"Red50\":\"#f2b5c1\",\"Red100\":\"#f2798f\",\"Red200\":\"#f23d5e\",\"Red300\":\"#f2002c\",\"Red400\":\"#d90027\",\"Red500\":\"#bf0023\",\"Red600\":\"#a6001e\",\"Red700\":\"#8c001a\",\"Red800\":\"#730015\",\"Red900\":\"#590010\",\"Yellow50\":\"#fcf8bd\",\"Yellow100\":\"#fcf37e\",\"Yellow200\":\"#fcef3f\",\"Yellow300\":\"#fceb00\",\"Yellow400\":\"#e3d400\",\"Yellow500\":\"#c9bc00\",\"White\":\"#fff\",\"Black\":\"#17181a\",\"Orange\":\"#ff8900\",\"Transparent\":\"rgba(255,255,255,0)\"};","export * from \"-!../../../node_modules/mini-css-extract-plugin/dist/loader.js??ref--8-oneOf-1-0!../../../node_modules/css-loader/dist/cjs.js??ref--8-oneOf-1-1!../../../node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/stylePostLoader.js!../../../node_modules/postcss-loader/src/index.js??ref--8-oneOf-1-2!../../../node_modules/sass-loader/dist/cjs.js??ref--8-oneOf-1-3!../../../node_modules/vue-cli-plugin-quasar/lib/loader.vue.auto-import-quasar.js?kebab!../../../node_modules/cache-loader/dist/cjs.js??ref--0-1!../../../node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/index.js??ref--0-2!./SubscriptionViewPage.vue?vue&type=style&index=0&id=053df376&lang=scss\"","export const dayMillis = (1000 * 60 * 60 * 24);\r\n\r\nexport function daysMillis (days: number): number {\r\n return dayMillis * days;\r\n}\r\n\r\nexport function minusDays (date: Date | number, days: number): number {\r\n return (typeof date === 'number' ? date : date.getTime()) - daysMillis(days);\r\n}\r\n\r\nexport function plusDays (date: Date | number, days: number): number {\r\n return (typeof date === 'number' ? date : date.getTime()) + daysMillis(days);\r\n}\r\n\r\nexport function formatSeconds (seconds: number | null | undefined): string {\r\n if (seconds === null || seconds === undefined) {\r\n return '0h';\r\n }\r\n // Convert seconds to hours, minutes, and seconds in this format 00h 00m 00s\r\n const hours = Math.floor(seconds / 3600);\r\n const minutes = Math.floor((seconds - (hours * 3600)) / 60);\r\n const secondsRemainder = seconds - (hours * 3600) - (minutes * 60);\r\n\r\n let timeString = '';\r\n if (hours > 0) {\r\n timeString += hours + 'h ';\r\n }\r\n if (minutes > 0) {\r\n timeString += minutes + 'm ';\r\n }\r\n if (secondsRemainder > 0) {\r\n timeString += secondsRemainder.toFixed(0) + 's ';\r\n }\r\n return timeString;\r\n}\r\n","export * from \"-!../../../node_modules/mini-css-extract-plugin/dist/loader.js??ref--8-oneOf-1-0!../../../node_modules/css-loader/dist/cjs.js??ref--8-oneOf-1-1!../../../node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/stylePostLoader.js!../../../node_modules/postcss-loader/src/index.js??ref--8-oneOf-1-2!../../../node_modules/sass-loader/dist/cjs.js??ref--8-oneOf-1-3!../../../node_modules/vue-cli-plugin-quasar/lib/loader.vue.auto-import-quasar.js?kebab!../../../node_modules/cache-loader/dist/cjs.js??ref--0-1!../../../node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/index.js??ref--0-2!./SubscriptionListPage.vue?vue&type=style&index=0&id=700b620d&lang=scss\"","// extracted by mini-css-extract-plugin\nmodule.exports = {\"Gray50\":\"#fafafa\",\"Gray100\":\"#f2f4f5\",\"Gray200\":\"#ebeff2\",\"Gray300\":\"#dae0e6\",\"Gray400\":\"#bec5cc\",\"Gray500\":\"#a1aab3\",\"Gray600\":\"#8a9299\",\"Gray700\":\"#737980\",\"Gray800\":\"#5c6166\",\"Gray900\":\"#45494d\",\"Navy50\":\"#bde3fc\",\"Navy100\":\"#7ec9fc\",\"Navy200\":\"#3faffc\",\"Navy300\":\"#0095fc\",\"Navy400\":\"#0086e3\",\"Navy500\":\"#0077c9\",\"Navy600\":\"#0068b0\",\"Navy700\":\"#005996\",\"Navy800\":\"#004a7d\",\"Navy900\":\"#002b49\",\"Blue50\":\"#bbeafa\",\"Blue100\":\"#7ddafa\",\"Blue200\":\"#3ecafa\",\"Blue300\":\"#00bbfa\",\"Blue400\":\"#00a8e1\",\"Blue500\":\"#0095c7\",\"Blue600\":\"#0081ad\",\"Blue700\":\"#006e94\",\"Blue800\":\"#005b7a\",\"Blue900\":\"#004861\",\"Red50\":\"#f2b5c1\",\"Red100\":\"#f2798f\",\"Red200\":\"#f23d5e\",\"Red300\":\"#f2002c\",\"Red400\":\"#d90027\",\"Red500\":\"#bf0023\",\"Red600\":\"#a6001e\",\"Red700\":\"#8c001a\",\"Red800\":\"#730015\",\"Red900\":\"#590010\",\"Yellow50\":\"#fcf8bd\",\"Yellow100\":\"#fcf37e\",\"Yellow200\":\"#fcef3f\",\"Yellow300\":\"#fceb00\",\"Yellow400\":\"#e3d400\",\"Yellow500\":\"#c9bc00\",\"White\":\"#fff\",\"Black\":\"#17181a\",\"Orange\":\"#ff8900\",\"Transparent\":\"rgba(255,255,255,0)\"};","import { IUpdateLabelModel } from '@/store/contracts/subscriptions/subscription';\r\nimport { ValidationModel } from '@/validation';\r\nimport { stringRequiredRule } from '@/validation/common/rules';\r\n\r\nexport enum UpdateLabelFieldName {\r\n Label = 'label'\r\n}\r\n\r\nclass UpdateSubscriptionLabelValidationModel extends ValidationModel {\r\n constructor () {\r\n super();\r\n\r\n this.setField(UpdateLabelFieldName.Label, {\r\n getter: (model) => model?.label ?? null,\r\n rules: [\r\n stringRequiredRule('Label is required')\r\n ]\r\n });\r\n }\r\n\r\n get modelName (): string {\r\n return 'UpdateSubscriptionLabelValidationModel';\r\n }\r\n}\r\n\r\nexport default new UpdateSubscriptionLabelValidationModel();\r\n","\r\n
\r\n
\r\n
View Subscription
\r\n
\r\n \r\n Back to Subscriptions\r\n \r\n
\r\n
\r\n
\r\n
\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n \r\n Jump to image analysis page\r\n \r\n Cannot jump to image analysis page without adding a Vision service\r\n \r\n \r\n {{ showSubscriptionKeyTooltip }}\r\n \r\n \r\n \r\n \r\n Generate new subscription key\r\n \r\n \r\n \r\n \r\n Copy subscription key to clipboard\r\n \r\n \r\n