mirror of
https://github.com/directus/directus.git
synced 2026-02-16 20:41:27 -05:00
🌊 Add Data Flows to Directus 🌊 (#12522)
* Replace attachment with correct icon
* Use standardized options formatting
* Improve preview styling, fix names
* Format IDs of DB read operation as csv
* Remove flow active state from header
* Don't return null for unknown flows
* Fix webhook trigger not showing id
* Fix alignment of attachment
* Make heading secondary if it's the reject handler
* Use flow name in subtitle of operation drawer
* Rename "Create new Operation" -> "Create Operation"
* Make name/key required
* Give name autofocus
* Add "uncaught exception" log message
* Various improvements on operations
* default status to "active"
* Add status dropdown at the bottom of trigger
* put status dot to the right of flow name header
* add toggle status option in context menu
* fix trigger options staging
* fix flow deletion
* show configured operation key on name hover
* prevent block pushing status toggle down
* ensure key is unique between operations in a flow
* allow add new panel when previous one is deleted
* fix staged panels temporarily disappear
The deletion of newTree.id causes it to "disconnect" when saving, thus causing it seemingly disappear. Using a cloneDeep prevents it from mutating the current stagedPanels
* hide key input when in query mode
* add write operation
* undo previous route props change
* include staged panel keys in key validation
* fix key validation logic
* add color to flow & insights
* ensure trigger does not have reject button
* prevent operation key error showing up when saving
* change context menu to Delete Operation
* fix add operation when removed operation is staged
* Hide ID in read preview when in query mode
* fix reject button showing without edit mode
* fix status toggle in flow overview
* simplify request operation methods & allow other
* fix preview function type
* simplify slot syntax
* add manual trigger
* simplify manual trigger handler
* prevent drawer closing on esc
* allow filter config without selecting collection
* improve affordance of add operation button
* fix loner reject button color
* Added emitEvents option to write operation (#13121)
* added emitEvent option toggle to write operation
* Re-gen package-lock
Co-authored-by: rijkvanzanten <rijkvanzanten@me.com>
* Clean up active/inactive toggle
* Align arrow to grid
* Visually align border radius of glow
* Tweak padding of footer in panels
* Remove init event
* Combine event triggers into single "Hook" trigger
* Fix mail operation
* Cleanup imports, return undefined for webhook executino flows
* Add border to panel footer
* Upgrade preview of hook trigger
* Don't warn on uncaught flow executions
* Clean up types
* Fix typing of reload
* Default to correct icon
* Add migrations to remove webhooks table
* Remove webhooks
* Update icons for triggers
* Reorganize triggers
* Merge flows and webhooks migrations
* Add permissions option to database read operatoin
* Add permissions configuration to database write
* Remove flow logs in favor of using directus_activity
* Upgrade webhook configuration, fix create operatoin
* Rename validation->condition
* Subdue everything when inactive
* Tweak tests
* Fix the test for real
* Remove circular FK trigger, please MSSQL
* Make things worse to please MSFT
* Add input
* Drop input scope from condition operation
* naming and description changes
* Default flow overview icon color to primary
* add danger styling to delete flow button
* fix hint buttons subdued style
* Hide trigger unlinked resolve btn when not editing
Don't show "check mark icon" or "operation arrow" on empty trigger when NOT in edit mode
* show email "to" value as CSV
* remove unused webhook.preview translation
* Default sort order of overview table to `name`
* Track activity / revisions in flows
* Extract w/ the intent to reuse revisions fetching
* Move Action type to shared to facilitate app use
* [WIP] Start rendering logs drawer from sidebar
* Fix type error (sorry Eron)
* add update operation
* add delete operation
* use parseJSON util in operations
* Add missing fields to flows system data
* Await promise in sleep operation
* fix e2e test missing flows & operations tables
* Add fallback title to flow logs drawer
* Add default value to flow prop for flow-dialog
* Hydrate flows store before moving to details page when creating flow
* Rename CRUD operations to item-*
* Change trigger options subtitle to Trigger Options
* Remove trigger name option
* Fix typescript complaining
* Remove two lines
* Fix notification operation
* Log error when executing a schedule flow
* Fix schedule flow activity tracking
* Fix notification operation when there is no user
* Make permissions for notifications configurable
* Do not drop non null constraint from column that is nullable
* Remove invalid option from activity seed
* Show resolve/reject dot when operation has successor
* Improve flow arrow placement
* Prevent arrow color from flickering
* Fix arrow being stuck when hovered while saving
* Fix arrows not being subdued on lone leaf operations
* Add tooltips to operation handles
* Remove option to trigger flow on init
* Move operation handle tooltip to icon
* Disconnect duplicated operation
* Fix deleting connected operations
* Make delete action name generic in v-workspace-panel
* Use flow-specific wording in flow edit tooltip
* Simplify hint handle check
* Fix deleting first operation
* Use useEditsGuard composable in flow component
* Add asynchronous option to webhook trigger
* Add option to make preview elements copyable
* Add hover transition to panels
* Register operation preview components as operation-preview-*
* Remove selectability of panel header and operation body
* Add return option to filter and operation triggers
* Add missing key
* Remove unnecessary ampersand from URLs in filter tests (#13523)
* Remove unused prop
* New translations en-US.yaml (Polish) (#13524)
* My favorite
* v9.11.1
* v9.11.1
* New translations en-US.yaml (Polish) (#13528)
* New translations en-US.yaml (Czech) (#13541)
* New translations en-US.yaml (Czech) (#13545)
* fix metadata for directus_folders (#13527)
* add `meta` to list responses for OAS (#13531)
* remove existing pasting check on slug values (#13532)
* Add copy button to user id on user info page (#13540)
* New translations en-US.yaml (Czech) (#13547)
* New translations en-US.yaml (Czech) (#13548)
* Added missing "DB_SSL_*_FILE" to the "_FILE" allow list. (#13539)
* Remove workaround in release flow (#13455)
This forces the release workflow to use `node@16.15` which includes `npm@8.5`.
* Remove npmrc files which prevent lockfile creation in workspaces (#13444)
* Remove npmrc files which prevent lockfile creation in workspaces
Since `v8.5.0` npm will detect that it is running inside a workspace and issue commands at the root package.
* Require a minimum npm version of 8.5.0
* Package-lock 🖤
* Don't consider SIGN_OUT an SSO error (#13389)
* Don't consider SIGN_OUT an SSO error
* Add SESSION_EXPIRED as valid reason
* Improve translation for require_value_to_be_set (#13363)
English + Dutch
Co-authored-by: Rijk van Zanten <rijkvanzanten@me.com>
* Fix field conditions optionDefaults computed property (#13563)
* fix: remove .value from options
* additional ref fix & type/null errors
Co-authored-by: Azri Kahar <42867097+azrikahar@users.noreply.github.com>
* `last_page` type was `date` instead of `str` (#13577)
* `last_page` type was `date` instead of `str`
* Update docs/reference/system/users.md
Co-authored-by: Rijk van Zanten <rijkvanzanten@me.com>
* New Crowdin updates (#13557)
* New translations en-US.yaml (Romanian)
* New translations en-US.yaml (Indonesian)
* New translations en-US.yaml (Spanish, Chile)
* New translations en-US.yaml (Thai)
* New translations en-US.yaml (Spanish, Latin America)
* New translations en-US.yaml (Russian)
* New translations en-US.yaml (Polish)
* New translations en-US.yaml (Swedish)
* New translations en-US.yaml (Turkish)
* New translations en-US.yaml (Portuguese, Brazilian)
* New translations en-US.yaml (French)
* New translations en-US.yaml (Spanish)
* New translations en-US.yaml (Bulgarian)
* New translations en-US.yaml (Catalan)
* New translations en-US.yaml (Danish)
* New translations en-US.yaml (German)
* New translations en-US.yaml (Finnish)
* New translations en-US.yaml (Hungarian)
* New translations en-US.yaml (Chinese Simplified)
* New translations en-US.yaml (Italian)
* New translations en-US.yaml (Slovenian)
* New translations en-US.yaml (Ukrainian)
* New translations en-US.yaml (English, United Kingdom)
* New translations en-US.yaml (English, Canada)
* New translations en-US.yaml (French, Canada)
* New translations en-US.yaml (Croatian)
* New translations en-US.yaml (Czech)
* New translations en-US.yaml (Czech)
* New translations en-US.yaml (Czech)
* New translations en-US.yaml (Czech)
* New translations en-US.yaml (Czech)
* New translations en-US.yaml (Czech)
* New translations en-US.yaml (Czech)
* New translations en-US.yaml (Czech)
* New translations en-US.yaml (Czech)
* New translations en-US.yaml (Czech)
* New translations en-US.yaml (Czech)
* New translations en-US.yaml (Czech)
* New translations en-US.yaml (Czech)
* New translations en-US.yaml (Czech)
* New translations en-US.yaml (Czech)
* Fix validate query number comparison
Ref https://github.com/directus/directus/pull/13492#issuecomment-1138770254
* New translations en-US.yaml (Polish) (#13580)
* add to project (#13581)
* Allow authentication using MSSQL azure-active-directory-service-principal-secret (#11141)
* Extract ignored settings requires by azure authentication
* Change the way to extract initial database settings
* Fix invalid names after extracting from env util
* Replace missing var after solving conflicts
* Add default value to poolconfig
* This should unbreak it
Co-authored-by: Rijk van Zanten <rijkvanzanten@me.com>
* Create pull_request_template.md
* Update pull_request_template.md
* Add System token interface (#13549)
* Add system token interface
* use system token interface in users token field
* Update placeholder
* move notice below input
* fix clear value interaction
* update placeholder and notice text
* remove unused translation key
* rename class to match current naming
* fix bugs in disabled state and it's UX
Co-authored-by: Rijk van Zanten <rijkvanzanten@me.com>
Co-authored-by: jaycammarano <jay.cammarano@gmail.com>
* New Crowdin updates (#13586)
* New translations en-US.yaml (Romanian)
* New translations en-US.yaml (Indonesian)
* New translations en-US.yaml (Spanish, Chile)
* New translations en-US.yaml (Thai)
* New translations en-US.yaml (Serbian (Latin))
* New translations en-US.yaml (Spanish, Latin America)
* New translations en-US.yaml (Russian)
* New translations en-US.yaml (Polish)
* New translations en-US.yaml (Portuguese)
* New translations en-US.yaml (Swedish)
* New translations en-US.yaml (Turkish)
* New translations en-US.yaml (Estonian)
* New translations en-US.yaml (Portuguese, Brazilian)
* New translations en-US.yaml (French)
* New translations en-US.yaml (Spanish)
* New translations en-US.yaml (Bulgarian)
* New translations en-US.yaml (Catalan)
* New translations en-US.yaml (Czech)
* New translations en-US.yaml (Danish)
* New translations en-US.yaml (German)
* New translations en-US.yaml (Finnish)
* New translations en-US.yaml (Hungarian)
* New translations en-US.yaml (Chinese Simplified)
* New translations en-US.yaml (Italian)
* New translations en-US.yaml (Japanese)
* New translations en-US.yaml (Dutch)
* New translations en-US.yaml (Slovenian)
* New translations en-US.yaml (Ukrainian)
* New translations en-US.yaml (English, United Kingdom)
* New translations en-US.yaml (English, Canada)
* New translations en-US.yaml (French, Canada)
* New translations en-US.yaml (Croatian)
* Add project_url to defaultTemplateData (#12033)
Might be useful in template footers.
* Update items.md
* Rename panel to tile
* Rename preview->overview
* Style flow log detail
* Log all parsed options
* Show used options in revision
* Finish log detail drawer
* new create flow flow
* fix firstOpen for new create flow flow
* update field layout for create flow form
* Fix TS typing
* Fix missing import
* Append random hash to key when duplicating operations
* Revert "Remove webhooks"
This reverts commit 044d3d8b66.
* Don't delete webhooks
* Make option preview selectable
* Prevent invalid linking when duplicating operations after creating operations
* Prevent sending of malformed query filter when deleting flow
* implement new manual trigger
* simplify payload for manual trigger
* use buttons instead of dropdown + run button
* add async option & loading state
* add collection check to manual trigger
* emit refresh after running flow in sidebar
* Add cross-instance messenger for reloading
* Use flow drawer for both create and edit
* Add manual trigger flow permissions to app recommended
Ensures that non-admin users can actually see the flows sidebar detail
* Add basic logs redaction
* Remove endpoint to trigger an operation
* Allow configuring location for manual trigger
* Rename "hook" trigger to "event"
* Tweak icon size
* Fix create flow button in info notice
* Make activity tracking full width
* Tweak descriptions
* Too long for comfort
* Remove mode option from item-* operations
* fix manual trigger empty collections option
* Add no-logs-yet message in sidebar detail
* Reset trigger options on change of trigger
* Rename `data`->`payload`
* Remove mode from preview of item-* operations
* Return operation options with "{{key}}" as raw value
* Show flow name in delete confirmation
* Add default generated name/key to new operations
* shorten arrows WIP
still needs icons moved
* rename note to description
* fix hint button icons
* update event hook type labels
* Animate resolve/reject arrow hints
* reorder event types
* Use x+4 instead of x+6 for new operation panels
* compress options to fit 6 lines in operation
* update hook labels
* animate trigger box shadow
sorry, rijk!
* update (global) disabled button color 1 shade
* Format times nicer
* Add placeholder for query
* add a note
* Fix formatting for curly brackets in translations
* Add item Create/update payload placeholder
* Add placeholder to user uuid
* Accept either null or undefined for nullable operation options
* Allow any string as request body
* Add more placeholders
* Consolidate filterScope and actionScope, filterCollections and actionCollections
* Rename flow note to description in types
Co-authored-by: rijkvanzanten <rijkvanzanten@me.com>
Co-authored-by: Azri Kahar <42867097+azrikahar@users.noreply.github.com>
Co-authored-by: Brainslug <br41nslug@users.noreply.github.com>
Co-authored-by: Ben Haynes <ben@rngr.org>
Co-authored-by: Nicola Krumschmidt <nicola.krumschmidt@freenet.de>
Co-authored-by: Aiden Foxx <aiden.foxx.mail@gmail.com>
Co-authored-by: Jan-Willem <jan-willem@qdentity.nl>
Co-authored-by: Yasser Lahbibi <yasser.lahbibi@apenhet.com>
Co-authored-by: Louis <32719150+louisgavalda@users.noreply.github.com>
Co-authored-by: Jay Cammarano <67079013+jaycammarano@users.noreply.github.com>
Co-authored-by: Erick Torres <ericktorresh@gmail.com>
Co-authored-by: jaycammarano <jay.cammarano@gmail.com>
Co-authored-by: Yuriy Belenko <yura-bely@mail.ru>
Co-authored-by: ian <licitdev@gmail.com>
This commit is contained in:
110
app/src/views/private/components/flow-sidebar-detail.vue
Normal file
110
app/src/views/private/components/flow-sidebar-detail.vue
Normal file
@@ -0,0 +1,110 @@
|
||||
<template>
|
||||
<sidebar-detail v-if="manualFlows.length > 0" icon="bolt" :title="t('flows')">
|
||||
<div class="fields">
|
||||
<div v-for="manualFlow in manualFlows" :key="manualFlow.id" class="field full">
|
||||
<v-button
|
||||
v-tooltip="primaryKey ? t('run_flow_on_current') : t('run_flow_on_selected', selection.length)"
|
||||
small
|
||||
full-width
|
||||
:loading="runningFlows.includes(manualFlow.id)"
|
||||
:disabled="!primaryKey && selection.length === 0"
|
||||
@click="runManualFlow(manualFlow.id)"
|
||||
>
|
||||
<v-icon :name="manualFlow.icon ?? 'bolt'" small left />
|
||||
{{ manualFlow.name }}
|
||||
</v-button>
|
||||
</div>
|
||||
</div>
|
||||
</sidebar-detail>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import api from '@/api';
|
||||
import { useFlowsStore } from '@/stores';
|
||||
import { notify } from '@/utils/notify';
|
||||
import { unexpectedError } from '@/utils/unexpected-error';
|
||||
import { useCollection } from '@directus/shared/composables';
|
||||
import { computed, ref, toRefs } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
interface Props {
|
||||
collection: string;
|
||||
primaryKey?: string;
|
||||
selection: (number | string)[];
|
||||
location: 'collection' | 'item';
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
primaryKey: undefined,
|
||||
selection: () => [],
|
||||
});
|
||||
|
||||
const emit = defineEmits(['refresh']);
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const { collection, primaryKey, selection } = toRefs(props);
|
||||
|
||||
const { primaryKeyField } = useCollection(collection);
|
||||
|
||||
const flowsStore = useFlowsStore();
|
||||
|
||||
const manualFlows = computed(() =>
|
||||
flowsStore
|
||||
.getManualFlowsForCollection(collection.value)
|
||||
.filter(
|
||||
(flow) =>
|
||||
!flow.options?.location || flow.options?.location === 'both' || flow.options?.location === props.location
|
||||
)
|
||||
);
|
||||
|
||||
const runningFlows = ref<string[]>([]);
|
||||
|
||||
async function runManualFlow(flowId: string) {
|
||||
const selectedFlow = manualFlows.value.find((flow) => flow.id === flowId);
|
||||
|
||||
if (!selectedFlow || !primaryKeyField.value) return;
|
||||
|
||||
runningFlows.value = [...runningFlows.value, flowId];
|
||||
|
||||
try {
|
||||
const keys = primaryKey.value ? [primaryKey.value] : selection.value;
|
||||
|
||||
await api.post(`/flows/trigger/${flowId}`, { collection: collection.value, keys });
|
||||
|
||||
emit('refresh');
|
||||
|
||||
notify({
|
||||
title: t('run_flow_success', { flow: selectedFlow.name }),
|
||||
});
|
||||
} catch (err: any) {
|
||||
unexpectedError(err);
|
||||
} finally {
|
||||
runningFlows.value = runningFlows.value.filter((runningFlow) => runningFlow !== flowId);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '@/styles/mixins/form-grid';
|
||||
|
||||
.fields {
|
||||
@include form-grid;
|
||||
}
|
||||
|
||||
.fields {
|
||||
--form-vertical-gap: 24px;
|
||||
|
||||
.type-label {
|
||||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.v-button) .button:disabled {
|
||||
--v-button-background-color-disabled: var(--background-normal-alt);
|
||||
}
|
||||
|
||||
.v-icon {
|
||||
margin-right: 8px;
|
||||
}
|
||||
</style>
|
||||
@@ -12,25 +12,17 @@
|
||||
</v-detail>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref } from 'vue';
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
|
||||
import RevisionItem from './revision-item.vue';
|
||||
|
||||
export default defineComponent({
|
||||
components: { RevisionItem },
|
||||
props: {
|
||||
group: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
emits: ['click'],
|
||||
setup() {
|
||||
const expand = ref(true);
|
||||
return { expand };
|
||||
},
|
||||
});
|
||||
</script>
|
||||
interface Props {
|
||||
group: Record<string, any>;
|
||||
}
|
||||
|
||||
<style scoped></style>
|
||||
defineProps<Props>();
|
||||
defineEmits(['click']);
|
||||
|
||||
const expand = ref(true);
|
||||
</script>
|
||||
|
||||
@@ -35,208 +35,47 @@
|
||||
</sidebar-detail>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
<script lang="ts" setup>
|
||||
import { useRevisions } from '@/composables/use-revisions';
|
||||
import { abbreviateNumber } from '@directus/shared/utils';
|
||||
import { ref, toRefs, watch } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { defineComponent, ref, watch } from 'vue';
|
||||
import { Revision, RevisionsByDate } from './types';
|
||||
|
||||
import api from '@/api';
|
||||
import { groupBy, orderBy } from 'lodash';
|
||||
import { isToday, isYesterday, isThisYear } from 'date-fns';
|
||||
import formatLocalized from '@/utils/localized-format';
|
||||
import RevisionsDateGroup from './revisions-date-group.vue';
|
||||
import RevisionsDrawer from './revisions-drawer.vue';
|
||||
import { unexpectedError } from '@/utils/unexpected-error';
|
||||
import { abbreviateNumber } from '@directus/shared/utils';
|
||||
|
||||
export default defineComponent({
|
||||
components: { RevisionsDrawer, RevisionsDateGroup },
|
||||
props: {
|
||||
collection: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
primaryKey: {
|
||||
type: [String, Number],
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
emits: ['revert'],
|
||||
setup(props) {
|
||||
const { t } = useI18n();
|
||||
interface Props {
|
||||
collection: string;
|
||||
primaryKey: string | number;
|
||||
}
|
||||
|
||||
const { revisions, revisionsByDate, loading, refresh, revisionsCount, pagesCount, created } = useRevisions(
|
||||
props.collection,
|
||||
props.primaryKey
|
||||
);
|
||||
const props = defineProps<Props>();
|
||||
|
||||
const modalActive = ref(false);
|
||||
const modalCurrentRevision = ref<number | null>(null);
|
||||
const page = ref<number>(1);
|
||||
defineEmits(['revert']);
|
||||
|
||||
watch(
|
||||
() => page.value,
|
||||
(newPage) => {
|
||||
refresh(newPage);
|
||||
}
|
||||
);
|
||||
const { t } = useI18n();
|
||||
|
||||
return {
|
||||
t,
|
||||
revisions,
|
||||
revisionsByDate,
|
||||
loading,
|
||||
refresh,
|
||||
modalActive,
|
||||
modalCurrentRevision,
|
||||
openModal,
|
||||
revisionsCount,
|
||||
created,
|
||||
page,
|
||||
pagesCount,
|
||||
abbreviateNumber,
|
||||
};
|
||||
const { collection, primaryKey } = toRefs(props);
|
||||
|
||||
function openModal(id: number) {
|
||||
modalCurrentRevision.value = id;
|
||||
modalActive.value = true;
|
||||
}
|
||||
const { revisions, revisionsByDate, loading, refresh, revisionsCount, pagesCount, created } = useRevisions(
|
||||
collection,
|
||||
primaryKey
|
||||
);
|
||||
|
||||
function useRevisions(collection: string, primaryKey: number | string) {
|
||||
const revisions = ref<Revision[] | null>(null);
|
||||
const revisionsByDate = ref<RevisionsByDate[] | null>(null);
|
||||
const loading = ref(false);
|
||||
const revisionsCount = ref(0);
|
||||
const created = ref<Revision>();
|
||||
const pagesCount = ref(0);
|
||||
const modalActive = ref(false);
|
||||
const modalCurrentRevision = ref<number | null>(null);
|
||||
const page = ref<number>(1);
|
||||
|
||||
getRevisions();
|
||||
watch(
|
||||
() => page.value,
|
||||
(newPage) => {
|
||||
refresh(newPage);
|
||||
}
|
||||
);
|
||||
|
||||
return { created, revisions, revisionsByDate, loading, refresh, revisionsCount, pagesCount };
|
||||
|
||||
async function getRevisions(page = 0) {
|
||||
loading.value = true;
|
||||
const pageSize = 100;
|
||||
|
||||
try {
|
||||
const response = await api.get(`/revisions`, {
|
||||
params: {
|
||||
filter: {
|
||||
collection: {
|
||||
_eq: collection,
|
||||
},
|
||||
item: {
|
||||
_eq: primaryKey,
|
||||
},
|
||||
},
|
||||
sort: '-id',
|
||||
limit: pageSize,
|
||||
page,
|
||||
fields: [
|
||||
'id',
|
||||
'data',
|
||||
'delta',
|
||||
'collection',
|
||||
'item',
|
||||
'activity.action',
|
||||
'activity.timestamp',
|
||||
'activity.user.id',
|
||||
'activity.user.email',
|
||||
'activity.user.first_name',
|
||||
'activity.user.last_name',
|
||||
'activity.ip',
|
||||
'activity.user_agent',
|
||||
],
|
||||
meta: ['filter_count'],
|
||||
},
|
||||
});
|
||||
|
||||
const createdResponse = await api.get(`/revisions`, {
|
||||
params: {
|
||||
filter: {
|
||||
collection: {
|
||||
_eq: collection,
|
||||
},
|
||||
item: {
|
||||
_eq: primaryKey,
|
||||
},
|
||||
activity: {
|
||||
action: {
|
||||
_eq: 'create',
|
||||
},
|
||||
},
|
||||
},
|
||||
sort: '-id',
|
||||
limit: 1,
|
||||
fields: [
|
||||
'id',
|
||||
'data',
|
||||
'delta',
|
||||
'collection',
|
||||
'item',
|
||||
'activity.action',
|
||||
'activity.timestamp',
|
||||
'activity.user.id',
|
||||
'activity.user.email',
|
||||
'activity.user.first_name',
|
||||
'activity.user.last_name',
|
||||
'activity.ip',
|
||||
'activity.user_agent',
|
||||
],
|
||||
meta: ['filter_count'],
|
||||
},
|
||||
});
|
||||
|
||||
created.value = createdResponse.data.data?.[0];
|
||||
|
||||
const revisionsGroupedByDate = groupBy(
|
||||
response.data.data.filter((revision: any) => !!revision.activity),
|
||||
(revision: Revision) => {
|
||||
// revision's timestamp date is in iso-8601
|
||||
const date = new Date(new Date(revision.activity.timestamp).toDateString());
|
||||
return date;
|
||||
}
|
||||
);
|
||||
|
||||
const revisionsGrouped: RevisionsByDate[] = [];
|
||||
|
||||
for (const [key, value] of Object.entries(revisionsGroupedByDate)) {
|
||||
const date = new Date(key);
|
||||
const today = isToday(date);
|
||||
const yesterday = isYesterday(date);
|
||||
const thisYear = isThisYear(date);
|
||||
|
||||
let dateFormatted: string;
|
||||
|
||||
if (today) dateFormatted = t('today');
|
||||
else if (yesterday) dateFormatted = t('yesterday');
|
||||
else if (thisYear) dateFormatted = await formatLocalized(date, String(t('date-fns_date_short_no_year')));
|
||||
else dateFormatted = await formatLocalized(date, String(t('date-fns_date_short')));
|
||||
|
||||
revisionsGrouped.push({
|
||||
date: date,
|
||||
dateFormatted: String(dateFormatted),
|
||||
revisions: orderBy(value, ['activity.timestamp'], ['desc']),
|
||||
});
|
||||
}
|
||||
|
||||
revisionsByDate.value = orderBy(revisionsGrouped, ['date'], ['desc']);
|
||||
revisions.value = orderBy(response.data.data, ['activity.timestamp'], ['desc']);
|
||||
revisionsCount.value = response.data.meta.filter_count;
|
||||
pagesCount.value = Math.ceil(revisionsCount.value / pageSize);
|
||||
} catch (err) {
|
||||
unexpectedError(err);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function refresh(page = 0) {
|
||||
await getRevisions(page);
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
function openModal(id: number) {
|
||||
modalCurrentRevision.value = id;
|
||||
modalActive.value = true;
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -58,8 +58,8 @@ export default defineComponent({
|
||||
|
||||
if (!name) return null;
|
||||
|
||||
const currentValue = props.revision.delta[fieldKey];
|
||||
const previousValue = previousRevision.value.data[fieldKey];
|
||||
const currentValue = props.revision.delta?.[fieldKey];
|
||||
const previousValue = previousRevision.value.data?.[fieldKey];
|
||||
|
||||
if (isEqual(currentValue, previousValue)) return null;
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ export type Revision = {
|
||||
last_name: string;
|
||||
};
|
||||
};
|
||||
timestampFormatted: string;
|
||||
};
|
||||
|
||||
export type RevisionsByDate = {
|
||||
|
||||
Reference in New Issue
Block a user