Skip to content

Commit

Permalink
Merge pull request #185 from appwrite/fix-4762-index-creation-preview…
Browse files Browse the repository at this point in the history
…-values

fix: createIndex attribute select changing all other selects
  • Loading branch information
TorstenDittmann committed Nov 23, 2022
2 parents a31f099 + 322f9e3 commit af3d741
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 105 deletions.
15 changes: 15 additions & 0 deletions src/lib/helpers/array.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)));
Expand All @@ -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)];
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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>
Expand All @@ -141,46 +104,36 @@
</optgroup>
<optgroup label="Attributes">
{#each attributeOptions as option}
<option
value={option.value}
selected={option.value === selectedAttribute}>
<option value={option.value}>
{option.label}
</option>
{/each}
</optgroup>
</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>
Expand Down

1 comment on commit af3d741

@vercel
Copy link

@vercel vercel bot commented on af3d741 Nov 23, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.