From e5ac9a1be8c0f7acffd7f7d45180193b8b796226 Mon Sep 17 00:00:00 2001 From: Ryan Mitchell Date: Mon, 15 Feb 2021 08:44:31 +0000 Subject: [PATCH] Init --- Readme.md | 29 + composer.json | 28 + resources/dist/cplisting.js | 1198 +++++++++++++++++ resources/js/components/CPListing.vue | 127 ++ resources/js/components/DeletesListingRow.js | 48 + .../fieldtypes/ExampleFieldtype.vue | 15 + resources/js/cp.js | 4 + src/ServiceProvider.php | 13 + 8 files changed, 1462 insertions(+) create mode 100644 Readme.md create mode 100644 composer.json create mode 100644 resources/dist/cplisting.js create mode 100644 resources/js/components/CPListing.vue create mode 100644 resources/js/components/DeletesListingRow.js create mode 100644 resources/js/components/fieldtypes/ExampleFieldtype.vue create mode 100644 resources/js/cp.js create mode 100644 src/ServiceProvider.php diff --git a/Readme.md b/Readme.md new file mode 100644 index 0000000..545144a --- /dev/null +++ b/Readme.md @@ -0,0 +1,29 @@ +# CP Listing + +Provides a `` component to use within Statamic v3 for searchable, filterable listing views. + +To install: + +``` +composer require thoughtco/statamic-cplisting +``` + +Then run `composer update` + + +To use: + +```blade + +``` \ No newline at end of file diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..e1dcfbe --- /dev/null +++ b/composer.json @@ -0,0 +1,28 @@ +{ + "name": "thoughtco/statamic-cplisting", + "description": "Adds a cp-listing component to Statamic v3 for control panel lists", + "autoload": { + "psr-4": { + "Thoughtco\\CPListing\\": "src" + } + }, + "authors": [ + { + "name": "Ryan Mitchell" + } + ], + "support": { + "email": "help@thoughtcollective.com" + }, + "extra": { + "statamic": { + "name": "CP Listing", + "description": "Adds a cp-listing component to Statamic v3 for control panel lists" + }, + "laravel": { + "providers": [ + "Thoughtco\\CPListing\\ServiceProvider" + ] + } + } +} diff --git a/resources/dist/cplisting.js b/resources/dist/cplisting.js new file mode 100644 index 0000000..808ccd6 --- /dev/null +++ b/resources/dist/cplisting.js @@ -0,0 +1,1198 @@ +/******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) { +/******/ return installedModules[moduleId].exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.l = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; +/******/ +/******/ // define getter function for harmony exports +/******/ __webpack_require__.d = function(exports, name, getter) { +/******/ if(!__webpack_require__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); +/******/ } +/******/ }; +/******/ +/******/ // define __esModule on exports +/******/ __webpack_require__.r = function(exports) { +/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { +/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); +/******/ } +/******/ Object.defineProperty(exports, '__esModule', { value: true }); +/******/ }; +/******/ +/******/ // create a fake namespace object +/******/ // mode & 1: value is a module id, require it +/******/ // mode & 2: merge all properties of value into the ns +/******/ // mode & 4: return value when already ns object +/******/ // mode & 8|1: behave like require +/******/ __webpack_require__.t = function(value, mode) { +/******/ if(mode & 1) value = __webpack_require__(value); +/******/ if(mode & 8) return value; +/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; +/******/ var ns = Object.create(null); +/******/ __webpack_require__.r(ns); +/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); +/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); +/******/ return ns; +/******/ }; +/******/ +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __webpack_require__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; +/******/ +/******/ // Object.prototype.hasOwnProperty.call +/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; +/******/ +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = "/"; +/******/ +/******/ +/******/ // Load entry module and return exports +/******/ return __webpack_require__(__webpack_require__.s = 0); +/******/ }) +/************************************************************************/ +/******/ ({ + +/***/ "./node_modules/babel-loader/lib/index.js?!./node_modules/vue-loader/lib/index.js?!./resources/js/components/TCListing.vue?vue&type=script&lang=js&": +/*!********************************************************************************************************************************************************************!*\ + !*** ./node_modules/babel-loader/lib??ref--4-0!./node_modules/vue-loader/lib??vue-loader-options!./resources/js/components/TCListing.vue?vue&type=script&lang=js& ***! + \********************************************************************************************************************************************************************/ +/*! exports provided: default */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _DeletesListingRow_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./DeletesListingRow.js */ "./resources/js/components/DeletesListingRow.js"); +/* harmony import */ var _vendor_statamic_cms_resources_js_components_Listing__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../vendor/statamic/cms/resources/js/components/Listing */ "./vendor/statamic/cms/resources/js/components/Listing.vue"); +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// + + +/* harmony default export */ __webpack_exports__["default"] = ({ + mixins: [_vendor_statamic_cms_resources_js_components_Listing__WEBPACK_IMPORTED_MODULE_1__["default"], _DeletesListingRow_js__WEBPACK_IMPORTED_MODULE_0__["default"]], + props: { + listingConfig: Array + }, + data: function data() { + var _this$listingConfig$p; + + return { + listingKey: "id", + preferencesPrefix: (_this$listingConfig$p = this.listingConfig.preferencesPrefix) !== null && _this$listingConfig$p !== void 0 ? _this$listingConfig$p : 'tc', + requestUrl: cp_url(this.listingConfig.requestUrl), + columns: this.columns + }; + } +}); + +/***/ }), + +/***/ "./node_modules/babel-loader/lib/index.js?!./node_modules/vue-loader/lib/index.js?!./vendor/statamic/cms/resources/js/components/Listing.vue?vue&type=script&lang=js&": +/*!**************************************************************************************************************************************************************************************!*\ + !*** ./node_modules/babel-loader/lib??ref--4-0!./node_modules/vue-loader/lib??vue-loader-options!./vendor/statamic/cms/resources/js/components/Listing.vue?vue&type=script&lang=js& ***! + \**************************************************************************************************************************************************************************************/ +/*! exports provided: default */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _data_list_HasActions__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./data-list/HasActions */ "./vendor/statamic/cms/resources/js/components/data-list/HasActions.js"); +/* harmony import */ var _data_list_HasFilters__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./data-list/HasFilters */ "./vendor/statamic/cms/resources/js/components/data-list/HasFilters.js"); +/* harmony import */ var _data_list_HasPagination__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./data-list/HasPagination */ "./vendor/statamic/cms/resources/js/components/data-list/HasPagination.js"); +/* harmony import */ var _data_list_HasPreferences__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./data-list/HasPreferences */ "./vendor/statamic/cms/resources/js/components/data-list/HasPreferences.js"); +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + + + + + +/* harmony default export */ __webpack_exports__["default"] = ({ + mixins: [_data_list_HasActions__WEBPACK_IMPORTED_MODULE_0__["default"], _data_list_HasFilters__WEBPACK_IMPORTED_MODULE_1__["default"], _data_list_HasPagination__WEBPACK_IMPORTED_MODULE_2__["default"], _data_list_HasPreferences__WEBPACK_IMPORTED_MODULE_3__["default"]], + props: { + initialSortColumn: String, + initialSortDirection: String, + initialColumns: { + type: Array, + "default": function _default() { + return []; + } + }, + filters: Array + }, + data: function data() { + return { + source: null, + initializing: true, + loading: true, + items: [], + columns: this.initialColumns, + visibleColumns: this.initialColumns.filter(function (column) { + return column.visible; + }), + sortColumn: this.initialSortColumn, + sortDirection: this.initialSortDirection, + meta: null + }; + }, + computed: { + parameters: function parameters() { + return Object.assign({ + sort: this.sortColumn, + order: this.sortDirection, + page: this.page, + perPage: this.perPage, + search: this.searchQuery, + filters: this.activeFilterParameters, + columns: this.visibleColumns.map(function (column) { + return column.field; + }).join(',') + }, this.additionalParameters); + }, + activeFilterParameters: function activeFilterParameters() { + return btoa(JSON.stringify(this.activeFilters)); + }, + additionalParameters: function additionalParameters() { + return {}; + }, + shouldRequestFirstPage: function shouldRequestFirstPage() { + if (this.page > 1 && this.items.length === 0) { + this.page = 1; + return true; + } + + return false; + } + }, + created: function created() { + this.autoApplyFilters(this.filters); + this.request(); + }, + watch: { + parameters: { + deep: true, + handler: function handler(after, before) { + // A change to the search query would trigger both watchers. + // We only want the searchQuery one to kick in. + if (before.search !== after.search) return; + if (JSON.stringify(before) === JSON.stringify(after)) return; + this.request(); + } + }, + loading: { + immediate: true, + handler: function handler(loading) { + this.$progress.loading(this.listingKey, loading); + } + }, + searchQuery: function searchQuery(query) { + this.sortColumn = null; + this.sortDirection = null; + this.resetPage(); + this.request(); + } + }, + methods: { + request: function request() { + var _this = this; + + if (!this.requestUrl) { + this.loading = false; + return; + } + + this.loading = true; + if (this.source) this.source.cancel(); + this.source = this.$axios.CancelToken.source(); + this.$axios.get(this.requestUrl, { + params: this.parameters, + cancelToken: this.source.token + }).then(function (response) { + _this.columns = response.data.meta.columns; + _this.activeFilterBadges = _objectSpread({}, response.data.meta.activeFilterBadges); + _this.items = Object.values(response.data.data); + _this.meta = response.data.meta; + if (_this.shouldRequestFirstPage) return _this.request(); + _this.loading = false; + _this.initializing = false; + + _this.afterRequestCompleted(); + })["catch"](function (e) { + if (_this.$axios.isCancel(e)) return; + _this.loading = false; + _this.initializing = false; + + _this.$toast.error(e.response ? e.response.data.message : __('Something went wrong'), { + duration: null + }); + }); + }, + afterRequestCompleted: function afterRequestCompleted(response) {// + }, + sorted: function sorted(column, direction) { + this.sortColumn = column; + this.sortDirection = direction; + }, + removeRow: function removeRow(row) { + var id = row.id; + + var i = _.indexOf(this.rows, _.findWhere(this.rows, { + id: id + })); + + this.rows.splice(i, 1); + if (this.rows.length === 0) location.reload(); + } + } +}); + +/***/ }), + +/***/ "./node_modules/vue-loader/lib/loaders/templateLoader.js?!./node_modules/vue-loader/lib/index.js?!./resources/js/components/TCListing.vue?vue&type=template&id=694d364c&": +/*!************************************************************************************************************************************************************************************************************!*\ + !*** ./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/vue-loader/lib??vue-loader-options!./resources/js/components/TCListing.vue?vue&type=template&id=694d364c& ***! + \************************************************************************************************************************************************************************************************************/ +/*! exports provided: render, staticRenderFns */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "render", function() { return render; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "staticRenderFns", function() { return staticRenderFns; }); +var render = function() { + var _vm = this + var _h = _vm.$createElement + var _c = _vm._self._c || _h + return _c( + "div", + [ + _vm.initializing + ? _c("div", { staticClass: "card loading" }, [_c("loading-graphic")], 1) + : _vm._e(), + _vm._v(" "), + !_vm.initializing + ? _c("data-list", { + staticClass: "mb-4", + attrs: { + "visible-columns": _vm.columns, + columns: _vm.columns, + rows: _vm.items, + sort: false, + "sort-column": _vm.sortColumn, + "sort-direction": _vm.sortDirection + }, + scopedSlots: _vm._u( + [ + { + key: "default", + fn: function(ref) { + var hasSelections = ref.hasSelections + return _c("div", {}, [ + _c( + "div", + { staticClass: "card p-0 relative" }, + [ + _c("data-list-filter-presets", { + ref: "presets", + attrs: { + "active-preset": _vm.activePreset, + "preferences-prefix": _vm.preferencesPrefix + }, + on: { + selected: _vm.selectPreset, + reset: _vm.filtersReset + } + }), + _vm._v(" "), + _c( + "div", + { staticClass: "data-list-header" }, + [ + _c("data-list-filters", { + attrs: { + filters: _vm.filters, + "active-preset": _vm.activePreset, + "active-preset-payload": + _vm.activePresetPayload, + "active-filters": _vm.activeFilters, + "active-filter-badges": + _vm.activeFilterBadges, + "active-count": _vm.activeFilterCount, + "search-query": _vm.searchQuery, + "saves-presets": true, + "preferences-prefix": _vm.preferencesPrefix + }, + on: { + "filter-changed": _vm.filterChanged, + "search-changed": _vm.searchChanged, + saved: function($event) { + return _vm.$refs.presets.setPreset($event) + }, + deleted: function($event) { + return _vm.$refs.presets.refreshPresets() + }, + "restore-preset": function($event) { + return _vm.$refs.presets.viewPreset($event) + }, + reset: _vm.filtersReset + } + }) + ], + 1 + ), + _vm._v(" "), + _c("div", { + directives: [ + { + name: "show", + rawName: "v-show", + value: _vm.items.length === 0, + expression: "items.length === 0" + } + ], + staticClass: "p-3 text-center text-grey-50", + domProps: { + textContent: _vm._s(_vm.__("No results")) + } + }), + _vm._v(" "), + _c("data-list-table", { + directives: [ + { + name: "show", + rawName: "v-show", + value: _vm.items.length, + expression: "items.length" + } + ], + attrs: { + "allow-bulk-actions": false, + loading: _vm.loading, + reorderable: false, + sortable: true, + "toggle-selection-on-row-click": true, + "allow-column-picker": true, + "column-preferences-key": _vm.preferencesKey( + "columns" + ) + }, + on: { sorted: _vm.sorted }, + scopedSlots: _vm._u( + [ + { + key: "cell-label", + fn: function(ref) { + var row = ref.row + return [ + _c( + "a", + { + attrs: { + href: _vm.cp_url( + _vm.listingConfig.editUrl + row.id + ) + } + }, + [_vm._v(_vm._s(row.label))] + ) + ] + } + }, + { + key: "actions", + fn: function(ref) { + var row = ref.row + var index = ref.index + return [ + _c( + "dropdown-list", + [ + _c("dropdown-item", { + attrs: { + text: _vm.__("Edit"), + redirect: _vm.cp_url( + _vm.listingConfig.editUrl + + row.id + ) + } + }), + _vm._v(" "), + _vm.listingConfig.deleteUrl !== + undefined + ? _c("dropdown-item", { + staticClass: "warning", + attrs: { + text: _vm.__("Delete") + }, + on: { + click: function($event) { + return _vm.confirmDeleteRow( + row.id, + index + ) + } + } + }) + : _vm._e() + ], + 1 + ), + _vm._v(" "), + _vm.deletingRow !== false + ? _c("confirmation-modal", { + attrs: { + title: _vm.deletingModalTitle, + bodyText: _vm.__( + "Are you sure you want to delete this item?" + ), + buttonText: _vm.__("Delete"), + danger: true + }, + on: { + confirm: function($event) { + return _vm.deleteRow( + _vm.listingConfig.listingUrl + ) + }, + cancel: _vm.cancelDeleteRow + } + }) + : _vm._e() + ] + } + } + ], + null, + true + ) + }) + ], + 1 + ) + ]) + } + } + ], + null, + false, + 1745657748 + ) + }) + : _vm._e(), + _vm._v(" "), + _c("data-list-pagination", { + staticClass: "mt-3", + attrs: { "resource-meta": _vm.meta, "per-page": _vm.perPage }, + on: { + "page-selected": _vm.selectPage, + "per-page-changed": _vm.changePerPage + } + }) + ], + 1 + ) +} +var staticRenderFns = [] +render._withStripped = true + + + +/***/ }), + +/***/ "./node_modules/vue-loader/lib/runtime/componentNormalizer.js": +/*!********************************************************************!*\ + !*** ./node_modules/vue-loader/lib/runtime/componentNormalizer.js ***! + \********************************************************************/ +/*! exports provided: default */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return normalizeComponent; }); +/* globals __VUE_SSR_CONTEXT__ */ + +// IMPORTANT: Do NOT use ES2015 features in this file (except for modules). +// This module is a runtime utility for cleaner component module output and will +// be included in the final webpack user bundle. + +function normalizeComponent ( + scriptExports, + render, + staticRenderFns, + functionalTemplate, + injectStyles, + scopeId, + moduleIdentifier, /* server only */ + shadowMode /* vue-cli only */ +) { + // Vue.extend constructor export interop + var options = typeof scriptExports === 'function' + ? scriptExports.options + : scriptExports + + // render functions + if (render) { + options.render = render + options.staticRenderFns = staticRenderFns + options._compiled = true + } + + // functional template + if (functionalTemplate) { + options.functional = true + } + + // scopedId + if (scopeId) { + options._scopeId = 'data-v-' + scopeId + } + + var hook + if (moduleIdentifier) { // server build + hook = function (context) { + // 2.3 injection + context = + context || // cached call + (this.$vnode && this.$vnode.ssrContext) || // stateful + (this.parent && this.parent.$vnode && this.parent.$vnode.ssrContext) // functional + // 2.2 with runInNewContext: true + if (!context && typeof __VUE_SSR_CONTEXT__ !== 'undefined') { + context = __VUE_SSR_CONTEXT__ + } + // inject component styles + if (injectStyles) { + injectStyles.call(this, context) + } + // register component module identifier for async chunk inferrence + if (context && context._registeredComponents) { + context._registeredComponents.add(moduleIdentifier) + } + } + // used by ssr in case component is cached and beforeCreate + // never gets called + options._ssrRegister = hook + } else if (injectStyles) { + hook = shadowMode + ? function () { + injectStyles.call( + this, + (options.functional ? this.parent : this).$root.$options.shadowRoot + ) + } + : injectStyles + } + + if (hook) { + if (options.functional) { + // for template-only hot-reload because in that case the render fn doesn't + // go through the normalizer + options._injectStyles = hook + // register for functional component in vue file + var originalRender = options.render + options.render = function renderWithStyleInjection (h, context) { + hook.call(context) + return originalRender(h, context) + } + } else { + // inject component registration as beforeCreate hook + var existing = options.beforeCreate + options.beforeCreate = existing + ? [].concat(existing, hook) + : [hook] + } + } + + return { + exports: scriptExports, + options: options + } +} + + +/***/ }), + +/***/ "./resources/js/components/DeletesListingRow.js": +/*!******************************************************!*\ + !*** ./resources/js/components/DeletesListingRow.js ***! + \******************************************************/ +/*! exports provided: default */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony default export */ __webpack_exports__["default"] = ({ + data: function data() { + return { + deletingRow: false + }; + }, + computed: { + deletingModalTitle: function deletingModalTitle() { + return this.deletingModalTitleFromRowKey("source"); + } + }, + methods: { + confirmDeleteRow: function confirmDeleteRow(id, index) { + this.deletingRow = { + id: id, + index: index + }; + }, + deletingModalTitleFromRowKey: function deletingModalTitleFromRowKey(key) { + return __("Delete") + " " + this.rows[this.deletingRow.index][key]; + }, + deleteRow: function deleteRow(resourceRoute, message) { + var _this = this; + + var id = this.deletingRow.id; + message = message || __("Deleted"); + this.$axios["delete"](cp_url("".concat(resourceRoute, "/").concat(id))).then(function () { + var i = _.indexOf(_this.rows, _.findWhere(_this.rows, { + id: id + })); + + _this.rows.splice(i, 1); + + _this.deletingRow = false; + + _this.$toast.success(message); + + location.reload(); + })["catch"](function (e) { + _this.$toast.error(e.response ? e.response.data.message : __("Something went wrong")); + }); + }, + cancelDeleteRow: function cancelDeleteRow() { + this.deletingRow = false; + } + } +}); + +/***/ }), + +/***/ "./resources/js/components/TCListing.vue": +/*!***********************************************!*\ + !*** ./resources/js/components/TCListing.vue ***! + \***********************************************/ +/*! exports provided: default */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _TCListing_vue_vue_type_template_id_694d364c___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./TCListing.vue?vue&type=template&id=694d364c& */ "./resources/js/components/TCListing.vue?vue&type=template&id=694d364c&"); +/* harmony import */ var _TCListing_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./TCListing.vue?vue&type=script&lang=js& */ "./resources/js/components/TCListing.vue?vue&type=script&lang=js&"); +/* empty/unused harmony star reexport *//* harmony import */ var _node_modules_vue_loader_lib_runtime_componentNormalizer_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js */ "./node_modules/vue-loader/lib/runtime/componentNormalizer.js"); + + + + + +/* normalize component */ + +var component = Object(_node_modules_vue_loader_lib_runtime_componentNormalizer_js__WEBPACK_IMPORTED_MODULE_2__["default"])( + _TCListing_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_1__["default"], + _TCListing_vue_vue_type_template_id_694d364c___WEBPACK_IMPORTED_MODULE_0__["render"], + _TCListing_vue_vue_type_template_id_694d364c___WEBPACK_IMPORTED_MODULE_0__["staticRenderFns"], + false, + null, + null, + null + +) + +/* hot reload */ +if (false) { var api; } +component.options.__file = "resources/js/components/TCListing.vue" +/* harmony default export */ __webpack_exports__["default"] = (component.exports); + +/***/ }), + +/***/ "./resources/js/components/TCListing.vue?vue&type=script&lang=js&": +/*!************************************************************************!*\ + !*** ./resources/js/components/TCListing.vue?vue&type=script&lang=js& ***! + \************************************************************************/ +/*! exports provided: default */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _node_modules_babel_loader_lib_index_js_ref_4_0_node_modules_vue_loader_lib_index_js_vue_loader_options_TCListing_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../../node_modules/babel-loader/lib??ref--4-0!../../../node_modules/vue-loader/lib??vue-loader-options!./TCListing.vue?vue&type=script&lang=js& */ "./node_modules/babel-loader/lib/index.js?!./node_modules/vue-loader/lib/index.js?!./resources/js/components/TCListing.vue?vue&type=script&lang=js&"); +/* empty/unused harmony star reexport */ /* harmony default export */ __webpack_exports__["default"] = (_node_modules_babel_loader_lib_index_js_ref_4_0_node_modules_vue_loader_lib_index_js_vue_loader_options_TCListing_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_0__["default"]); + +/***/ }), + +/***/ "./resources/js/components/TCListing.vue?vue&type=template&id=694d364c&": +/*!******************************************************************************!*\ + !*** ./resources/js/components/TCListing.vue?vue&type=template&id=694d364c& ***! + \******************************************************************************/ +/*! exports provided: render, staticRenderFns */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _node_modules_vue_loader_lib_loaders_templateLoader_js_vue_loader_options_node_modules_vue_loader_lib_index_js_vue_loader_options_TCListing_vue_vue_type_template_id_694d364c___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../../node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!../../../node_modules/vue-loader/lib??vue-loader-options!./TCListing.vue?vue&type=template&id=694d364c& */ "./node_modules/vue-loader/lib/loaders/templateLoader.js?!./node_modules/vue-loader/lib/index.js?!./resources/js/components/TCListing.vue?vue&type=template&id=694d364c&"); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "render", function() { return _node_modules_vue_loader_lib_loaders_templateLoader_js_vue_loader_options_node_modules_vue_loader_lib_index_js_vue_loader_options_TCListing_vue_vue_type_template_id_694d364c___WEBPACK_IMPORTED_MODULE_0__["render"]; }); + +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "staticRenderFns", function() { return _node_modules_vue_loader_lib_loaders_templateLoader_js_vue_loader_options_node_modules_vue_loader_lib_index_js_vue_loader_options_TCListing_vue_vue_type_template_id_694d364c___WEBPACK_IMPORTED_MODULE_0__["staticRenderFns"]; }); + + + +/***/ }), + +/***/ "./resources/js/cp.js": +/*!****************************!*\ + !*** ./resources/js/cp.js ***! + \****************************/ +/*! no exports provided */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _components_TCListing__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./components/TCListing */ "./resources/js/components/TCListing.vue"); +/** + * When extending the control panel, be sure to uncomment the necessary code for your build process: + * https://statamic.dev/extending/control-panel + */ + +Statamic.booting(function () { + Statamic.$components.register("cp-listing", _components_TCListing__WEBPACK_IMPORTED_MODULE_0__["default"]); +}); + +/***/ }), + +/***/ "./vendor/statamic/cms/resources/js/components/Listing.vue": +/*!*****************************************************************!*\ + !*** ./vendor/statamic/cms/resources/js/components/Listing.vue ***! + \*****************************************************************/ +/*! exports provided: default */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _Listing_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Listing.vue?vue&type=script&lang=js& */ "./vendor/statamic/cms/resources/js/components/Listing.vue?vue&type=script&lang=js&"); +/* empty/unused harmony star reexport *//* harmony import */ var _node_modules_vue_loader_lib_runtime_componentNormalizer_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js */ "./node_modules/vue-loader/lib/runtime/componentNormalizer.js"); +var render, staticRenderFns + + + + +/* normalize component */ + +var component = Object(_node_modules_vue_loader_lib_runtime_componentNormalizer_js__WEBPACK_IMPORTED_MODULE_1__["default"])( + _Listing_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_0__["default"], + render, + staticRenderFns, + false, + null, + null, + null + +) + +/* hot reload */ +if (false) { var api; } +component.options.__file = "vendor/statamic/cms/resources/js/components/Listing.vue" +/* harmony default export */ __webpack_exports__["default"] = (component.exports); + +/***/ }), + +/***/ "./vendor/statamic/cms/resources/js/components/Listing.vue?vue&type=script&lang=js&": +/*!******************************************************************************************!*\ + !*** ./vendor/statamic/cms/resources/js/components/Listing.vue?vue&type=script&lang=js& ***! + \******************************************************************************************/ +/*! exports provided: default */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _node_modules_babel_loader_lib_index_js_ref_4_0_node_modules_vue_loader_lib_index_js_vue_loader_options_Listing_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../../../../../node_modules/babel-loader/lib??ref--4-0!../../../../../../node_modules/vue-loader/lib??vue-loader-options!./Listing.vue?vue&type=script&lang=js& */ "./node_modules/babel-loader/lib/index.js?!./node_modules/vue-loader/lib/index.js?!./vendor/statamic/cms/resources/js/components/Listing.vue?vue&type=script&lang=js&"); +/* empty/unused harmony star reexport */ /* harmony default export */ __webpack_exports__["default"] = (_node_modules_babel_loader_lib_index_js_ref_4_0_node_modules_vue_loader_lib_index_js_vue_loader_options_Listing_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_0__["default"]); + +/***/ }), + +/***/ "./vendor/statamic/cms/resources/js/components/data-list/HasActions.js": +/*!*****************************************************************************!*\ + !*** ./vendor/statamic/cms/resources/js/components/data-list/HasActions.js ***! + \*****************************************************************************/ +/*! exports provided: default */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony default export */ __webpack_exports__["default"] = ({ + props: { + runActionUrl: String, + bulkActionsUrl: String + }, + methods: { + actionStarted: function actionStarted() { + this.loading = true; + }, + actionCompleted: function actionCompleted() { + var successful = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + this.loading = false; + if (successful === false) return; + this.$events.$emit('clear-selections'); + this.$events.$emit('reset-action-modals'); + this.$toast.success(__('Action completed')); + this.request(); + } + } +}); + +/***/ }), + +/***/ "./vendor/statamic/cms/resources/js/components/data-list/HasFilters.js": +/*!*****************************************************************************!*\ + !*** ./vendor/statamic/cms/resources/js/components/data-list/HasFilters.js ***! + \*****************************************************************************/ +/*! exports provided: default */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony default export */ __webpack_exports__["default"] = ({ + data: function data() { + return { + activePreset: null, + activePresetPayload: {}, + searchQuery: '', + activeFilters: {}, + activeFilterBadges: {} + }; + }, + computed: { + activeFilterCount: function activeFilterCount() { + var count = Object.keys(this.activeFilters).length; + + if (this.activeFilters.hasOwnProperty('fields')) { + count = count + Object.keys(this.activeFilters.fields).filter(function (field) { + return field != 'badge'; + }).length - 1; + } + + return count; + }, + hasActiveFilters: function hasActiveFilters() { + return this.activeFilterCount > 0; + } + }, + methods: { + searchChanged: function searchChanged(query) { + this.searchQuery = query; + }, + hasFields: function hasFields(values) { + for (var fieldHandle in values) { + if (values[fieldHandle]) return true; + } + + return false; + }, + filterChanged: function filterChanged(_ref) { + var handle = _ref.handle, + values = _ref.values; + var unselectAll = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + + if (values && this.hasFields(values)) { + Vue.set(this.activeFilters, handle, values); + } else { + Vue["delete"](this.activeFilters, handle); + } + + if (unselectAll) this.unselectAllItems(); + }, + filtersChanged: function filtersChanged(filters) { + this.activeFilters = {}; + + for (var handle in filters) { + var values = filters[handle]; + this.filterChanged({ + handle: handle, + values: values + }, false); + } + + this.unselectAllItems(); + }, + filtersReset: function filtersReset() { + this.activePreset = null; + this.activePresetPayload = {}; + this.searchQuery = ''; + this.activeFilters = {}; + this.activeFilterBadges = {}; + }, + unselectAllItems: function unselectAllItems() { + if (this.$refs.toggleAll) { + this.$refs.toggleAll.uncheckAllItems(); + } + }, + selectPreset: function selectPreset(handle, preset) { + this.activePreset = handle; + this.activePresetPayload = preset; + this.searchQuery = preset.query; + this.filtersChanged(preset.filters); + }, + autoApplyFilters: function autoApplyFilters(filters) { + if (!filters) return; + var values = {}; + filters.filter(function (filter) { + return !_.isEmpty(filter.auto_apply); + }).forEach(function (filter) { + values[filter.handle] = filter.auto_apply; + }); + this.activeFilters = values; + } + } +}); + +/***/ }), + +/***/ "./vendor/statamic/cms/resources/js/components/data-list/HasPagination.js": +/*!********************************************************************************!*\ + !*** ./vendor/statamic/cms/resources/js/components/data-list/HasPagination.js ***! + \********************************************************************************/ +/*! exports provided: default */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony default export */ __webpack_exports__["default"] = ({ + props: { + initialPerPage: { + type: Number, + "default": function _default() { + return Statamic.$config.get('paginationSize'); + } + } + }, + data: function data() { + return { + perPage: this.initialPerPage, + page: 1 + }; + }, + mounted: function mounted() { + this.setInitialPerPage(); + }, + methods: { + setInitialPerPage: function setInitialPerPage() { + if (!this.hasPreferences) { + return; + } + + this.perPage = this.getPreference('per_page') || this.initialPerPage; + }, + changePerPage: function changePerPage(perPage) { + var _this = this; + + perPage = parseInt(perPage); + var promise = this.hasPreferences ? this.setPreference('per_page', perPage != this.initialPerPage ? perPage : null) : Promise.resolve(); + promise.then(function (response) { + _this.perPage = perPage; + + _this.resetPage(); + }); + }, + selectPage: function selectPage(page) { + this.page = page; + }, + resetPage: function resetPage() { + this.page = 1; + } + } +}); + +/***/ }), + +/***/ "./vendor/statamic/cms/resources/js/components/data-list/HasPreferences.js": +/*!*********************************************************************************!*\ + !*** ./vendor/statamic/cms/resources/js/components/data-list/HasPreferences.js ***! + \*********************************************************************************/ +/*! exports provided: default */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony default export */ __webpack_exports__["default"] = ({ + data: function data() { + return { + preferencesPrefix: null + }; + }, + computed: { + hasPreferences: function hasPreferences() { + return this.preferencesPrefix !== null; + } + }, + methods: { + preferencesKey: function preferencesKey(type) { + return "".concat(this.preferencesPrefix, ".").concat(type); + }, + getPreference: function getPreference(type) { + return this.$preferences.get(this.preferencesKey(type)); + }, + setPreference: function setPreference(type, value) { + return this.$preferences.set(this.preferencesKey(type), value); + }, + removePreference: function removePreference(type) { + var value = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; + return this.$preferences.remove(this.preferencesKey(type), value); + } + } +}); + +/***/ }), + +/***/ 0: +/*!**********************************!*\ + !*** multi ./resources/js/cp.js ***! + \**********************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +module.exports = __webpack_require__(/*! /var/www/oopla/resources/js/cp.js */"./resources/js/cp.js"); + + +/***/ }) + +/******/ }); \ No newline at end of file diff --git a/resources/js/components/CPListing.vue b/resources/js/components/CPListing.vue new file mode 100644 index 0000000..03abf5a --- /dev/null +++ b/resources/js/components/CPListing.vue @@ -0,0 +1,127 @@ + + + \ No newline at end of file diff --git a/resources/js/components/DeletesListingRow.js b/resources/js/components/DeletesListingRow.js new file mode 100644 index 0000000..139ba6c --- /dev/null +++ b/resources/js/components/DeletesListingRow.js @@ -0,0 +1,48 @@ +export default { + data() { + return { + deletingRow: false, + }; + }, + + computed: { + deletingModalTitle() { + return this.deletingModalTitleFromRowKey("source"); + }, + }, + + methods: { + confirmDeleteRow(id, index) { + this.deletingRow = { id, index }; + }, + + deletingModalTitleFromRowKey(key) { + return __("Delete") + " " + this.rows[this.deletingRow.index][key]; + }, + + deleteRow(resourceRoute, message) { + const id = this.deletingRow.id; + message = message || __("Deleted"); + + this.$axios + .delete(cp_url(`${resourceRoute}/${id}`)) + .then(() => { + let i = _.indexOf(this.rows, _.findWhere(this.rows, { id })); + this.rows.splice(i, 1); + this.deletingRow = false; + this.$toast.success(message); + + location.reload(); + }) + .catch((e) => { + this.$toast.error( + e.response ? e.response.data.message : __("Something went wrong") + ); + }); + }, + + cancelDeleteRow() { + this.deletingRow = false; + }, + }, +}; \ No newline at end of file diff --git a/resources/js/components/fieldtypes/ExampleFieldtype.vue b/resources/js/components/fieldtypes/ExampleFieldtype.vue new file mode 100644 index 0000000..1293e4e --- /dev/null +++ b/resources/js/components/fieldtypes/ExampleFieldtype.vue @@ -0,0 +1,15 @@ + + + diff --git a/resources/js/cp.js b/resources/js/cp.js new file mode 100644 index 0000000..18d64ef --- /dev/null +++ b/resources/js/cp.js @@ -0,0 +1,4 @@ +import CPListing from "./components/CPListing"; +Statamic.booting(() => { + Statamic.$components.register("cp-listing", CPListing); +}); diff --git a/src/ServiceProvider.php b/src/ServiceProvider.php new file mode 100644 index 0000000..6a290cf --- /dev/null +++ b/src/ServiceProvider.php @@ -0,0 +1,13 @@ +