Fix order

This commit is contained in:
Adrian Woźniak 2022-08-01 09:47:36 +02:00
parent ee61a10282
commit 670c1f7cf2
No known key found for this signature in database
GPG Key ID: 0012845A89C7352B
6 changed files with 112 additions and 62 deletions

View File

@ -81,19 +81,23 @@ customElements.define('business-item-editor', class extends Component {
ev.stopPropagation();
ev.preventDefault();
if (this.shadowRoot.querySelector('register-item-form-row').reportValidity()) {
// console.info(this);
// if (this.shadowRoot.querySelector('register-item-form-row').reportValidity()) {
if (form.reportValidity()) {
const {
name,
price,
picture_url,
item_order,
} = ev.detail;
form.querySelector('#name').value = name;
form.querySelector('#price').value = price;
form.querySelector('#picture_url').value = picture_url;
form.querySelector('#item_order').value = item_order;
form.submit();
}
// }
});
const moveForm = this.shadowRoot.querySelector('#moveForm');
this.addEventListener('item:up', ev => {

View File

@ -147,10 +147,6 @@ customElements.define('business-item', class extends Component {
}
}
connectedCallback() {
super.connectedCallback();
}
attributeChangedCallback(name, oldV, newV) {
super.attributeChangedCallback(name, oldV, newV);

View File

@ -288,6 +288,7 @@ pub struct Offer {
#[derive(Debug)]
pub struct CreateLocalBusinessItemInput {
pub account_id: i32,
pub local_business_id: i32,
pub name: String,
pub price: i64,

View File

@ -122,8 +122,92 @@ pub async fn move_item(
item_id: i32,
item_order: i32,
) -> Result<db::LocalBusinessItem> {
let mut current = item_by_id(t, account_id, item_id).await?;
dbg!(item_id, item_order);
let _idx = reorder_items(t, account_id).await;
let mut current = item_by_id(t, account_id, item_id).await?;
dbg!(&current);
match item_order.cmp(&current.item_order) {
Ordering::Less => {
if let Some(prev_idx) = current.item_order.checked_sub(1) {
dbg!(prev_idx);
let prev = find_by_item_order(t, account_id, prev_idx).await?;
dbg!(
"Less and found",
current.id,
current.item_order,
prev.id,
prev.item_order,
);
dbg!(update_item_order(&mut *t, current.id, prev.item_order).await?);
dbg!(update_item_order(&mut *t, prev.id, current.item_order).await?);
} else {
dbg!("Less and not found, skipping...");
}
}
Ordering::Equal => {
dbg!("Equal, skipping...");
}
Ordering::Greater => {
if let Some(next_idx) = current.item_order.checked_add(1) {
dbg!(next_idx);
let next = find_by_item_order(t, account_id, next_idx).await?;
dbg!(
"Greater and found",
current.id,
current.item_order,
next.id,
next.item_order,
);
dbg!(update_item_order(&mut *t, current.id, next.item_order).await?);
dbg!(update_item_order(&mut *t, next.id, current.item_order).await?);
} else {
dbg!("Greater and not found, skipping...");
}
}
};
current.item_order = item_order;
Ok(current)
}
#[tracing::instrument]
async fn find_by_item_order(
t: &mut T<'_>,
account_id: i32,
item_order: i32,
) -> Result<db::LocalBusinessItem> {
sqlx::query_as(
r#"
SELECT
local_business_items.id,
local_business_items.local_business_id,
local_business_items.name,
local_business_items.price,
local_business_items.item_order,
local_business_items.picture_url
FROM local_business_items
INNER JOIN local_businesses
ON local_businesses.id = local_business_items.local_business_id
WHERE local_business_items.item_order = $1 AND owner_id = $2
ORDER BY item_order ASC
"#,
)
.bind(item_order)
.bind(account_id)
.fetch_one(t)
.await
.map_err(|e| {
error!("{e}");
dbg!(e);
Error::AllItems
})
}
#[tracing::instrument]
async fn reorder_items(t: &mut T<'_>, account_id: i32) -> i32 {
let all: Vec<db::LocalBusinessItem> = sqlx::query_as(
r#"
SELECT
@ -143,63 +227,25 @@ ORDER BY item_order ASC
.bind(account_id)
.fetch_all(&mut *t)
.await
.map_err(|e| {
error!("{e}");
dbg!(e);
Error::Item { item_id }
})?;
.unwrap_or_default();
let idx = all
.iter()
.position(|p| p.id == item_id)
.ok_or(Error::Item { item_id })?;
dbg!(idx);
match item_order.cmp(&current.item_order) {
Ordering::Less => {
if let Some(prev) = idx.checked_sub(1).and_then(|prev_idx| {
dbg!(prev_idx);
all.get(prev_idx)
}) {
dbg!(
"Less and found",
current.id,
current.item_order,
prev.id,
prev.item_order,
);
dbg!(update_item_order(&mut *t, current.id, prev.item_order).await?);
dbg!(update_item_order(&mut *t, prev.id, current.item_order).await?);
} else {
dbg!("Less and not found, skipping...");
}
let mut sql = String::from(
r#"
UPDATE local_business_items AS a
SET item_order = b.item_order
FROM (VALUES "#,
);
all.iter().enumerate().fold(&mut sql, |memo, (idx, row)| {
if idx != 0 {
memo.push_str(", ");
}
Ordering::Equal => {
dbg!("Equal, skipping...");
}
Ordering::Greater => {
if let Some(next) = idx.checked_add(1).and_then(|next_idx| {
dbg!(next_idx);
all.get(next_idx)
}) {
dbg!(
"Greater and found",
current.id,
current.item_order,
next.id,
next.item_order,
);
dbg!(update_item_order(&mut *t, current.id, next.item_order).await?);
dbg!(update_item_order(&mut *t, next.id, current.item_order).await?);
} else {
dbg!("Greater and not found, skipping...");
}
}
};
current.item_order = item_order;
Ok(current)
memo.push_str(format!("({}, {})", row.id, idx).as_str());
memo
});
sql.push_str(") AS b (id, item_order) WHERE a.id = b.id");
dbg!(&sql);
sqlx::query(&sql).execute(&mut *t).await.ok();
all.len() as i32
}
#[tracing::instrument]
@ -284,6 +330,7 @@ pub async fn create_item(
t: &mut T<'_>,
input: db::CreateLocalBusinessItemInput,
) -> Result<db::LocalBusinessItem> {
let item_order = reorder_items(t, input.account_id).await;
sqlx::query_as(
r#"
INSERT INTO local_business_items (local_business_id, name, price, picture_url, item_order)
@ -307,7 +354,7 @@ RETURNING
.map(String::from)
.unwrap_or_else(|| format!("--{}", uuid::Uuid::new_v4())),
)
.bind(input.item_order)
.bind(item_order)
.fetch_one(t)
.await
.map_err(|e| {

View File

@ -155,6 +155,7 @@ async fn new_business_item(
if let Err(e) = queries::create_item(
&mut t,
db::CreateLocalBusinessItemInput {
account_id: account.id,
local_business_id: business.id,
name: form.name,
price: form.price,

View File

@ -417,6 +417,7 @@ async fn save_account_details(
let res = queries::create_item(
&mut t,
db::CreateLocalBusinessItemInput {
account_id: account.id,
local_business_id: business.id,
name: item.name,
price: item.price as i64,