mirror of
https://github.com/appwrite/console.git
synced 2026-06-06 19:27:48 +00:00
Merge pull request #185 from appwrite/fix-4762-index-creation-preview-values
fix: createIndex attribute select changing all other selects
This commit is contained in:
@@ -3,6 +3,7 @@ export function intersection(arr1: unknown[], arr2: unknown[]) {
|
||||
const intersection = new Set(arr1.filter((elem) => set.has(elem)));
|
||||
return Array.from(intersection);
|
||||
}
|
||||
|
||||
export function difference(arr1: unknown[], arr2: unknown[]) {
|
||||
const set = new Set(arr2);
|
||||
const intersection = new Set(arr1.filter((elem) => !set.has(elem)));
|
||||
@@ -12,3 +13,17 @@ export function difference(arr1: unknown[], arr2: unknown[]) {
|
||||
export function symmetricDifference(arr1: unknown[], arr2: unknown[]) {
|
||||
return difference(arr1, arr2).concat(difference(arr2, arr1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the element at the specified index from the array, and returns a new array.
|
||||
*
|
||||
* @export
|
||||
* @template T
|
||||
* @param {T[]} arr
|
||||
* @param {number} index
|
||||
* @returns {T[]}
|
||||
*/
|
||||
export function remove<T>(arr: T[], index: number): T[] {
|
||||
// Remove the element at the given index, return a new array
|
||||
return [...arr.slice(0, index), ...arr.slice(index + 1)];
|
||||
}
|
||||
|
||||
+58
-105
@@ -11,6 +11,7 @@
|
||||
import { Dependencies } from '$lib/constants';
|
||||
import Select from './select.svelte';
|
||||
import { trackEvent } from '$lib/actions/analytics';
|
||||
import { remove } from '$lib/helpers/array';
|
||||
|
||||
export let showCreateIndex = false;
|
||||
export let externalAttribute: Attributes = null;
|
||||
@@ -24,115 +25,77 @@
|
||||
{ value: 'unique', label: 'Unique' },
|
||||
{ value: 'fulltext', label: 'FullText' }
|
||||
];
|
||||
let newAttr = false;
|
||||
let selectedType = 'key';
|
||||
$: attributeOptions = $collection.attributes.map((attribute: Attributes) => ({
|
||||
|
||||
let attributeOptions = $collection.attributes.map((attribute: Attributes) => ({
|
||||
value: attribute.key,
|
||||
label: attribute.key
|
||||
}));
|
||||
$: attributeList = [];
|
||||
let attributeList = [{ value: '', order: '' }];
|
||||
|
||||
let selectedAttribute = '';
|
||||
let selectedOrder = '';
|
||||
$: addAttributeDisabled = !attributeList.at(-1)?.value || !attributeList.at(-1)?.order;
|
||||
|
||||
onMount(() => {
|
||||
if (externalAttribute) {
|
||||
attributeList = [{ value: externalAttribute.key, order: 'ASC' }];
|
||||
}
|
||||
if (!externalAttribute) return;
|
||||
attributeList = [{ value: externalAttribute.key, order: 'ASC' }];
|
||||
});
|
||||
|
||||
$: if (showCreateIndex) {
|
||||
attributeList = [];
|
||||
selectedOrder = selectedAttribute = '';
|
||||
attributeList = [{ value: '', order: '' }];
|
||||
selectedType = 'key';
|
||||
key = null;
|
||||
}
|
||||
const created = async () => {
|
||||
if (key && selectedAttribute && selectedOrder && selectedType) {
|
||||
if (selectedAttribute && selectedOrder) {
|
||||
attributeList.push({ value: selectedAttribute, order: selectedOrder });
|
||||
selectedAttribute = selectedOrder = '';
|
||||
}
|
||||
try {
|
||||
await sdkForProject.databases.createIndex(
|
||||
databaseId,
|
||||
$collection.$id,
|
||||
key,
|
||||
selectedType,
|
||||
attributeList.map((a) => a.value),
|
||||
attributeList.map((a) => a.order)
|
||||
);
|
||||
invalidate(Dependencies.COLLECTION);
|
||||
addNotification({
|
||||
message: 'Index has been created',
|
||||
type: 'success'
|
||||
});
|
||||
trackEvent('submit_index_create');
|
||||
} catch (error) {
|
||||
addNotification({
|
||||
message: error.message,
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
|
||||
async function create() {
|
||||
if (!(key && selectedType && !addAttributeDisabled)) {
|
||||
error = 'All fields are required';
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await sdkForProject.databases.createIndex(
|
||||
databaseId,
|
||||
$collection.$id,
|
||||
key,
|
||||
selectedType,
|
||||
attributeList.map((a) => a.value),
|
||||
attributeList.map((a) => a.order)
|
||||
);
|
||||
invalidate(Dependencies.COLLECTION);
|
||||
addNotification({
|
||||
message: 'Index has been created',
|
||||
type: 'success'
|
||||
});
|
||||
trackEvent('submit_index_create');
|
||||
} catch (error) {
|
||||
addNotification({
|
||||
message: error.message,
|
||||
type: 'error'
|
||||
});
|
||||
} finally {
|
||||
showCreateIndex = false;
|
||||
} else error = 'All fields are required';
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function addAttribute() {
|
||||
if (addAttributeDisabled) return;
|
||||
|
||||
// We assign instead of pushing to trigger Svelte's reactivity
|
||||
attributeList = [...attributeList, { value: '', order: '' }];
|
||||
}
|
||||
</script>
|
||||
|
||||
<Modal bind:error size="big" on:submit={created} bind:show={showCreateIndex}>
|
||||
<Modal bind:error size="big" on:submit={create} bind:show={showCreateIndex}>
|
||||
<svelte:fragment slot="header">Create Index</svelte:fragment>
|
||||
<FormList>
|
||||
<InputText id="key" label="Index Key" placeholder="Enter Key" bind:value={key} autofocus />
|
||||
<InputSelect options={types} id="type" label="Index type" bind:value={selectedType} />
|
||||
|
||||
{#if attributeList?.length}
|
||||
{#each attributeList as index, i}
|
||||
<li class="form-item is-multiple">
|
||||
<div class="form-item-part u-stretch">
|
||||
<Select id="attribute" label="Attribute" bind:value={index.value}>
|
||||
<optgroup label="Internal">
|
||||
<option value="$id">$id</option>
|
||||
<option value="$createdAt">$createdAt</option>
|
||||
<option value="$updatedAt">$updatedAt</option>
|
||||
</optgroup>
|
||||
<optgroup label="Attributes">
|
||||
{#each attributeOptions as option}
|
||||
<option
|
||||
value={option.value}
|
||||
selected={option.value === selectedAttribute}>
|
||||
{option.label}
|
||||
</option>
|
||||
{/each}
|
||||
</optgroup>
|
||||
</Select>
|
||||
</div>
|
||||
<div class="form-item-part u-stretch">
|
||||
<Select id="order" label="Order" bind:value={index.order}>
|
||||
<option value="ASC"> ASC </option>
|
||||
<option value="DESC"> DESC </option>
|
||||
</Select>
|
||||
</div>
|
||||
|
||||
<div class="form-item-part u-cross-child-end">
|
||||
<Button
|
||||
text
|
||||
disabled={externalAttribute && i === 0}
|
||||
on:click={() => {
|
||||
if (i === 0) attributeList = [];
|
||||
attributeList = attributeList.splice(i, 1);
|
||||
}}>
|
||||
<span class="icon-x" aria-hidden="true" />
|
||||
</Button>
|
||||
</div>
|
||||
</li>
|
||||
{/each}
|
||||
{/if}
|
||||
{#if !attributeList?.length || newAttr}
|
||||
{#each attributeList as attribute, i}
|
||||
<li class="form-item is-multiple">
|
||||
<div class="form-item-part u-stretch" style="align-items: flex-start;">
|
||||
<Select id="attribute" label="Attribute" bind:value={selectedAttribute}>
|
||||
<option value="" disabled selected hidden>Select Attribute</option>
|
||||
<div class="form-item-part u-stretch">
|
||||
<Select id={`attribute-${i}`} label="Attribute" bind:value={attribute.value}>
|
||||
<option value="" disabled hidden>Select Attribute</option>
|
||||
|
||||
<optgroup label="Internal">
|
||||
<option value="$id">$id</option>
|
||||
@@ -141,9 +104,7 @@
|
||||
</optgroup>
|
||||
<optgroup label="Attributes">
|
||||
{#each attributeOptions as option}
|
||||
<option
|
||||
value={option.value}
|
||||
selected={option.value === selectedAttribute}>
|
||||
<option value={option.value}>
|
||||
{option.label}
|
||||
</option>
|
||||
{/each}
|
||||
@@ -151,36 +112,28 @@
|
||||
</Select>
|
||||
</div>
|
||||
<div class="form-item-part u-stretch">
|
||||
<Select id="order" label="Order" bind:value={selectedOrder}>
|
||||
<option value="" disabled selected hidden>Select Order</option>
|
||||
<Select id={`order-${i}`} label="Order" bind:value={attribute.order}>
|
||||
<option value="" disabled hidden>Select Order</option>
|
||||
|
||||
<option value="ASC"> ASC </option>
|
||||
<option value="DESC"> DESC </option>
|
||||
</Select>
|
||||
</div>
|
||||
|
||||
<div class="form-item-part u-cross-child-end">
|
||||
<Button
|
||||
text
|
||||
disabled={false}
|
||||
disabled={attributeList.length <= 1}
|
||||
on:click={() => {
|
||||
newAttr = false;
|
||||
selectedAttribute = selectedOrder = '';
|
||||
attributeList = remove(attributeList, i);
|
||||
}}>
|
||||
<span class="icon-x" aria-hidden="true" />
|
||||
</Button>
|
||||
</div>
|
||||
</li>
|
||||
{/if}
|
||||
<Button
|
||||
text
|
||||
noMargin
|
||||
on:click={() => {
|
||||
newAttr = true;
|
||||
if (selectedAttribute && selectedOrder) {
|
||||
attributeList.push({ value: selectedAttribute, order: selectedOrder });
|
||||
selectedAttribute = selectedOrder = '';
|
||||
}
|
||||
}}>
|
||||
{/each}
|
||||
|
||||
<Button text noMargin on:click={addAttribute} disabled={addAttributeDisabled}>
|
||||
<span class="icon-plus" aria-hidden="true" />
|
||||
<span class="text">Add attribute</span>
|
||||
</Button>
|
||||
|
||||
Reference in New Issue
Block a user