updated import popup handling and api preview examples
This commit is contained in:
parent
65b830198b
commit
d56b8fcb90
|
@ -190,23 +190,29 @@ func (dao *Dao) ImportCollections(
|
||||||
|
|
||||||
mappedImported := make(map[string]*models.Collection, len(importedCollections))
|
mappedImported := make(map[string]*models.Collection, len(importedCollections))
|
||||||
for _, imported := range importedCollections {
|
for _, imported := range importedCollections {
|
||||||
// normalize ids
|
|
||||||
if !imported.HasId() {
|
|
||||||
// generate id if not set
|
// generate id if not set
|
||||||
|
if !imported.HasId() {
|
||||||
imported.MarkAsNew()
|
imported.MarkAsNew()
|
||||||
imported.RefreshId()
|
imported.RefreshId()
|
||||||
} else if _, ok := mappedExisting[imported.GetId()]; !ok {
|
}
|
||||||
imported.MarkAsNew()
|
|
||||||
|
if existing, ok := mappedExisting[imported.GetId()]; ok {
|
||||||
|
// preserve original created date
|
||||||
|
if !existing.Created.IsZero() {
|
||||||
|
imported.Created = existing.Created
|
||||||
}
|
}
|
||||||
|
|
||||||
// extend existing schema
|
// extend existing schema
|
||||||
if existing, ok := mappedExisting[imported.GetId()]; ok && !deleteMissing {
|
if !deleteMissing {
|
||||||
schema, _ := existing.Schema.Clone()
|
schema, _ := existing.Schema.Clone()
|
||||||
for _, f := range imported.Schema.Fields() {
|
for _, f := range imported.Schema.Fields() {
|
||||||
schema.AddField(f) // add or replace
|
schema.AddField(f) // add or replace
|
||||||
}
|
}
|
||||||
imported.Schema = *schema
|
imported.Schema = *schema
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
imported.MarkAsNew()
|
||||||
|
}
|
||||||
|
|
||||||
mappedImported[imported.GetId()] = imported
|
mappedImported[imported.GetId()] = imported
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,14 +5,25 @@
|
||||||
export let collectionA = new Collection();
|
export let collectionA = new Collection();
|
||||||
export let collectionB = new Collection();
|
export let collectionB = new Collection();
|
||||||
export let deleteMissing = false;
|
export let deleteMissing = false;
|
||||||
|
let schemaA = [];
|
||||||
|
let schemaB = [];
|
||||||
|
let removedFields = [];
|
||||||
|
let sharedFields = [];
|
||||||
|
let addedFields = [];
|
||||||
|
|
||||||
$: isDeleteDiff = !collectionB?.id && !collectionB?.name;
|
$: isDeleteDiff = !collectionB?.id && !collectionB?.name;
|
||||||
|
|
||||||
$: isCreateDiff = !isDeleteDiff && !collectionA?.id;
|
$: isCreateDiff = !isDeleteDiff && !collectionA?.id;
|
||||||
|
|
||||||
$: schemaA = Array.isArray(collectionA?.schema) ? collectionA?.schema : [];
|
$: schemaA = Array.isArray(collectionA?.schema) ? collectionA?.schema.concat() : [];
|
||||||
|
|
||||||
$: schemaB = Array.isArray(collectionB?.schema) ? collectionB?.schema : [];
|
$: if (
|
||||||
|
typeof collectionA?.schema !== "undefined" ||
|
||||||
|
typeof collectionB?.schema !== "undefined" ||
|
||||||
|
typeof deleteMissing !== "undefined"
|
||||||
|
) {
|
||||||
|
setSchemaB();
|
||||||
|
}
|
||||||
|
|
||||||
$: removedFields = schemaA.filter((fieldA) => {
|
$: removedFields = schemaA.filter((fieldA) => {
|
||||||
return !schemaB.find((fieldB) => fieldA.id == fieldB.id);
|
return !schemaB.find((fieldB) => fieldA.id == fieldB.id);
|
||||||
|
@ -26,20 +37,21 @@
|
||||||
return !schemaA.find((fieldA) => fieldA.id == fieldB.id);
|
return !schemaA.find((fieldA) => fieldA.id == fieldB.id);
|
||||||
});
|
});
|
||||||
|
|
||||||
$: if (typeof deleteMissing !== "undefined") {
|
$: hasAnyChange = CommonHelper.hasCollectionChanges(collectionA, collectionB, deleteMissing);
|
||||||
normalizeSchemaB();
|
|
||||||
}
|
|
||||||
|
|
||||||
$: hasAnyChange = detectChanges(collectionA, collectionB);
|
|
||||||
|
|
||||||
const mainModelProps = Object.keys(new Collection().export()).filter(
|
const mainModelProps = Object.keys(new Collection().export()).filter(
|
||||||
(key) => !["schema", "created", "updated"].includes(key)
|
(key) => !["schema", "created", "updated"].includes(key)
|
||||||
);
|
);
|
||||||
|
|
||||||
function normalizeSchemaB() {
|
function setSchemaB() {
|
||||||
schemaB = Array.isArray(collectionB?.schema) ? collectionB?.schema : [];
|
schemaB = Array.isArray(collectionB?.schema) ? collectionB?.schema.concat() : [];
|
||||||
|
|
||||||
if (!deleteMissing) {
|
if (!deleteMissing) {
|
||||||
schemaB = schemaB.concat(removedFields);
|
schemaB = schemaB.concat(
|
||||||
|
schemaA.filter((fieldA) => {
|
||||||
|
return !schemaB.find((fieldB) => fieldA.id == fieldB.id);
|
||||||
|
})
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,29 +66,6 @@
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function detectChanges() {
|
|
||||||
// added or removed fields
|
|
||||||
if (addedFields?.length || (deleteMissing && removedFields?.length)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// changes in the main model props
|
|
||||||
for (let prop of mainModelProps) {
|
|
||||||
if (hasChanges(collectionA?.[prop], collectionB?.[prop])) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// changes in the schema fields
|
|
||||||
for (let field of sharedFields) {
|
|
||||||
if (hasChanges(field, CommonHelper.findByKey(schemaA, "id", field.id))) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function hasChanges(valA, valB) {
|
function hasChanges(valA, valB) {
|
||||||
// direct match
|
// direct match
|
||||||
if (valA === valB) {
|
if (valA === valB) {
|
||||||
|
@ -88,7 +77,7 @@
|
||||||
|
|
||||||
function displayValue(value) {
|
function displayValue(value) {
|
||||||
if (typeof value === "undefined") {
|
if (typeof value === "undefined") {
|
||||||
return "N/A";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
return CommonHelper.isObject(value) ? JSON.stringify(value, null, 4) : value;
|
return CommonHelper.isObject(value) ? JSON.stringify(value, null, 4) : value;
|
||||||
|
@ -97,21 +86,21 @@
|
||||||
|
|
||||||
<div class="section-title">
|
<div class="section-title">
|
||||||
{#if !collectionA?.id}
|
{#if !collectionA?.id}
|
||||||
<strong>{collectionB?.name}</strong>
|
|
||||||
<span class="label label-success">Added</span>
|
<span class="label label-success">Added</span>
|
||||||
|
<strong>{collectionB?.name}</strong>
|
||||||
{:else if !collectionB?.id}
|
{:else if !collectionB?.id}
|
||||||
|
<span class="label label-danger">Deleted</span>
|
||||||
<strong>{collectionA?.name}</strong>
|
<strong>{collectionA?.name}</strong>
|
||||||
<span class="label label-danger">Removed</span>
|
|
||||||
{:else}
|
{:else}
|
||||||
<div class="inline-flex fleg-gap-5">
|
<div class="inline-flex fleg-gap-5">
|
||||||
|
{#if hasAnyChange}
|
||||||
|
<span class="label label-warning">Changed</span>
|
||||||
|
{/if}
|
||||||
{#if collectionA.name !== collectionB.name}
|
{#if collectionA.name !== collectionB.name}
|
||||||
<strong class="txt-strikethrough txt-hint">{collectionA.name}</strong>
|
<strong class="txt-strikethrough txt-hint">{collectionA.name}</strong>
|
||||||
<i class="ri-arrow-right-line txt-sm" />
|
<i class="ri-arrow-right-line txt-sm" />
|
||||||
{/if}
|
{/if}
|
||||||
<strong class="txt">{collectionB.name}</strong>
|
<strong class="txt">{collectionB.name}</strong>
|
||||||
{#if hasAnyChange}
|
|
||||||
<span class="label label-warning">Changed</span>
|
|
||||||
{/if}
|
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
@ -152,9 +141,9 @@
|
||||||
{#each removedFields as field}
|
{#each removedFields as field}
|
||||||
<tr>
|
<tr>
|
||||||
<th class="min-width" colspan="3">
|
<th class="min-width" colspan="3">
|
||||||
<span class="txt">schema.{field.name}</span>
|
<span class="txt">field: {field.name}</span>
|
||||||
<span class="label label-danger m-l-5">
|
<span class="label label-danger m-l-5">
|
||||||
Removed - <small>
|
Deleted - <small>
|
||||||
All stored data related to <strong>{field.name}</strong> will be deleted!
|
All stored data related to <strong>{field.name}</strong> will be deleted!
|
||||||
</small>
|
</small>
|
||||||
</span>
|
</span>
|
||||||
|
@ -176,7 +165,7 @@
|
||||||
{#each sharedFields as field}
|
{#each sharedFields as field}
|
||||||
<tr>
|
<tr>
|
||||||
<th class="min-width" colspan="3">
|
<th class="min-width" colspan="3">
|
||||||
<span class="txt">schema.{field.name}</span>
|
<span class="txt">field: {field.name}</span>
|
||||||
{#if hasChanges(getFieldById(schemaA, field.id), getFieldById(schemaB, field.id))}
|
{#if hasChanges(getFieldById(schemaA, field.id), getFieldById(schemaB, field.id))}
|
||||||
<span class="label label-warning m-l-5">Changed</span>
|
<span class="label label-warning m-l-5">Changed</span>
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -199,7 +188,7 @@
|
||||||
{#each addedFields as field}
|
{#each addedFields as field}
|
||||||
<tr>
|
<tr>
|
||||||
<th class="min-width" colspan="3">
|
<th class="min-width" colspan="3">
|
||||||
<span class="txt">schema.{field.name}</span>
|
<span class="txt">field: {field.name}</span>
|
||||||
<span class="label label-success m-l-5">Added</span>
|
<span class="label label-success m-l-5">Added</span>
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
|
@ -12,8 +12,7 @@
|
||||||
|
|
||||||
$: adminsOnly = collection?.createRule === null;
|
$: adminsOnly = collection?.createRule === null;
|
||||||
|
|
||||||
$: backendAbsUrl =
|
$: backendAbsUrl = CommonHelper.getApiExampleUrl(ApiClient.baseUrl);
|
||||||
window.location.href.substring(0, window.location.href.indexOf("/_")) || ApiClient.baseUrl;
|
|
||||||
|
|
||||||
$: responses = [
|
$: responses = [
|
||||||
{
|
{
|
||||||
|
|
|
@ -11,8 +11,7 @@
|
||||||
|
|
||||||
$: adminsOnly = collection?.deleteRule === null;
|
$: adminsOnly = collection?.deleteRule === null;
|
||||||
|
|
||||||
$: backendAbsUrl =
|
$: backendAbsUrl = CommonHelper.getApiExampleUrl(ApiClient.baseUrl);
|
||||||
window.location.href.substring(0, window.location.href.indexOf("/_")) || ApiClient.baseUrl;
|
|
||||||
|
|
||||||
$: if (collection?.id) {
|
$: if (collection?.id) {
|
||||||
responses.push({
|
responses.push({
|
||||||
|
|
|
@ -13,8 +13,7 @@
|
||||||
|
|
||||||
$: adminsOnly = collection?.listRule === null;
|
$: adminsOnly = collection?.listRule === null;
|
||||||
|
|
||||||
$: backendAbsUrl =
|
$: backendAbsUrl = CommonHelper.getApiExampleUrl(ApiClient.baseUrl);
|
||||||
window.location.href.substring(0, window.location.href.indexOf("/_")) || ApiClient.baseUrl;
|
|
||||||
|
|
||||||
$: if (collection?.id) {
|
$: if (collection?.id) {
|
||||||
responses.push({
|
responses.push({
|
||||||
|
|
|
@ -7,8 +7,7 @@
|
||||||
|
|
||||||
export let collection = new Collection();
|
export let collection = new Collection();
|
||||||
|
|
||||||
$: backendAbsUrl =
|
$: backendAbsUrl = CommonHelper.getApiExampleUrl(ApiClient.baseUrl);
|
||||||
window.location.href.substring(0, window.location.href.indexOf("/_")) || ApiClient.baseUrl;
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="alert">
|
<div class="alert">
|
||||||
|
|
|
@ -12,8 +12,7 @@
|
||||||
|
|
||||||
$: adminsOnly = collection?.updateRule === null;
|
$: adminsOnly = collection?.updateRule === null;
|
||||||
|
|
||||||
$: backendAbsUrl =
|
$: backendAbsUrl = CommonHelper.getApiExampleUrl(ApiClient.baseUrl);
|
||||||
window.location.href.substring(0, window.location.href.indexOf("/_")) || ApiClient.baseUrl;
|
|
||||||
|
|
||||||
$: responses = [
|
$: responses = [
|
||||||
{
|
{
|
||||||
|
|
|
@ -12,8 +12,7 @@
|
||||||
|
|
||||||
$: adminsOnly = collection?.viewRule === null;
|
$: adminsOnly = collection?.viewRule === null;
|
||||||
|
|
||||||
$: backendAbsUrl =
|
$: backendAbsUrl = CommonHelper.getApiExampleUrl(ApiClient.baseUrl);
|
||||||
window.location.href.substring(0, window.location.href.indexOf("/_")) || ApiClient.baseUrl;
|
|
||||||
|
|
||||||
$: if (collection?.id) {
|
$: if (collection?.id) {
|
||||||
responses.push({
|
responses.push({
|
||||||
|
|
|
@ -35,14 +35,20 @@
|
||||||
function loadPairs() {
|
function loadPairs() {
|
||||||
pairs = [];
|
pairs = [];
|
||||||
|
|
||||||
// add deleted and modified collections
|
// add modified and deleted (if deleteMissing is set)
|
||||||
for (const oldCollection of oldCollections) {
|
for (const oldCollection of oldCollections) {
|
||||||
const newCollection = CommonHelper.findByKey(newCollections, "id", oldCollection.id) || null;
|
const newCollection = CommonHelper.findByKey(newCollections, "id", oldCollection.id) || null;
|
||||||
|
if (
|
||||||
|
(deleteMissing && !newCollection?.id) ||
|
||||||
|
(newCollection?.id &&
|
||||||
|
CommonHelper.hasCollectionChanges(oldCollection, newCollection, deleteMissing))
|
||||||
|
) {
|
||||||
pairs.push({
|
pairs.push({
|
||||||
old: oldCollection,
|
old: oldCollection,
|
||||||
new: newCollection,
|
new: newCollection,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// add only new collections
|
// add only new collections
|
||||||
for (const newCollection of newCollections) {
|
for (const newCollection of newCollections) {
|
||||||
|
@ -61,7 +67,7 @@
|
||||||
const deletedFieldNames = [];
|
const deletedFieldNames = [];
|
||||||
if (deleteMissing) {
|
if (deleteMissing) {
|
||||||
for (const old of oldCollections) {
|
for (const old of oldCollections) {
|
||||||
const imported = !CommonHelper.findByKey(newCollections, "id", old.id);
|
const imported = CommonHelper.findByKey(newCollections, "id", old.id);
|
||||||
if (!imported) {
|
if (!imported) {
|
||||||
// add all fields
|
// add all fields
|
||||||
deletedFieldNames.push(old.name + ".*");
|
deletedFieldNames.push(old.name + ".*");
|
||||||
|
@ -70,7 +76,7 @@
|
||||||
const schema = Array.isArray(old.schema) ? old.schema : [];
|
const schema = Array.isArray(old.schema) ? old.schema : [];
|
||||||
for (const field of schema) {
|
for (const field of schema) {
|
||||||
if (!CommonHelper.findByKey(imported.schema, "id", field.id)) {
|
if (!CommonHelper.findByKey(imported.schema, "id", field.id)) {
|
||||||
deletedFieldNames.push(old.name + "." + field.name);
|
deletedFieldNames.push(`${old.name}.${field.name} (${field.id})`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,8 +19,8 @@
|
||||||
let isLoadingFile = false;
|
let isLoadingFile = false;
|
||||||
let newCollections = [];
|
let newCollections = [];
|
||||||
let oldCollections = [];
|
let oldCollections = [];
|
||||||
let deleteMissing = false;
|
let deleteMissing = true;
|
||||||
let collectionsToChange = [];
|
let collectionsToUpdate = [];
|
||||||
let isLoadingOldCollections = false;
|
let isLoadingOldCollections = false;
|
||||||
|
|
||||||
$: if (typeof schemas !== "undefined") {
|
$: if (typeof schemas !== "undefined") {
|
||||||
|
@ -33,19 +33,19 @@
|
||||||
newCollections.length === newCollections.filter((item) => !!item.id && !!item.name).length;
|
newCollections.length === newCollections.filter((item) => !!item.id && !!item.name).length;
|
||||||
|
|
||||||
$: collectionsToDelete = oldCollections.filter((collection) => {
|
$: collectionsToDelete = oldCollections.filter((collection) => {
|
||||||
return isValid && !CommonHelper.findByKey(newCollections, "id", collection.id);
|
return isValid && deleteMissing && !CommonHelper.findByKey(newCollections, "id", collection.id);
|
||||||
});
|
});
|
||||||
|
|
||||||
$: collectionsToAdd = newCollections.filter((collection) => {
|
$: collectionsToAdd = newCollections.filter((collection) => {
|
||||||
return isValid && !CommonHelper.findByKey(oldCollections, "id", collection.id);
|
return isValid && !CommonHelper.findByKey(oldCollections, "id", collection.id);
|
||||||
});
|
});
|
||||||
|
|
||||||
$: if (typeof newCollections !== "undefined") {
|
$: if (typeof newCollections !== "undefined" || typeof deleteMissing !== "undefined") {
|
||||||
loadCollectionsToModify();
|
loadCollectionsToUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
$: hasChanges =
|
$: hasChanges =
|
||||||
!!schemas && (collectionsToDelete.length || collectionsToAdd.length || collectionsToChange.length);
|
!!schemas && (collectionsToDelete.length || collectionsToAdd.length || collectionsToUpdate.length);
|
||||||
|
|
||||||
$: canImport = !isLoadingOldCollections && isValid && hasChanges;
|
$: canImport = !isLoadingOldCollections && isValid && hasChanges;
|
||||||
|
|
||||||
|
@ -62,8 +62,13 @@
|
||||||
const oldSchema = Array.isArray(old.schema) ? old.schema : [];
|
const oldSchema = Array.isArray(old.schema) ? old.schema : [];
|
||||||
const newSchema = Array.isArray(collection.schema) ? collection.schema : [];
|
const newSchema = Array.isArray(collection.schema) ? collection.schema : [];
|
||||||
for (const field of newSchema) {
|
for (const field of newSchema) {
|
||||||
const oldField = CommonHelper.findByKey(oldSchema, "name", field.name);
|
const oldFieldById = CommonHelper.findByKey(oldSchema, "id", field.id);
|
||||||
if (oldField && field.id != oldField.id) {
|
if (oldFieldById) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const oldFieldByName = CommonHelper.findByKey(oldSchema, "name", field.name);
|
||||||
|
if (oldFieldByName && field.id != oldFieldByName.id) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -90,8 +95,8 @@
|
||||||
isLoadingOldCollections = false;
|
isLoadingOldCollections = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadCollectionsToModify() {
|
function loadCollectionsToUpdate() {
|
||||||
collectionsToChange = [];
|
collectionsToUpdate = [];
|
||||||
|
|
||||||
if (!isValid) {
|
if (!isValid) {
|
||||||
return;
|
return;
|
||||||
|
@ -103,12 +108,12 @@
|
||||||
// no old collection
|
// no old collection
|
||||||
!oldCollection?.id ||
|
!oldCollection?.id ||
|
||||||
// no changes
|
// no changes
|
||||||
JSON.stringify(oldCollection) === JSON.stringify(newCollection)
|
!CommonHelper.hasCollectionChanges(oldCollection, newCollection, deleteMissing)
|
||||||
) {
|
) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
collectionsToChange.push({
|
collectionsToUpdate.push({
|
||||||
new: newCollection,
|
new: newCollection,
|
||||||
old: oldCollection,
|
old: oldCollection,
|
||||||
});
|
});
|
||||||
|
@ -194,7 +199,7 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
reader.onerror = (err) => {
|
reader.onerror = (err) => {
|
||||||
console.log(err);
|
console.warn(err);
|
||||||
addErrorToast("Failed to load the imported JSON.");
|
addErrorToast("Failed to load the imported JSON.");
|
||||||
|
|
||||||
isLoadingFile = false;
|
isLoadingFile = false;
|
||||||
|
@ -269,13 +274,18 @@
|
||||||
{/if}
|
{/if}
|
||||||
</Field>
|
</Field>
|
||||||
|
|
||||||
|
{#if false}
|
||||||
|
<!-- for now hide the delete control and enable/remove based on users feedback -->
|
||||||
<Field class="form-field form-field-toggle" let:uniqueId>
|
<Field class="form-field form-field-toggle" let:uniqueId>
|
||||||
<input type="checkbox" id={uniqueId} bind:checked={deleteMissing} disabled={!isValid} />
|
<input
|
||||||
<label for={uniqueId}>
|
type="checkbox"
|
||||||
Delete all collections and fields that are not present in the above imported
|
id={uniqueId}
|
||||||
configuration
|
bind:checked={deleteMissing}
|
||||||
</label>
|
disabled={!isValid}
|
||||||
|
/>
|
||||||
|
<label for={uniqueId}>Delete missing collections and schema fields</label>
|
||||||
</Field>
|
</Field>
|
||||||
|
{/if}
|
||||||
|
|
||||||
{#if isValid && newCollections.length && !hasChanges}
|
{#if isValid && newCollections.length && !hasChanges}
|
||||||
<div class="alert alert-info">
|
<div class="alert alert-info">
|
||||||
|
@ -304,8 +314,8 @@
|
||||||
{/each}
|
{/each}
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if collectionsToChange.length}
|
{#if collectionsToUpdate.length}
|
||||||
{#each collectionsToChange as pair (pair.old.id + pair.new.id)}
|
{#each collectionsToUpdate as pair (pair.old.id + pair.new.id)}
|
||||||
<div class="list-item">
|
<div class="list-item">
|
||||||
<span class="label label-warning list-label">Changed</span>
|
<span class="label label-warning list-label">Changed</span>
|
||||||
<strong>
|
<strong>
|
||||||
|
@ -336,13 +346,15 @@
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if idReplacableCollections.length}
|
{#if idReplacableCollections.length}
|
||||||
<div class="alert alert-warning">
|
<div class="alert alert-warning m-t-base">
|
||||||
<div class="icon">
|
<div class="icon">
|
||||||
<i class="ri-error-warning-line" />
|
<i class="ri-error-warning-line" />
|
||||||
</div>
|
</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<string>
|
<string>
|
||||||
Some of the imported collections shares the same name but has different IDs.
|
Some of the imported collections shares the same name and/or fields but are
|
||||||
|
imported with different IDs. You can replace them in the import if you want
|
||||||
|
to.
|
||||||
</string>
|
</string>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
|
@ -350,7 +362,7 @@
|
||||||
class="btn btn-warning btn-sm btn-outline"
|
class="btn btn-warning btn-sm btn-outline"
|
||||||
on:click={() => replaceIds()}
|
on:click={() => replaceIds()}
|
||||||
>
|
>
|
||||||
<span class="txt">Replace and keep old ids</span>
|
<span class="txt">Replace with original ids</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
.bulkbar {
|
.bulkbar {
|
||||||
position: sticky;
|
position: sticky;
|
||||||
bottom: -10px;
|
bottom: var(--baseSpacing);
|
||||||
z-index: 101;
|
z-index: 101;
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
--warningColor: #ff8e3c;
|
--warningColor: #ff8e3c;
|
||||||
--warningAltColor: #ffe7d6;
|
--warningAltColor: #ffe7d6;
|
||||||
|
|
||||||
--overlayColor: rgba(88, 95, 101, 0.3);
|
--overlayColor: rgba(70, 85, 100, 0.3);
|
||||||
--tooltipColor: rgba(0, 0, 0, 0.85);
|
--tooltipColor: rgba(0, 0, 0, 0.85);
|
||||||
--shadowColor: rgba(0, 0, 0, 0.05);
|
--shadowColor: rgba(0, 0, 0, 0.05);
|
||||||
|
|
||||||
|
|
|
@ -874,4 +874,70 @@ export default class CommonHelper {
|
||||||
return 'String';
|
return 'String';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an API url address extract from the current running instance.
|
||||||
|
*
|
||||||
|
* @param {String} fallback Fallback url that will be used if the extractions fail.
|
||||||
|
* @return {String}
|
||||||
|
*/
|
||||||
|
static getApiExampleUrl(fallback) {
|
||||||
|
let url = window.location.href.substring(0, window.location.href.indexOf("/_")) || fallback || '/';
|
||||||
|
|
||||||
|
// for broader compatibility replace localhost with 127.0.0.1
|
||||||
|
// (see https://github.com/pocketbase/js-sdk/issues/21)
|
||||||
|
return url.replace('//localhost', '//127.0.0.1');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the provided 2 collections has any change (ignoring root schema fields order).
|
||||||
|
*
|
||||||
|
* @param {Collection} oldCollection
|
||||||
|
* @param {Collection} newCollection
|
||||||
|
* @param {Boolean} withDeleteMissing Skip missing schema fields from the newCollection.
|
||||||
|
* @return {Boolean}
|
||||||
|
*/
|
||||||
|
static hasCollectionChanges(oldCollection, newCollection, withDeleteMissing = false) {
|
||||||
|
oldCollection = oldCollection || {};
|
||||||
|
newCollection = newCollection || {};
|
||||||
|
|
||||||
|
if (oldCollection.id != newCollection.id) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let prop in oldCollection) {
|
||||||
|
if (prop !== 'schema' && JSON.stringify(oldCollection[prop]) !== JSON.stringify(newCollection[prop])) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const oldSchema = Array.isArray(oldCollection.schema) ? oldCollection.schema : [];
|
||||||
|
const newSchema = Array.isArray(newCollection.schema) ? newCollection.schema : [];
|
||||||
|
const removedFields = oldSchema.filter((oldField) => {
|
||||||
|
return oldField?.id && !CommonHelper.findByKey(newSchema, "id", oldField.id);
|
||||||
|
});
|
||||||
|
const addedFields = newSchema.filter((newField) => {
|
||||||
|
return newField?.id && !CommonHelper.findByKey(oldSchema, "id", newField.id);
|
||||||
|
});
|
||||||
|
const changedFields = newSchema.filter((newField) => {
|
||||||
|
const oldField = CommonHelper.isObject(newField) && CommonHelper.findByKey(oldSchema, "id", newField.id);
|
||||||
|
if (!oldField) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let prop in oldField) {
|
||||||
|
if (JSON.stringify(newField[prop]) != JSON.stringify(oldField[prop])) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
return !!(
|
||||||
|
addedFields.length ||
|
||||||
|
changedFields.length ||
|
||||||
|
(withDeleteMissing && removedFields.length)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue