Skip to content

Commit

Permalink
[7.x] Tidy up Vue components (#585)
Browse files Browse the repository at this point in the history
  • Loading branch information
duncanmcclean authored Aug 14, 2024
1 parent d57f964 commit 1f0acc6
Show file tree
Hide file tree
Showing 10 changed files with 107 additions and 166 deletions.
Original file line number Diff line number Diff line change
@@ -1,17 +1,25 @@
<template>

<!--
This component is *mostly* the same as the one in Statamic Core, however with one difference:
it swaps out the 'fields' string with 'runway-fields' to avoid breaking the Fields filter on Entry Listing Tables.
See https://github.com/statamic-rad-pack/runway/pull/292 for more info.
-->

<div class="shadow-inner bg-gray-300 dark:bg-dark-600">
<div class="flex items-center flex-wrap px-3 border-b dark:border-dark-900 pt-2">

<!-- Field filter (requires custom selection UI) -->
<popover v-if="fieldFilter" placement="bottom-start" @closed="fieldFilterClosed">
<template slot="trigger">
<button class="filter-badge filter-badge-control mr-2 mb-2" @click="resetFilterPopover">
<button class="filter-badge filter-badge-control rtl:ml-2 ltr:mr-2 mb-2" @click="resetFilterPopover">
{{ fieldFilter.title }}
<svg-icon name="micro/chevron-down-xs" class="w-2 h-2 mx-2" />
</button>
</template>
<template #default="{ close: closePopover }">
<div class="flex flex-col text-left min-w-[18rem]">
<div class="flex flex-col rtl:text-right ltr:text-left min-w-[18rem]">
<div class="filter-fields text-sm">
<field-filter
ref="fieldFilter"
Expand All @@ -30,7 +38,7 @@
<!-- Standard pinned filters -->
<popover v-if="pinnedFilters.length" v-for="filter in pinnedFilters" :key="filter.handle" placement="bottom-start" :stop-propagation="false">
<template slot="trigger">
<button class="filter-badge filter-badge-control mr-2 mb-2">
<button class="filter-badge filter-badge-control rtl:ml-2 ltr:mr-2 mb-2">
{{ filter.title }}
<svg-icon name="micro/chevron-down-xs" class="w-2 h-2 mx-2" />
</button>
Expand All @@ -51,7 +59,7 @@
<!-- Standard unpinned filters -->
<popover v-if="unpinnedFilters.length" placement="bottom-start" :stop-propagation="false">
<template slot="trigger">
<button class="filter-badge filter-badge-control mr-2 mb-2" @click="resetFilterPopover">
<button class="filter-badge filter-badge-control rtl:ml-2 ltr:mr-2 mb-2" @click="resetFilterPopover">
{{ __('Filter') }}
<svg-icon name="micro/chevron-down-xs" class="w-2 h-2 mx-2" />
</button>
Expand Down Expand Up @@ -85,11 +93,11 @@
</popover>

<!-- Active filter badges -->
<div class="filter-badge mr-2 mb-2" v-for="(badge, handle) in fieldFilterBadges">
<div class="filter-badge rtl:ml-2 ltr:mr-2 mb-2" v-for="(badge, handle) in fieldFilterBadges">
<span>{{ badge }}</span>
<button @click="removeFieldFilter(handle)" v-tooltip="__('Remove Filter')">&times;</button>
</div>
<div class="filter-badge mr-2 mb-2" v-for="(badge, handle) in standardBadges">
<div class="filter-badge rtl:ml-2 ltr:mr-2 mb-2" v-for="(badge, handle) in standardBadges">
<span>{{ badge }}</span>
<button @click="removeStandardFilter(handle)" v-tooltip="__('Remove Filter')">&times;</button>
</div>
Expand Down Expand Up @@ -208,7 +216,7 @@ export default {
},
savingPresetHandle() {
return this.$slugify(this.savingPresetName, '_');
return snake_case(this.savingPresetName);
},
isUpdatingPreset() {
Expand Down Expand Up @@ -255,15 +263,15 @@ export default {
delete fields[handle];
this.$emit('changed', {handle: 'runway-fields', values: fields});
this.$emit('changed', { handle: 'runway-fields', values: fields });
},
removeStandardFilter(handle) {
this.$emit('changed', {handle: handle, values: null});
this.$emit('changed', { handle: handle, values: null });
},
save() {
if (! this.canSave || ! this.preferencesPayload) return;
if (!this.canSave || !this.preferencesPayload) return;
this.saving = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@
:column-preferences-key="preferencesKey('columns')"
@sorted="sorted"
>
<template :slot="primaryColumn" slot-scope="{ row: model, value }">
<template :slot="`cell-${primaryColumn}`" slot-scope="{ row: model, value }">
<a class="title-index-field inline-flex items-center" :href="model.edit_url" @click.stop>
<span class="little-dot rtl:ml-2 ltr:mr-2" v-tooltip="getStatusLabel(model)" :class="getStatusClass(model)" v-if="hasPublishStates && ! columnShowing('status')" />
<span v-text="value" />
Expand All @@ -110,42 +110,15 @@
<div class="status-index-field select-none" v-tooltip="getStatusTooltip(model)" :class="`status-${model.status}`" v-text="getStatusLabel(model)" />
</template>

<template
slot="actions"
slot-scope="{ row, index }"
>
<dropdown-list
v-if="
canViewRow(row) ||
canEditRow(row) ||
row.actions.length
"
>
<dropdown-item
v-if="canViewRow(row)"
:text="__('View')"
:redirect="row.permalink"
/>

<dropdown-item
v-if="canEditRow(row)"
:text="__('Edit')"
:redirect="row.edit_url"
/>

<div
class="divider"
v-if="
(canViewRow(row) ||
canEditRow(row)) &&
row.actions.length
"
/>

<template slot="actions" slot-scope="{ row: model, index }">
<dropdown-list v-if="(model.viewable && model.permalink) || model.editable || model.actions.length">
<dropdown-item v-if="model.viewable && model.permalink" :text="__('View')" :external-link="model.permalink" />
<dropdown-item v-if="model.editable" :text="__('Edit')" :redirect="model.edit_url" />
<div v-if="((model.viewable && model.permalink) || model.editable) && model.actions.length" class="divider" />
<data-list-inline-actions
:item="row.id"
:item="model.id"
:url="actionUrl"
:actions="row.actions"
:actions="model.actions"
@started="actionStarted"
@completed="actionCompleted"
/>
Expand All @@ -154,18 +127,6 @@
</template>
</data-list-table>
</div>

<confirmation-modal
v-if="deletingRow !== false"
:title="__('Delete')"
:bodyText="
__('Are you sure you want to delete this item?')
"
:buttonText="__('Delete')"
:danger="true"
@confirm="deleteRow()"
@cancel="cancelDeleteRow"
></confirmation-modal>
</div>

<data-list-pagination
Expand All @@ -182,7 +143,7 @@

<script>
import Listing from '../../../../vendor/statamic/cms/resources/js/components/Listing.vue'
import DataListFilters from './DataListFilters.vue'
import DataListFilters from '../data-list/Filters.vue'
export default {
mixins: [Listing],
Expand All @@ -192,21 +153,16 @@ export default {
},
props: {
listingConfig: Object,
initialColumns: Array,
actionUrl: String,
initialPrimaryColumn: String,
resource: String,
primaryColumn: String,
hasPublishStates: Boolean,
},
data() {
return {
listingKey: 'id',
preferencesPrefix: this.listingConfig.preferencesPrefix ?? 'runway',
requestUrl: this.listingConfig.requestUrl,
columns: this.initialColumns,
meta: {},
primaryColumn: `cell-${this.initialPrimaryColumn}`,
listingKey: 'models',
preferencesPrefix: `runway.${this.resource}`,
requestUrl: cp_url(`runway/${this.resource}/listing-api`),
deletingRow: false,
}
},
Expand Down Expand Up @@ -239,56 +195,6 @@ export default {
columnShowing(column) {
return this.visibleColumns.find(c => c.field === column);
},
canViewRow(row) {
return row.viewable && row.permalink
},
canEditRow(row) {
return row.editable
},
confirmDeleteRow(id, index, deleteUrl) {
this.visibleColumns = this.columns.filter(
(column) => column.visible
)
this.deletingRow = { id, index, deleteUrl }
},
deleteRow(message) {
const id = this.deletingRow.id
message = message || __('Deleted')
this.$axios
.delete(this.deletingRow.deleteUrl)
.then(() => {
let i = _.indexOf(
this.items,
_.findWhere(this.rows, { id })
)
this.items.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
setTimeout(() => {
this.visibleColumns = this.columns.filter(
(column) => column.visible
)
}, 50)
},
},
}
</script>
49 changes: 49 additions & 0 deletions resources/js/components/resources/View.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<template>
<div>
<header class="mb-6">
<div class="flex items-center">
<h1 class="flex-1" v-text="__(title)" />

<div>
<a v-if="canCreate" class="btn-primary" :href="createUrl" v-text="createLabel" />
</div>
</div>
</header>

<runway-listing
:resource="handle"
:initial-sort-column="sortColumn"
:initial-sort-direction="sortDirection"
:initial-columns="columns"
:filters="filters"
:action-url="actionUrl"
:primary-column="primaryColumn"
:has-publish-states="hasPublishStates"
></runway-listing>
</div>
</template>

<script>
import RunwayListing from './Listing.vue'
export default {
components: {
RunwayListing,
},
props: {
title: { type: String, required: true },
handle: { type: String, required: true },
canCreate: { type: Boolean, required: true },
createUrl: { type: String, required: true },
createLabel: { type: String, required: true },
sortColumn: { type: String, required: true },
sortDirection: { type: String, required: true },
columns: { type: Array, required: true },
filters: { type: Array, required: true },
actionUrl: { type: String, required: true },
primaryColumn: { type: String, required: true},
hasPublishStates: { type: Boolean, required: true },
},
}
</script>
8 changes: 3 additions & 5 deletions resources/js/cp.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import PublishForm from './components/Publish/PublishForm.vue'
import RunwayListing from './components/Listing/RunwayListing.vue'
import HasManyFieldtypeIndex from '../../vendor/statamic/cms/resources/js/components/fieldtypes/relationship/RelationshipIndexFieldtype.vue'
import PublishForm from './components/resources/PublishForm.vue'
import ResourceView from './components/resources/View.vue'

Statamic.$components.register('runway-publish-form', PublishForm)
Statamic.$components.register('runway-listing', RunwayListing)
Statamic.$components.register('has_many-fieldtype-index', HasManyFieldtypeIndex)
Statamic.$components.register('resource-view', ResourceView)
42 changes: 14 additions & 28 deletions resources/views/index.blade.php
Original file line number Diff line number Diff line change
@@ -1,36 +1,22 @@
@inject('str', 'Statamic\Support\Str')
@extends('statamic::layout')
@section('title', $title)
@section('title', $resource->name())
@section('wrapper_class', 'max-w-full')

@section('content')
<div class="flex items-center justify-between mb-6">
<h1 class="flex-1">{{ $title }}</h1>

@can('configure fields')
<dropdown-list @if($canCreate) class="mr-2" @endif>
<dropdown-item :text="__('Edit Blueprint')" redirect="{{ cp_route('blueprints.edit', ['namespace' => 'runway', 'handle' => $resource->handle()]) }}"></dropdown-item>
</dropdown-list>
@endcan

@if($canCreate)
<a
class="btn-primary"
href="{{ cp_route('runway.create', ['resource' => $resource->handle()]) }}"
>
{{ __('Create :resource', [
'resource' => $resource->singular()
]) }}
</a>
@endif
</div>

<runway-listing
<resource-view
title="{{ $resource->name() }}"
handle="{{ $resource->handle() }}"
:can-create="{{ Statamic\Support\Str::bool($canCreate) }}"
create-url="{{ $createUrl }}"
create-label="{{ $createLabel }}"
sort-column="{{ $resource->orderBy() }}"
sort-direction="{{ $resource->orderByDirection() }}"
:columns="{{ $columns->toJson() }}"
:filters="{{ $filters->toJson() }}"
:listing-config='@json($listingConfig)'
:initial-columns='@json($columns)'
action-url="{{ $actionUrl }}"
initial-primary-column="{{ $primaryColumn }}"
:has-publish-states="{{ $str::bool($hasPublishStates) }}"
></runway-listing>
primary-column="{{ $primaryColumn }}"
:has-publish-states="{{ Statamic\Support\Str::bool($resource->hasPublishStates()) }}"
></resource-view>

@endsection
2 changes: 2 additions & 0 deletions src/Fieldtypes/HasManyFieldtype.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

class HasManyFieldtype extends BaseFieldtype
{
protected $indexComponent = 'relationship';

protected function configFieldItems(): array
{
$config = [
Expand Down
Loading

0 comments on commit 1f0acc6

Please sign in to comment.